zoukankan      html  css  js  c++  java
  • 监听器和拦截器复习

    监听器(Listener)

    监听器是一个接口,具体内容由我们来实现,监听器的实现用了观察者模式,我们实现的具体监听器就是观察者

    JavaWeb中的监听器

    事件源(被监听的对象):三大域!

    • ServletContext

    生命周期监听:ServletContextListener,它有两个方法,一个在出生时调用,一个在死亡时调用;

    1.   void contextInitialized(ServletContextEvent sce):创建SErvletcontext时
    2.   void contextDestroyed(ServletContextEvent sce):销毁Servletcontext时

     属性监听:ServletContextAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

    1.   void attributeAdded(ServletContextAttributeEvent event):添加属性时;
    2.   void attributeReplaced(ServletContextAttributeEvent event):替换属性时;
    3.   void attributeRemoved(ServletContextAttributeEvent event):移除属性时;
    • HttpSession

     生命周期监听:HttpSessionListener,它有两个方法,一个在出生时调用,一个在死亡时调用;

    1.   void sessionCreated(HttpSessionEvent se):创建session时
    2.   void sessionDestroyed(HttpSessionEvent se):销毁session时

    属性监听:HttpSessioniAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

    1.   void attributeAdded(HttpSessionBindingEvent event):添加属性时;
    2.   void attributeReplaced(HttpSessionBindingEvent event):替换属性时
    3.   void attributeRemoved(HttpSessionBindingEvent event):移除属性时
    • ServletRequest

     生命周期监听:ServletRequestListener,它有两个方法,一个在出生时调用,一个在死亡时调用;

    1.   void requestInitialized(ServletRequestEvent sre):创建request时
    2.   void requestDestroyed(ServletRequestEvent sre):销毁request时

     属性监听:ServletRequestAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

    1.   void attributeAdded(ServletRequestAttributeEvent srae):添加属性时
    2.   void attributeReplaced(ServletRequestAttributeEvent srae):替换属性时
    3.   void attributeRemoved(ServletRequestAttributeEvent srae):移除属性时

    javaWeb中完成编写监听器:

    • 写一个监听器类:要求必须去实现某个监听器接口;
    • 注册,是在web.xml中配置来完成注册!(可以使用注解的方式,在后面的笔记中我再记录)

    在web.xml文件注册形式为 :

    <listener>
    <listener-class>你编写的具体监听器类</listener-class>
    </listener>

    在三大域中都存在一个生命周期监听和一个属性监听,实际上还有几个监听类,是与HttpSession相关,但它们是用来添加到JavaBean上,而不是添加到三大域上!这两个监听器都不需要在web.xml中注册!它们可以感知session域中对象的创建和销毁

    监听器在SSH中的应用

    在SSH整合的过程中,我们在项目的web.xml文件中配置的spring监听类,其内部就是实现了一个监听器接口,使服务器在启动的时候可以加载spring的配置文件进行初始化

      <!--指定spring文件的位置 -->
       <context-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>classpath:applicationContext.xml</param-value>
       </context-param>
      
      <!--配置spring监听器,这样在服务器启动的时候来加载spring-->
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>

    拦截器(Filter)

    过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的

    当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。

    其实可以这样理解,当用户请求某个Servlet时,Tomcat会去执行注册在这个请求上的Filter,然后是否“放行”由Filter来决定。可以理解为,Filter来决定是否调用Servlet!当执行完成Servlet的代码后,还会执行Filter后面的代码

    所谓的放行就是使用:

    chain.doFilter(request, response);

    chain是javax.servlet.FilterChain的参数

    javaWeb中完成编写拦截器:

    • 写过滤器就是写一个类,实现Filter(javax.servlet.Filter)接口
    • 注册,是在web.xml中配置来完成注册!(可以使用注解的方式,在后面的笔记中我再记录)

    在web.xml文件注册形式为 :

      <filter>
        <filter-name>取个名字</filter-name>
        <filter-class>类的全路径名</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>使用上边的名字</filter-name>
        <url-pattern>要拦截的范围(可以使/*,表示拦截所有请求,还可以是拦截某个Servlet)</url-pattern>
      </filter-mapping>

    和Servlet在web.xml中的配置很相似吧

    注意:Filter在web.xml中配置是有顺序的,先配置的先拦截

    还有一个值得注意的地方是:不要认为一个请求在给浏览器输出就完成了,实际上很多事情都需要在给客户端响应之后才能完成,可以在放行语句的前后各输出一句话,可以看到,在Filter放行之后,浏览器就可以输出一个页面(如果Servlet中不做过多操作,只起一个转跳的作用),但是放行之后的语句还是会在控制台输出

    过滤器的生命周期

    Filter的生命周期(和Servlet的生命周期类似)

    • init(FilterConfig):在服务器启动时会创建Filter实例,并且每个类型的Filter只创建一个实例,从此不再创建!在创建完Filter实例后,会马上调用init()方法完成初始化工作,这个方法只会被执行一次;
    • doFilter(ServletRequest req,ServletResponse res,FilterChain chain):这个方法会在用户每次访问“目标资源(<url->pattern>index.jsp</url-pattern>)”时执行,如果需要“放行”,那么需要调用FilterChain的doFilter(ServletRequest,ServletResponse)方法,如果不调用FilterChain的doFilter()方法,那么目标资源将无法执行;
    •  destroy():服务器会在创建Filter对象之后,把Filter放到缓存中一直使用,通常不会销毁它。一般会在服务器关闭时销毁Filter对象,在销毁Filter对象之前,服务器会调用Filter对象的destory()方法

     

    四种拦截方式

    我们来做个测试,写一个过滤器,指定过滤的资源为b.jsp,然后我们在浏览器中直接访问b.jsp,你会发现过滤器执行了!

    但是,当我们在a.jsp中request.getRequestDispathcer(“/b.jsp”).forward(request,response)时,就不会再执行过滤器了!也就是说,默认情况下,只能直接访问目标资源才会执行过滤器,而forward执行目标资源,不会执行过滤器

    其实过滤器有四种拦截方式!分别是:REQUEST、FORWARD、INCLUDE、ERROR。

    • REQUEST:直接访问目标资源时执行过滤器。包括:在地址栏中直接访问、表单提交、超链接、重定向,只要在地址栏中可以看到目标资源的路径,就是REQUEST;
    • FORWARD:转发访问执行过滤器。包括RequestDispatcher#forward()方法、<jsp:forward>标签都是转发访问;
    • INCLUDE:包含访问执行过滤器。包括RequestDispatcher#include()方法、<jsp:include>标签都是包含访问;
    • ERROR:当目标资源在web.xml中配置为<error-page>中时,并且真的出现了异常,转发到目标资源时,会执行过滤器

    可以在<filter-mapping>中添加0~n个<dispatcher>子元素,来说明当前访问的拦截方式:

        <filter-mapping>
            <filter-name>myfilter</filter-name>
            <url-pattern>/b.jsp</url-pattern>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>FORWARD</dispatcher>
        </filter-mapping>

    当没有给出拦截方式时,那么默认为REQUEST,其实最为常用的就是REQUEST和FORWARD两种拦截方式,而INCLUDE和ERROR都比较少用

    我们可以使用拦截器实现一个错误转跳的功能,但发生错误就转跳到一个错误页面:

        <filter-mapping>
            <filter-name>myfilter</filter-name>
            <url-pattern>/b.jsp</url-pattern>
            <dispatcher>ERROR</dispatcher>
        </filter-mapping>
        <error-page>
            <error-code>500</error-code>
            <location>/b.jsp</location>
        </error-page>

    我们就可以在b.jsp中编写一个错误提示页面,或者是做一些其他操作

    过滤器的应用场景

    •  执行目标资源之前做预处理工作,例如设置编码,这种处理通常都会放行,只是在目标资源执行之前做一些准备工作
    • 通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;
    • 进行权限控制

    最后我们再来看看Filter在SSH整合中的使用:

    当然是Struts2的使用啦:

        <filter>
          <filter-name>struts2</filter-name>
          <filter-class>
              org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
          </filter-class>
      </filter>
      <filter-mapping>
          <filter-name>struts2</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>

    StrutPrepareAndExecuteFilter这个拦截器的作用就是拦截所有请求

  • 相关阅读:
    android数据恢复
    UVA 690 Pipeline Scheduling
    2017 国庆湖南 Day4
    2017 国庆湖南 Day5
    2017 国庆湖南 Day6
    2017国庆 清北学堂 北京综合强化班 Day1
    2017 国庆湖南Day2
    bzoj 2962 序列操作
    UVA 818 Cutting Chains
    UVA 211 The Domino Effect
  • 原文地址:https://www.cnblogs.com/lz2017/p/7077912.html
Copyright © 2011-2022 走看看