ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Filter和Interceptor 使用场景和原理(二)

2022-07-27 23:04:34  阅读:179  来源: 互联网

标签:场景 请求 request System Filter 拦截器 startTime Interceptor


上接:Filter和Interceptor 使用场景和原理(一) - liyanbo - 博客园 (cnblogs.com)

上接 Filter和Interceptor 使用场景和原理(一), (一)主要对Filter 过滤器进行了总结和梳理,下面进行inteceptor的介绍,该Interceptor,中如果读request 请求数据需依赖 (一)过滤器,传递 RequestWrapper增强请求对象,使用该对象可以对请求数据Body读取多次,如果不使用只能读取一次。

Interceptor

一、原理定义说明

1、创建 MyIntecptor 需要实现 implements HandlerInterceptor 

2、Inteceptor 接口方法说明 

      preHandler(HttpServletRequest request, HttpServletResponse response, Object handler) 方法在请求处理之前被调用。如果已经是最后一个 Interceptor 的时候就会调用当前请求的 Controller 方法。

     postHandler(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) 方法在当前请求处理完成之后,所以我们可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作。 

     afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法需要在当前对应的 Interceptor 类的 preHandle 方法返回值为 true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行。此方法主要用来进行资源清理

3、Inteceptor 用途

     1)、鉴权

     2)、增加属性参数:  request.setAttribute("startTime", startTime)

     3)、记录 请求->响应时间   preHandle:记录开始时间  afterCompletion:记录结束时间  相减

     4)、通用行为:读取 Cookie 得到用户信息,并解析后将用户对象放入请求

 4、请看图

  

二、代码实例

1、MyInterceptor  定义拦截器 需实现HandlerInterceptor

/**
 * 拦截器
 * filter——>servlet->interceptor->controller
 * 用于处理:
 *  1、鉴权
 *  2、增加属性参数:  request.setAttribute("startTime", startTime)
 *  3、记录 请求->响应时间   preHandle:记录开始时间  afterCompletion:记录结束时间  相减
 *  4、通用行为:读取 Cookie 得到用户信息,并解析后将用户对象放入请求
 *
 */
@Component
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public  boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        long startTime = System.currentTimeMillis();
        System.out.println("\n-------- LogInterception.preHandle --- ");
        System.out.println("Request URL: " + request.getRequestURL());
        request.setAttribute("startTime", startTime);// 增加参数
        if(request instanceof RequestWrapper){
            // 获取请求参数
            String bodyData=((RequestWrapper) request).getRequestBody();
            System.out.println("bodyData = " + bodyData);
        }

        // 统一拦截(查询token)
        String token = request.getHeader("token");
        if(StringUtils.isEmpty(token)){
             //throw new  CustomException(ResultEnum.MY_EXCEPTION.code,ResultEnum.MY_EXCEPTION.msg);
            // 验证登录,可以抛出自定义异常
            // return  false;
        }

        System.out.println("preHandle方法在控制器的处理请求方法调用之后,解析视图之前执行");
        return true; // 返回 true: 正常执行   false:该请求停止向下运行
    }

    @Override
    public  void  postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle方法在控制器的处理请求方法调用之后,解析视图之前执行");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {

        long startTime = (Long) request.getAttribute("startTime");
        long endTime = System.currentTimeMillis();
        System.out.println("Request URL: " + request.getRequestURL());
        System.out.println("End Time: " + endTime);
        System.out.println("Time Taken: " + (endTime - startTime));

    }

}

2)WebConfig  将拦截器注册添加到拦截器链

 

Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private MyInterceptor myInterceptor;
   @Override
   public void addInterceptors(InterceptorRegistry registry) {
       registry.addInterceptor(myInterceptor).addPathPatterns("/**");
       // .excludePathPatterns("/user/get")/.addPathPatterns(). 可以排除和指定设置
    }

}

 

三、Filter和Inteceptor 的区别说明

1、使用范围不同
  过滤器Filter实现了javax.servlet.Filter接口,也就是说过滤器的使用要依赖于Tomcat等容器,所以它只能在web程序中使用。
拦截器Interceptor实现了org.springframework.web.servlet接口,它是由Spring容器进行管理,并不依赖Tomcat等容器,既可以应用在web程序中,也可以应用在非web程序中。
2、触发时机不同
  过滤器Filter是在请求进入Tomcat等容器后,servlet处理之前进行调用的。
  拦截器Interceptor是在请求进入servlet后,执行Controller之前进行调用的。

3、深度不同:

  Filter在只在Servlet前后起作用。而拦截器能够深入到方法前后、异常抛出前后等,因此拦截器的使用具有更大的弹性。所以在Spring构架的程序中,要优先使用拦截器。

 

至此Fitler和Inteceptor 原理和使用场景就总结和梳理就结束了,如有看不明白或疑问可以随时沟通交流,qq:626382542

代码实例:https://files.cnblogs.com/files/liyanbofly/filterIntecptorDemo.rar?t=1658933924

 

标签:场景,请求,request,System,Filter,拦截器,startTime,Interceptor
来源: https://www.cnblogs.com/liyanbofly/p/16526832.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有