• 监听器和拦截器复习


    监听器(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这个拦截器的作用就是拦截所有请求

  • 相关阅读:
    C++中如何使用大整数__int 128
    全排列问题
    读书札记:瑞士法郎的因素
    读书札记:影响欧元的因素
    金融市场:最全的外汇平台资料大全(包括开户金额、点差、特色!)
    读书札记:澳大利亚元因素
    情感日记:祭衣文
    情感日记:第一次亲密的接触
    读书札记:美元影响的因素
    读书札记:外汇市场
  • 原文地址:https://www.cnblogs.com/lz2017/p/7077912.html
Copyright © 2020-2023  润新知