zoukankan      html  css  js  c++  java
  • 过滤器和拦截器

    过滤器和拦截器

    Filter

    1. SpringBoot启动默认加载的Filter
      • characterEncodingFilter
      • hiddenHttpMethodFilter
      • httpPutFormContentFilter
      • requestContextFilter
    2. Filter 优先级
      • Ordered.HIGHEST_PRECEDENCE
      • Ordered.HIGHEST_PRECEDENCE
        • 低位值意味着更高的优先级 Higher values are interpreted as lower priority
        • 自定义Filter,避免和默认的Filter优先级一样,不然会冲突
    3. 自定义 Filter
      • 新建一个 Filter 类,实现 javax.servlet.Filter 接口
      public class MyFilter  implements Filter {
      
          @Override
          public void init(FilterConfig filterConfig) throws ServletException {
              System.out.println("filter init");
          }
      
          @Override
          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
              // 可以对 request 和 response 进行强转进行后续处理
              System.out.println("coming in");
              // 放行
              filterChain.doFilter(servletRequest, servletResponse);
          }
      
          @Override
          public void destroy() {
              System.out.println("filter destroy");
          }
      }
      
      • 两种方式添加 Filter 进 Spring
        1. servlet 3.0 方式
        • 在自定义 Filter 上添加注解 @WebFileter(urlPatterns={"/api/*"})
          • 支持正则
        • 在启动类添加扫描注解 @ServletComponentScan
        1. config 方式
        • 在自定义 Filter 上添加注解 @Component
        • 添加一个配置类
        /**
         * 对原始 filter 进行配置
         */
        @Configuration
        public class WebConfig {
        
            @Bean
            public FilterRegistrationBean<MyFilter> myFilter(){
                FilterRegistrationBean<MyFilter> filterRegistrationBean = new FilterRegistrationBean<>();
                MyFilter filter = new MyFilter();
                filterRegistrationBean.setFilter(filter);
                // 可以设置不同的 url
                List<String> urls = new LinkedList<>();
                urls.add("/api/*");
                filterRegistrationBean.setUrlPatterns(urls);
                return filterRegistrationBean;
            }
        }
        
        

    Servlet

    原生

    • 添加 servlet
    @WebServlet(name = "userServlet",urlPatterns = "/test/customs")
    public class UserServlet extends HttpServlet {
    
        @Override
        public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.getWriter().print("custom sevlet");
            resp.getWriter().flush();
            resp.getWriter().close();
        }
    }
    
    • 启动类配置 @ServletComponentScan

    Listener 监听器

    • 常用的监听器
      • servletContextListener
      • httpSessionListener
      • servletRequestListener
    • 自定义Listener
    @WebListener
    public class RequestListener implements ServletRequestListener {
    
        @Override
        public void requestDestroyed(ServletRequestEvent sre) {
        	// TODO Auto-generated method stub
        	System.out.println("======requestDestroyed========");
        }
        
        @Override
        public void requestInitialized(ServletRequestEvent sre) {
        	System.out.println("======requestInitialized========");
        	
        }
    }
    
    • 启动类配置 @ServletComponentScan

    拦截器

    1. 新建配置类
    • 1.x
      • 继承 WebMvcConfigurationAdapter
    • 2.x
      • 实现 WebMvcConfigurer
          /**
           * 配置拦截器
           */
          @Configuration
          public class WebConfigTwo implements WebMvcConfigurer {
              @Autowired
              private TimeInterceptor timeInterceptor;
          
              @Override
              public void addInterceptors(InterceptorRegistry registry) {
                  registry.addInterceptor(timeInterceptor)
                      .addPathPatterns("/user/**")
                      .excludePathPatterns("/user/all");
              }
          }
      
    1. 自定义拦截器 HandlerInterceptor
    @Component
    public class TimeInterceptor implements HandlerInterceptor {
        /**
         * 进入 controller 之前
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println(" preHandle ");
            request.setAttribute("start", LocalDateTime.now().toEpochSecond(ZoneOffset.UTC));
    
            System.out.println(((HandlerMethod)handler).getBean().getClass().getName());
            System.out.println(((HandlerMethod)handler).getMethod().getName());
    
            return true;
        }
    
        /**
         * controller 返回之前, 出现异常则不会执行
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println(" postHandle ");
            long start = (long) request.getAttribute("start");
            System.out.println("花费了: " + (LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)-start));
        }
    
        /**
         * 不管 controller 是正常返回还是异常,都会进入
         * 会被 @ControllerHandler 中的 @ExceptionHandler 给吃掉
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println(" afterCompletion ");
            System.out.println("ex is : " + ex);
        }
    }
    
    
    1. 按照注册顺序进行拦截
    • 先注册,先被拦截

    拦截器不生效常见问题:

    1. 是否有加 @Configuration
    2. 拦截路径是否有问题 ** 和 *
    3. 拦截器最后路径一定要 "/**", 如果是目录的话则是 "/*/"

    Filter 和 Intercepter 区别

    Filter Interceptor
    基于函数回调 doFilter() 基于 AOP 思想
    只在Servlet前后起作用 深入到方法前后、异常抛出前后等
    依赖于 Servlet 容器即web应用中 不依赖于Servlet 容器所以可以运行在多种环境。
    只能在容器初始化时调用一次 接口调用的生命周期里, 可以被多次调用

    执行顺序

    过滤前->拦截前->action执行->拦截后->过滤后

  • 相关阅读:
    ●BZOJ 2752 [HAOI2012]高速公路(road)
    ●UVA 11021 tunnello
    ●POJ 2794 Double Patience
    【51Nod1555】布丁怪
    【LG1600】[NOIP2016]天天爱跑步
    【LG5171】Earthquake
    【LG4437】[HNOI/AHOI2018]排列
    【CF1097F】Alex and a TV Show
    【51Nod 1769】Clarke and math2
    【LG5330】[SNOI2019]数论
  • 原文地址:https://www.cnblogs.com/scp-166/p/11942129.html
Copyright © 2011-2022 走看看