SpringBoot 拦截器

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");
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容