1. Interceptor 介绍
拦截器(Interceptor) 和 过滤器 (Filter) 一样,也是面向AOP编程的。
拦截器用于在请求发送到服务器之前或者响应发送到客户端之前做一些处理工作。
2. Interceptor 作用
- 权限校验:例如检测用户是否登录、校验用户权限等
- 日志记录:记录到达服务器的请求信息,以便进行监控、统计PV等
- 性能监控:通过拦截器在请求到达处理器之前记录开始时间,当处理结束后记录结束时间,从而计算请求的响应时长
- 通用行为:例如读取Cookie中的用户信息,存在在用户对象中以便后续流程使用
3. 自定义 Interceptor
用户在自定义 Interceptor 的时,必须要实现HandlerInterceptor
接口或者继承HandlerInceptorAdapter
类,然后重写以下3个方法:
(1) preHandler()
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
preHandler() 方法在请求处理之前被调用,用来对当前请求进行预处理,然后判断当前请求是否需要继续执行下去。preHandler() 方法返回boolean类型,当返回值为false时,表示请求结束,后续的 Interceptor 和 Controller 都不再执行;当返回值为true时,会继续执行下一个 Interceptor 或者执行 Controller
(2) postHandler()
void postHandler(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
postHandler() 方法在响应发送到客户端之前被调用,同时也在 DispatcherServlet 渲染视图之前被调用,因此,可以在postHandler()方法中对ModelAndView对象进行操作
(3) afterCompletion()
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception
afterCompletion() 方法在DispatcherServlet 渲染视图之后被调用,也是拦截器3个方法中最后执行的,常用来做收尾工作
说明:
- 在Java8中,如果不重写上述3个方法也不会报错,这是因为在Java8中HandlerInterceptor接口的方法是default方法。
- 自定义的 Interceptor 类需要使用
@Component
注解,将其作为SpringBoot的组件。
4. 注册 Interceptor
在实现了自定义的 Interceptor 类后,还需要在配置类WebConfig
中将 Interceptor 注册到拦截器注册表中,配置类WegConfig
必须实现WebMvcConfigurer
接口。
自定义LoginInterceptor拦截器
@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandler(HttpServletRequest request, HttpServletResponse responst, Object handler) throws Exception {
long startTime = System.currentTimeMillis();
request.setAttribute("startTime", startTime);
return true;
}
@Override
public void afterCompletion(HttpServletRquest request, HttpServletResponse respose, Object handler, Exception ex) {
long startTime = (long) resquest.getAttribute("startTime");
long endTime = System.currentTimeMillis();
System.Out.Println("Time taken:" + (endTime - startTime));
}
}
注册 LoginInterceptor
@Configuration
public class WebConfig extends WebMvcConfigurer {
@Autowired
LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册LoginInterceptor拦截器
registry.addInterceptor().addPathPatterns("/**").excludePathPatterns("/admin/login");
}
}
网友评论