拦截器
在Spring Boot中,拦截器(Interceptor)是用于在处理请求前后进行一些自定义操作的组件,常用于日志记录、权限检查、性能监控等。拦截器的使用依赖于HandlerInterceptor
接口和WebMvcConfigurer
接口。
1. HandlerInterceptor
接口
HandlerInterceptor
接口是Spring MVC中用来定义拦截器的核心接口。它有三个方法需要实现:
-
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
: 这个方法在请求处理之前执行,返回true
表示请求继续往下处理,返回false
则请求被终止,后续的处理逻辑不会执行。 -
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
: 这个方法在请求处理之后(视图渲染之前)执行。可以在此方法中修改ModelAndView
,即控制器返回的模型和视图信息。 -
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
: 这个方法在整个请求处理完毕后执行,通常用于清理资源等操作。无论请求成功与否都会执行。
示例代码(HandlerInterceptor实现):
@Component
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("请求前处理");return true; // 如果返回false,请求将被拦截}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("请求后处理");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("请求完成处理");}
}
2. WebMvcConfigurer
接口
WebMvcConfigurer
接口是Spring MVC的配置接口,允许我们定制Spring MVC的配置。通过实现该接口并重写其中的方法,我们可以注册拦截器、配置视图解析器、设置静态资源等。
如何注册拦截器:
要在Spring Boot中注册拦截器,需要实现WebMvcConfigurer
接口,并在addInterceptors()
方法中注册自定义拦截器。WebMvcConfigurer
接口提供了许多默认实现的方法,可以按需覆盖。
示例代码(注册拦截器):
@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate MyInterceptor myInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myInterceptor).addPathPatterns("/**") // 拦截所有路径.excludePathPatterns("/login", "/public/**"); // 排除某些路径}
}
在这个例子中,WebConfig
类实现了WebMvcConfigurer
接口,并在addInterceptors
方法中注册了MyInterceptor
拦截器。addPathPatterns
方法用来配置哪些路径会被拦截,excludePathPatterns
方法用来配置哪些路径不会被拦截。
小结:
HandlerInterceptor
用于定义具体的拦截器,提供了请求前、请求后、请求完成后的处理方法。WebMvcConfigurer
用于定制Spring MVC的配置,包括注册拦截器。通过实现addInterceptors
方法可以将拦截器添加到Spring MVC的拦截链中。
这种机制为应用程序提供了灵活的请求拦截能力,可以非常方便地在请求流程中添加自定义逻辑。
在Spring Boot应用中,拦截器的路径设置是非常常见的需求,通常会通过addPathPatterns
和excludePathPatterns
方法来进行配置。以下是一些常见的拦截路径设置方式,可以根据不同的场景需求来选择合适的方式。
拦截路径设置
1. 拦截所有路径
如果你希望拦截应用中的所有请求路径,可以使用/**
,这表示拦截所有路径。
registry.addInterceptor(myInterceptor).addPathPatterns("/**"); // 拦截所有路径
2. 拦截特定路径
有时你只想拦截某些特定的路径,可以使用精确路径或通配符。例如,拦截以/admin
开头的所有请求:
registry.addInterceptor(myInterceptor).addPathPatterns("/admin/**"); // 拦截所有以/admin开头的路径
3. 排除某些路径
你可以通过excludePathPatterns
方法排除某些特定路径的请求不被拦截。例如,排除对/login
和/public/**
路径的拦截:
registry.addInterceptor(myInterceptor).addPathPatterns("/**") // 拦截所有路径.excludePathPatterns("/login", "/public/**"); // 排除/login和/public/**路径
4. 拦截多个路径
你可以同时拦截多个不连续的路径。例如,拦截/user/**
和/order/**
路径:
registry.addInterceptor(myInterceptor).addPathPatterns("/user/**", "/order/**"); // 拦截/user和/order下的所有路径
5. 使用通配符
Spring MVC支持使用通配符来匹配路径,常见的有:
*
:匹配单个路径元素(如/user/*
匹配/user/123
)**
:匹配多个路径元素(如/admin/**
匹配/admin/xxx/yyy
)?
:匹配单个字符(如/user/?
匹配/user/1
)
例如,拦截以/api/
开头且后面跟着两个路径段的请求:
registry.addInterceptor(myInterceptor).addPathPatterns("/api/*/*"); // 匹配/api/xxx/yyy形式的路径
6. 排除静态资源路径
通常,我们会排除静态资源路径(如CSS、JS、图片等)不被拦截。假设静态资源存放在/static/**
路径下:
registry.addInterceptor(myInterceptor).addPathPatterns("/**") // 拦截所有路径.excludePathPatterns("/static/**"); // 排除静态资源路径
7. 排除特定请求方法
拦截器可以不仅仅根据路径进行设置,还可以结合HTTP请求方法来排除。例如,排除GET
请求不被拦截:
registry.addInterceptor(myInterceptor).addPathPatterns("/**") // 拦截所有路径.excludePathPatterns(HttpMethod.GET, "/login"); // 排除GET方法的请求
8. 拦截特定请求方法
通过addPathPatterns
方法,你还可以拦截特定的HTTP请求方法,例如只拦截POST
请求:
registry.addInterceptor(myInterceptor).addPathPatterns("/submit/**") // 拦截/submit路径下的所有请求.excludePathPatterns(HttpMethod.GET, "/submit/**"); // 排除GET请求
9. 排除某些用户或角色的路径
有时你需要根据用户角色或者登录状态来决定是否拦截某个路径。例如,只有登录用户才能访问/user/**
路径:
registry.addInterceptor(myInterceptor).addPathPatterns("/user/**") // 拦截/user/**路径.excludePathPatterns("/login", "/signup"); // 排除/login和/signup路径
10. 条件性拦截
如果你的拦截器需要根据某些动态条件(如请求头、参数等)来决定是否拦截请求,你可以在preHandle
方法中进行检查。
例如,拦截包含特定请求头的请求:
@Component
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("Authorization");if (token != null && token.startsWith("Bearer ")) {return true; // 允许请求继续}response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");return false; // 拦截请求}
}
总结
Spring Boot中拦截路径的设置灵活多样,你可以通过精确的路径、通配符、HTTP请求方法等多种方式配置拦截规则。常见的设置有:
- 拦截所有路径或特定路径
- 排除某些路径
- 配合HTTP请求方法进行拦截
- 根据用户或其他条件动态控制是否拦截请求
通过合理地配置拦截器的路径,可以满足各种业务需求,比如权限控制、请求日志记录等。