zoukankan      html  css  js  c++  java
  • filter(过滤器)和listener(监听器)

    Filter

    简介

    Filter也称之为过滤器,是Servlet2.3新增的一个特性,主要用于过滤url请求,通过FIlter我们可以实现URL请求资源权限验证,用户登录检测等功能。

    Filter是一个接口,实现一个Filter只需要重写init、doFilter、destroy方法即可,其中过滤逻辑都在doFilter方法中实现。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。

    Filter的工作原理

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

    • 调用目标资源之前,让一段代码执行。
    • 是否调用目标资源(也就是是否让用户访问web资源)
    • 调用目标资源之后,让一段代码执行。

    web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对象,它也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方法,即web资源就会被访问,否则web资源不会被访问。

    Filter的使用

    通常,我们使用filter过滤器一般是用来进行一些统一的操作,比如登录验证,对拼接了用户输入的请求进行过滤等。

    定义步骤:

    • 定义一个类,视线接口Filter
    • 重写方法
    • 配置拦截路径

    针对于配置拦截路径的方法有两种,第一种就是之前经常使用的在代码前面加上注解进行配置,第二钟就是在web.xml中进行配置。

    注解配置拦截路径

    package Fileter;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    
    
    @WebFilter("/*")
    public class Demo01 implements Filter{
        public void destroy(){
            System.out.println("filter销毁");
        }
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            request.setCharacterEncoding("utf-8");
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
            System.out.println("调用servlet之前执行一段代码");
            chain.doFilter(request,response);
            System.out.println("调用servlet之后执行的一段代码");
        }
    
        public void init(FilterConfig config) throws ServletException{
    
        }
    }
    

    web.xml配置拦截路径

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
        <filter>
            <filter-name>Demo01</filter-name>  //声明名字
            <filter-class>Fileter.Demo01</filter-class> //指定filter过滤器
        </filter>
        
        <filter-mapping>
            <filter-name>Demo01</filter-name>
            <url-pattern>/*</url-pattern> //声明拦截对象  
        </filter-mapping>
    </web-app>
    

    在刚才的代码演示里面,可以看到filter类需要重写三个方法,分别是:

    • init:在服务器启动后,会创建Filter对象,然后调用init方法,只执行一次,用于加载资源
    • doFilter:请求的时候执行的代码主体,如果我们需要让过滤器完成什么功能,就可以将代码写在其中,该方法会在每一次请求被拦截的时候执行,可执行多次
    • destroy:在服务器关闭后,Filter对象被销毁,如果服务器是正常关闭的,就会执行destroy方法,只执行一次,用来释放资源。

    除了之前演示的那种之外,拦截器还能拦截以下三种类型的请求。

    1. 具体资源路径:/test.jsp 如果这么定义,就会拦截指定的资源,也就是在用户访问这个页面的时候,过滤器才会执行。
    2. 目录拦截: /test/* 如果这么定义,就会拦截任意对指定文件夹发起的请求,也就是在用户访问这个目录下文件的时候,过滤器才会执行。
    3. 后缀名拦截: *.jsp 如果这么定义,就会拦截后缀名是.jsp的文件发起的请求,也就是在用户访问指定后悔名的时候,过滤器才会执行。

    定义拦截方式

    注解里面定义拦截路径,默认是REQUEST方式,也就是浏览器直接访问,使用转发或者是其他请求方式一样是会被拦截器给拦截的。

    如果我们希望转发访问资源不被拦截器拦截,可以在注解中配置dispatcherTypes属性的值。

    dispathcherTypes有五种属性:

    • REQUEST:浏览器直接请求资源(默认值)
    • FORWARD:转发访问资源
    • INCLUDE:包含访问资源
    • ERROR:错误跳转资源
    • ASYNC:异步访问资源

    注解方式定义拦截方式

    package Fileter;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    
    
    @WebFilter(value = "/*",dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.FORWARD})// 定义浏览器请求和转发拦截器执行
    public class Demo01 implements Filter{
        public void destroy(){
            System.out.println("filter销毁");
        }
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            request.setCharacterEncoding("utf-8");
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
            System.out.println("调用servlet之前执行一段代码");
            chain.doFilter(request,response);
            System.out.println("调用servlet之后执行的一段代码");
        }
    
        public void init(FilterConfig config) throws ServletException{
    
        }
    }
    

    web.xml配置定义拦截方式

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
        <filter>
            <filter-name>Demo01</filter-name>
            <filter-class>Fileter.Demo01</filter-class>
        </filter>
    
        <filter-mapping>
            <filter-name>Demo01</filter-name>
            <url-pattern>/*</url-pattern>
            
            <dispatcher>REQUEST</dispatcher>
        </filter-mapping>
        
    </web-app>
    

    Filter链

    在一个web应用中,可以开发编写多个Filter,这些个Filter组合起来称之为Filter链。web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter, 如果有,则调用第二个filter,如果没有,则调用目标资源。

    Listener

    简介

    监听器用于监听web应用中某些对象、信息的创建、销毁、增加、修改、删除等动作的发生,然后做出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等等。

    分类

    按照监听的对象划分

    • ServletContext对象监听器
    • HttpSession对象监听器
    • ServletRequest对象监听器

    按监听的事件划分

    • 对象自身的创建和销毁的监听器
    • 对象中属性的创建和消除的监听器
    • session中的某个对象的状态彼岸花的监听器

    监听器的例子:用监听器统计网站在线人数

    原理:每当有一个访问连接到服务器时,服务器就会创建一个session来管理会话。那么我们就可以通过统计session的数量来获得当前在线人数。

    事件监听机制:

    • 事件:一件事情
    • 事件源:事件发生的地方
    • 监听器:一个对象
    • 注册监听:将事件、事件源、监听器绑定在一起。当事件源上发生某个事件后,执行监听器代码

    监听器实现

    要实现监听器,我们首先需要实现ServletContextListener接口,该接口没有定义好的实现类,需要我们自己去定义。

    ServletContextListener方法

    • void contextDestroyed(ServletContextEvent sce):ServletContext对象被销毁之前会调用该方法
    • void contextInitialized(ServletContextEvent sce):ServletContext对象创建后会调用该方法

    使用

    1. 配置web.xml

       <context-param>
              <param-name>configLocation</param-name>
              <param-value>/WEB-INF/config.xml</param-value>
          </context-param>
      
    2. 代码

      package Listener;
      
      import javax.servlet.ServletContext;
      import javax.servlet.ServletContextEvent;
      import javax.servlet.ServletContextListener;
      import javax.servlet.annotation.WebListener;
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      
      @WebListener
      public class Demo01 implements ServletContextListener {
          @Override
          public void contextInitialized(ServletContextEvent servletContextEvent){
              ServletContext servletContext = servletContextEvent.getServletContext();
              String contextConfig = servletContext.getInitParameter("configLocation"); //获取configLocation参数
              String realPath = servletContext.getRealPath(contextConfig);//获取路径
              try {
                  FileInputStream fis = new FileInputStream(realPath);//读取文件
                  System.out.println(fis);
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              }
          }
      
          @Override
          public void contextDestroyed(ServletContextEvent servletContextEvent){
              System.out.println("listener被销毁了");
          }
      }
      

  • 相关阅读:
    梦断代码阅读笔记
    程序员的自我修养阅读笔记
    11月总结3
    11月总结3
    程序员的自我修养阅读笔记
    程序员的自我修养阅读笔记
    程序员的自我修养阅读笔记
    程序员的自我修养阅读笔记
    第十四周总结
    第十三周总结
  • 原文地址:https://www.cnblogs.com/Xiaoming0/p/14147535.html
Copyright © 2011-2022 走看看