1. 拦截器:Interceptor
SpringMVC拦截器是SpringMVC框架中的一种组件,它可以执行在请求之前或者之后。通常用于解决处理若干请求都需要执行的任务,例如验证用户之前是否已经是登录状态。
2.拦截器的使用
我们要使用SpringMVC拦截器,首先要自定义一个类实现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()");
}
}
以上的三种方法分别执行在不同的时间节点:
preHandle()
:在控制器(Controller
)之前执行,此方法的返回值是boolean
类型的,当返回true
时表示“放行”,当返回false
时表示“阻止”,当阻止时,程序不会向后继续运行,例如控制器将不会执行
postHandle()
:在控制器(Controller
)之后执行
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.设置拦截路径
在配置拦截路径时,可以使用星号(*
)作为通配符,但是,只能匹配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
集合。
4.拦截器和过滤器的区别
以上讨论的拦截器(Interceptor
)是Spring MVC框架中的组件,而过滤器(Filter
)是Java EE中的组件。
过滤器是最早接收到客户端请求的组件,是执行在所有组件之前的,而拦截器是执行在Spring MVC的控制器(Controller
)之前和之后的。
- 基于以上特点,某些问题只能通过过滤器来解决,
- 例如:设置字符编码
- Spring Security的相关过滤器
过滤器只能配置“黑名单”,不可以配置“白名单”,所以,使用时并不是那么方便,而拦截器的配置更加灵活!