美文网首页
过滤器,监听器,拦截器

过滤器,监听器,拦截器

作者: bit_拳倾天下 | 来源:发表于2021-03-01 14:49 被阅读0次

    过滤器

    Filter 是 Servlet 的一种工具,用于对 web 服务器管理的 web 资源(例如Jsp, Servlet, 静态图片文件或静态 html 文件等 )进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。思想是过滤器模式(责任链模式)。

    实现方式:
    1、实现 javax.servlet.Filter 接口,并实现方法;

    @Slf4j
    public class TestFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            log.info("initFilter----------------");
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            log.info("doFilter----------------");
            filterChain.doFilter(servletRequest, servletResponse);
        }
    
        @Override
        public void destroy() {
            log.info("destroyFilter----------------");
        }
    }
    

    2、注入到 servlet 容器

    1. 如果用的是外置的 tomcat 容器,直接在 webapp/web.xml 中添加 filter 映射即可
     <filter>
           <filter-name>TestFilter </filter-name>
           <filter-class>TestFilter 权限定类名</filter-class>
       </filter>
       
       <!--映射过滤器-->
       <filter-mapping>
           <filter-name>TestFilter </filter-name>
           <!--“/*”表示拦截所有的请求 -->
           <url-pattern>/*</url-pattern>
       </filter-mapping>
    
    1. 如果用 SpringBoot 的内嵌 tomcat 容器,是没有 web.xml 的,需要在配置类中添加
    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
        @Bean
        public FilterRegistrationBean testFilter(){
            FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean<>(new TestFilter());
            return filterRegistrationBean;
        }
    }
    

    监听器

    Servlet 中用于对系统的域对象产生、销毁,绑定等进行监听的组件,
    Servlet监听器分为三大类

    1、ServletContextListener : 用来监听ServletContext对象的创建和销毁
    2、HttpSessionListener: HttpSession 数据对象创建和销毁监听器
    3、ServletRequestListener: HttpServletRequest对象的创建和销毁监听器

    Servlet监听器详解及举例

    拦截器

    通常,拦截器是指 SpringMvc 中的 拦截器,用于拦截请求,从而做一些处理。
    实现 SpringMvc 拦截器:

    1. 实现 HandlerInterceptor, 或者继承 HandlerInterceptorAdapter,实现方法;
      题外话:

    HandlerInterceptorAdapter 是 HandlerInterceptor 的抽象实现类,目的就是为了避免开发拦截器,需要重写所有的的 HandlerInterceptor 方法;
    但是 java 从 1.8 开始,接口支持 default 方法,即接口内部也可以有方法实现,下面是 HandlerInterceptor 的源码:

    public interface HandlerInterceptor {
        default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            return true;
        }
    
        default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        }
    
        default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        }
    }
    

    所以,在实现 HandlerInterceptor 的时候,可以只重写自己关注的方法,其他方法则可以不用实现,这样一来,HandlerInterceptorAdapter 貌似就没啥用了。同样的情况也出现在上面的 WebMvcConfigurer 和 WebMvcConfigurerAdapter 等很多这样类似的组合,所以很多 XXXAdapter 都已经被标注为过时。

    实现:

    public class TestInterceptor implements HandlerInterceptor {
        //在请求发生前执行
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            if(true){
              //放行
              return true;
            }else{
              //终端请求
              return false;
            }
        }
        
        /**
          *在Controller的方法调用之后,在DispatcherServlet进行视图的渲染之前,可以对ModelAndView进行操作
          *前提是 preHandle 返回 true
          */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
        }
        /**
          *DispatcherServlet进行视图的渲染之后,多用于清理资源
          *前提是 preHandle 返回 true
          */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
        }
    }
    
    1. 在 WebMvcConfigurer 中重写 addInterceptors(), 将拦截器加入到 registry
    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
        @Bean
        public FilterRegistrationBean testFilter(){
            FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean<>(new TestFilter());
            return filterRegistrationBean;
        }
    
           @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new TestInterceptor())
                    .addPathPatterns("/*","/**")
                    .excludePathPatterns("/abc");
        }
    }
    

    三者对比

    对比 过滤器 监听器 拦截器
    依赖于 Servlet Servlet SpringMvc
    针对 Web请求 系统域对象的监听 Web请求
    实现方式 函数回调 事件触发 动态代理

    另外,拦截器和过滤器还有几点不通
    1.拦截器也是一个Spring的组件,归Spring管理,配置在Spring文件中,因此能使用Spring里得任何资源、对象,例如Service对象、数据源、事务管理等,通过Ioc注入道拦截器即可。而Filter则不能。

    相关文章

      网友评论

          本文标题:过滤器,监听器,拦截器

          本文链接:https://www.haomeiwen.com/subject/eziofltx.html