1. Spring MVC拦截器
1.1. 关于拦截器
拦截器:Interceptor
Spring MVC拦截器是Spring MVC框架中的一种组件,它可以执行在若干个请求之前、之后,通常用于解决处理若干个请求都需要执行的任务,例如验证用户是否已经登录等。
1.2. 使用拦截器
使用Spring MVC拦截器,首先,需要自定义类,作为拦截器类,这个类必须实现HandlerInterceptor
接口,例如:
@Slf4j
@Component
public class DemoInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.debug("DemoInterceptor.preHandle()");
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.debug("DemoInterceptor.postHandle()");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.debug("DemoInterceptor.afterCompletion()");
}
}
每个拦截器都必须注册后才可以生效,在Spring MVC的配置类(实现了WebMvcConfigurer
接口的配置类)中重写addInterceptors()
方法即可实现注册,例如:
@Autowired
private DemoInterceptor demoInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(demoInterceptor)
.addPathPatterns("/brands", "/categories/list-by-parent");
}
通过测试运行,可以发现,拦截器的3个方法:
preHandle()
:在控制器(Controller
)之前执行,此方法的返回值是boolean
类型的,当返回true
时表示“放行”,当返回false
时表示“阻止”,当阻止时,程序不会向后继续运行,例如控制器将不会执行postHandle()
:在控制器(Controller
)之后执行afterCompletion()
:在处理完整个浏览,即将向客户端进行响应之前执行
1.3. 配置拦截路径
在配置拦截路径时,可以使用星号(*
)作为通配符,但是,只能匹配1层路径,例如:使用/brands/*
可以匹配/brands/add-new
、/brands/list
,却不可以匹配到/brands/1/delete
。
如果要匹配若干层路径,需要使用2个连续的星号(**
),例如:使用/brands/**
,可以匹配到/brands/add-new
、/brands/list
、/brands/1/delete
、/brands/1/status/disable
……
一旦使用通配符,可能导致匹配的范围过大,例如:配置为/admins/**
,将匹配到/admins/change-password
、/admins/upload-avatar
等,还会匹配到/admins/login
等,如果此拦截器是用于验证“是否登录”的,将/admins/login
也拦截是不合适的!
在配置拦截路径时,还可以调用excluedePathPatterns()
方法,在已有的拦截范围中添加“排除在外”的请求路径,例如:
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(demoInterceptor)
.addPathPatterns("/admins/**")
.excludePathPatterns("/admins/login");
}
提示:以上addPathPatterns()
和excludePathPatterns()
这2个方法的参数都可以是可变参数,或List
集合。
1.4. 拦截器与过滤器的区别
以上讨论的拦截器(Interceptor
)是Spring MVC框架中的组件,而过滤器(Filter
)是Java EE中的组件。
过滤器是最早接收到客户端请求的组件,是执行在所有组件之前的,而拦截器是执行在Spring MVC的控制器(Controller
)之前和之后的。
- 基于以上特点,某些问题只能通过过滤器来解决,例如:
- 设置字符编码
- Spring Security的相关过滤器
过滤器只能配置“黑名单”,不可以配置“白名单”,所以,使用时并不是那么方便,而拦截器的配置更加灵活!