zoukankan      html  css  js  c++  java
  • 拦截器、过滤器、监听器各有什么作用

    这里是修真院后端小课堂,每篇分享文从

    【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】

    八个方面深度解析后端知识/技能,本篇分享的是:

    【 拦截器、过滤器、监听器各有什么作用】

    大家好,我是IT修真院西安分院第4期的JAVA学员,一枚正直纯洁善良的JAVA程序员。今天给大家分享一下,拦截器、过滤器、监听器各有什么作用

    一、.背景介绍

    1、拦截器

          Interceptor是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个Action执行

               的前后执行的代码,也可以在一个Action执行前阻止其执行 。同时也提供了一种可以提取Action中可重用

               的部分的方式。

     2、过滤器

            Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码,做一些业务逻辑

               判断,过滤器随web应用启动而启动,只初始化一次,只有当web应用停止或重新部署才销毁

     3、  监听器

            Listener是实现了javax.servlet.ServletContextListener接口的服务器端程序,

              它也是随web应用的启动而启动,只初始化了一次,随web应用的停止而销毁。

              主要作用是:做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者

              是一些固定的对象等等。

    二、知识剖析

           2.知识剖析

               拦截器的实现方法:

                主要通过两种途径,第一种是实现HandlerInterceptor接口,第二种是实现WebRequestInterceptor接口。</P>

                  拦截器的使用

                项目中使用:编写实现接口的类+springMVC.xml中配拦截器只需要实现HandlerInterceptor或者WebRequestInterceptor, 重写相应的preHandle(...)、postHandle(...)和afterCompletion(...)方法即可</p>

          (1)HandlerInterceptor 接口

             在该接口中,定义了 3 个方法,分别为preHandle()、postHandle()和afterCompletion(),通过复写这 3 个方法来对用户的请求进行拦截处理

            而且在 Spring 框架中,还提供了另外一个接口和一个抽象类,实现了对HandlerInterceptor接口的功能扩展,分别为:AsyncHandlerInterceptor和HandlerInterceptorAdapter.

            在实际应用中,一般都是通过实现HandlerInterceptor接口或者继承HandlerInterceptorAdapter抽象类

        1)preHandle方法,该方法在请求处理之前进行调用。

         SpringMVC 中的 Interceptor 是链式调用的,在一个请求中可以同时存在多个 Interceptor 。每个 Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是preHandle 方法,因此可以在这个方法中进行一些前置初始化操作或者是对当前请求做一个预处理,也可以进行一些判断来决定请求是否要继续进行下去。

        当它返回为 false 时,表示请求结束,后续的 Interceptor 和 Controller 都不会再执行;

        当返回值为 true 时,就会继续调用下一个 Interceptor 的 preHandle 方法,如果已经是最后一个 Interceptor 的时候,就会调用当前请求的 Controller 中的方法。

         2)postHandle方法在在当前所属的 Interceptor 的 preHandle 方法的返回值为 true 的时候,才能被调用。

           当前请求被处理之后,也就是在 Controller 中的方法调用之后执行,但是它会在 DispatcherServlet 进行视图返回渲染之前被调用,所以可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作。

         postHandle 方法被调用的方向跟 preHandle 是相反的,先声明的 postHandle 方法反而会后执行。

        3)afterCompletion方法,也是需要当前对应的 Interceptor 的 preHandle 方法的返回值为 true 时才会执行。因此,该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行,这个方法的主要作用是用于进行资源清理的工作。

      (2)WebRequestInterceptor 接口 

           在此接口中也定义了 3 个方法,同HandlerInterceptor接口完全相同,也需要复写这 3 个方法来对用户的请求进行拦截处理。而且这 3 个方法都传递了同一个参数 WebRequest。

          它里面的方法定义跟 HttpServletRequest 类似,在WebRequestInterceptor中对 WebRequest 进行的所有操作都将同步到 HttpServletRequest 中,然后在当前请求中依次传递。

            1)preHandle(WebRequest request)方法,该方法跟 HandlerInterceptor 中的 preHandle 不同,

              主要区别在于该方法无返回值。因此不能通过返回值决定是否终止请求。其主要作用是进行资源的准备工作。

             2)postHandle(WebRequest request, ModelMap model)方法,同样也是在controller之后,

              视图返回被渲染之前被调用。该方法有两个参数,WebRequest 对象是用于传递整个请求数据的,

              比如在 preHandle 中准备的数据都可以通过 WebRequest 来传递和访问;

              3)afterCompletion(WebRequest request, Exception ex)方法,同样是在视图渲染之后调用, 主要用来进行资源的释放。

          过滤器

           Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter 技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。 

          Filter接口中有一个doFilter方法,当我们编写好Filter,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法,因此,在该方法内编写代码可达到如下目的:

           调用目标资源之前,让一段代码执行;

           是否调用目标资源(即是否让用户访问web资源);

           调用目标资源之后,让一段代码执行。<br>

           过滤器的使用

           项目中使用:编写实现接口的类+web.xml中配置

             过滤器只需要实现javax.servlet.filter,重写doFilter(...)、init(...)和destroy(..)方法即可

             web服务器在调用doFilter方法时,会传递一个filterChain对象进来,

             filterChain对象是filter接口中最重要的一个对 象,它也提供了一个doFilter方 ,开发人员可以根据需求决定是否调用此方法,调用该方法,

                则web服务器就会调用web资源的service方 法,即web资源就会被访问,否则web资源不会被访问。</p>

            过滤器中的方法

            init: 程序启动时,web服务器将创建Filter的实例对象,并调用其init方法,完成对象的初始化 功能;filter对象只会创建一次,init方法也只会执行一次。

              doFilter:当访问web服务器时对请求进行操作。

               destroy:web容器调用destroy方法销毁Filter。destroy方法在Filter的生命周期中仅执行一次。在destroy方法中,可以释放过滤器使用的资源。

               监听器

             监听web应用,监听许多信息的初始化,销毁,增加,修改,删除等 。

           监听器对象可以在事情发生前、发生后可以做一些必要的处理。

            监听器的分类

              <p>1、ServletContext监听</p>

              <p>ServletContextListener:用于对Servlet整个上下文进行监听(创建、销毁)。</p>

              <p>ServletContextAttributeListener:对Servlet上下文属性的监听(增删改属性)。

            需要实现ServeltContextAttrbuteListener接口;</p>

              <p>2、Session监听</p>

              <p>HttpSessionListener接口:对Session的整体状态的监听。</p>

              <p>HttpSessionAttributeListener接口:对session的属性监听。

            主要监听session属性的更改、添加、删除,需要实现HttpSessionAttrbuteListener接口</p>

            3、Request监听

             ServletRequestListener:用于对Request请求进行监听(创建、销毁)。

               ServletRequestAttributeListener:对Request属性的监听(增删改属性)。

            需要实现ServletRequestAttrbuteListener接口;

              监听器的使用

             项目中使用:编写实现接口的类+web.xml中配置

            监听器接口主要有四类八种,能够监听包括request域,session域,

            application域的产生,销毁和属性的变化

            监听对象的创建:1.ServletContext:主要监听servletContext的创建,

            需要实现ServeltContextListener接口;

            2.ServletRequest:主要监听request的创建,

            需要实现ServletRequestListener接口;3.HttpSession:主要监听session的创建,

            需要实现HttpSessionListener接口  

    三、常见问题

            拦截器、过滤器、监听器的区别是什么?

    四、解决方案

      1.从关注的点来说:过滤器拦截器作用域web请求,并对一些信息做相应的更改;监听器作用于系统级别的参数的监听,一般不做更改。

       2.所依赖的支持来说:拦截器需要Spring的支持;过滤器、监听器需要servlet的支持。

       3.应用场景的不同

       拦截器:拦截未登录、审计日志等;

       过滤器:设置字符编码、URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等;

        监听器:统计在线人数、清除过期session

    五、编码实战

    六、扩展思考

    1.拦截器、过滤器、监听器的执行顺序?

        1.拦截器、过滤器、监听器的执行顺序

                  监听器 > 过滤器 > 拦截器 > servlet执行 > 拦截器 > 过滤器 > 监听器              

    七、参考文献

    https://www.cnblogs.com/qdhxhz/p/8468913.html

    八、更多讨论

    Q1:(西安分院秦永辉)2.多个拦截器的执行顺序(两个)</p>

      (1)当俩个拦截器都实现放行操作时,顺序为preHandle 1,preHandle 2,postHandle 2,postHandle 1,afterCompletion 2,afterCompletion 1;      

      (2)当第一个拦截器preHandle返回false,也就是对其进行拦截时,第二个拦截器是完全不执行的,第一个拦截器只执行preHandle部分;             

      (3)当第一个拦截器preHandle返回true,第二个拦截器preHandle返回false,顺序为preHandle 1,preHandle 2 ,afterCompletion 1。       

    Q2:(西安分院郭靖).多个过滤器的执行顺序

          web服务器根据Filter在web.xml中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法,在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第二个filter,如果没有,则调用目标资源。         

      Q3: (西安分院秦永辉)  4.多个监听器的执行顺序

           一个webServlet里面若有多个监听器的话,顺序是按照加载的顺序来加载和注册的这些servlet监听器的。     

    这里是技能树.IT修真院,成千上万的师兄在这里找到了自己的学习路线,学习透明化,成长可见化,师兄1对1免费指导。快来与我一起学习吧~我的邀请码:28769611,或者你可以直接点击此链接:http://www.jnshu.com/login/1/28769611

    今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~

    更多内容,可以加入IT交流群565734203与大家一起讨论交流

    这里是技能树·IT修真院:https://www.jnshu.com,初学者转行到互联网的聚集地

  • 相关阅读:
    第二百零一天 how can I坚持
    第一百九十七-第二百天 how can I 坚持
    第一百九十六天 how can I 坚持
    第一百九十五天 how can I 坚持
    第一百九十四天 how can I坚持
    第一百九十三天 how can I 坚持
    第一百九十二天 how can I 坚持
    第一百九十一天 how can I 坚持
    杭电2085--核反应堆(打表)
    杭电1799--循环多少次
  • 原文地址:https://www.cnblogs.com/jnshu/p/10172077.html
Copyright © 2011-2022 走看看