zoukankan      html  css  js  c++  java
  • Filter、FilterChain、FilterConfig介绍

    感谢作者:本文内容复制于https://www.runoob.com/w3cnote/filter-filterchain-filterconfig-intro.html

    1. Filter程序是一个实现了特殊接口的Java类,与Servlet类似,也是有Servlet容器进行调用和执行的。

    2. 当web.xml注册了一个Filter来对某个Servlet进行拦截处理时,他可以决定是否将请求传递给Servlet程序,以及对请求和响应消息是否进行修改。

    3. 当Servlet 容器开始调用某个Servlet程序时,如果发现由一个Filter程序对该Servlet进行拦截。而是调用Filter的doFilter()方法,再由doFilter()方法决定是否去激活service()方法。

    4. 但是Filter.doFilter()方法不能直接调用Servlet的service()方法,而是调用FilterChain.doFilter方法来激活servlet的service()方法,FilterChain对象时通过Filter.doFilter方法的参数传递进来的。

    5. 只要在Filter.doFilter()方法中调用FilterChain.doFilter方法的语句前后增加某些程序代码,这样就可以在Servlet进行响应前后实现某些特殊的功能。

    6. 如果filter.dofilter中没有调用FilterChain.doFilter()方法,那么Servlet的service方法就不回被执行。这样通过Filter就可以阻止某些菲方的访问求情。

    二:FilterChain

    1. 在一个web应用程序中可以注册多个Filter程序,每个Filter都可以对一个或一组Servlet程序进行拦截。如果有多个Filter对某个Servlet程序进行拦截,当针对该Servlet的访问请求到达时,Web容器将把这多个Filter组合成一个FilterChian。也叫过滤器链

    2. Filter链中的各个Filter的蓝机器顺序与他们在web.xml文件中的映射顺序时一致的。上一个Filter.doFilter()方法调用FilterChain.doFilter方法将激活下一个Filter.doFilter方法。最后一个Filter.doFilter方法中调用FilterChain.doFilter方法激活Servlet中的service方法。

    3. 只要Filterchain中任意一个Filter没有调用FilterChain.doFilter方法,则目标Servlet的service方法就不回执行。

    三:Filter接口

    一个Filter程序就是一个java类,这个类必须实现Filter接口。javax.servlet.Filter接口中定义了三个方法:int,doFilter,destory.

    init方法

      在web应用程序启动时,web服务器将根据器web.xml文件的配置信息来创建每个注册的Filter的实例对象。并将其保存在内存中。

       Web容器在创建Filter对象之后,立即执行Filter对象的init方法。init方法在生命周期内仅仅被执行一次。Web容器在调用int的方法时会传递一个包含Filter配置和运行环境信息的FilterConfig对象。

      

    public voic init(FilterConfig filterConfig) throws ServletException

      开发人员可以在init方法中完成于构造方法类似的初始化功能。要注意的时如果初始化代码要使用FilterConfig对象,这些代码只能在init方法中编写,而不能在构造方法中编写。

    doFilter

      当一个Filter对象能够拦截访问请求时,Servlet容器将调用Filter容器将调用Filter对象的doFilter方法。

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException.ServletException

    destory

      该方法在web容器卸载Filter对象之前被调用,也仅执行一次。可以完成于init方法相反的功能。释放Filter对象打开的资源,例如:关闭数据库连接和IO流。

    四: FilterChain接口

      该接口用于定义一个Filter链对象应该对外提供的方法,这个接口只有一个doFilter方法

      

    public void doFilter(ServletRequest request, ServletResponse response) throws java.io.IOException.ServletException

    FilterChain接口的doFilter方法用于通知Web容器把请求交给Filter链中的下一个Filter去处理。如果当前调用此方法Filter链中的最后一个Filter,那么将把请求交给目标Servlet程序处理。

    五:FilterConfig接口

      1. 与普通的servlet程序一样,Filter程序可能需要访问Servlet容器。Servlet规范将代表ServletContext对象和Filter的配置参数信息封装到一个称之为FilterConfig的对象中。

      2. FilterConfig 接口则用于定义FilterConfig对象应该对外提供的方法。以便在Filter程序中可以调用这些方法来获取ServletContext对象,以及获取web.xml文件中Filter设置友好名称和初始化参数

      3. FilterConfig 接口定义的各个方法:

        a) getFilterName 方法,返回<filter-name>元素设置值

        b) getServletContext 方法,返回FilterConfig 对象中所封装的ServletContext引用

        c) getInitParameter方法,用于返回web.xml文件中为Filter所设置的某个名称的初始化参数值

        d) getInitParameterNames方法,返回一个Enumeration集合对象。

    六:Filter 的注册于反射

      1. 注册Filter

      一个<filter>元素用于注册一个Filter。其中<filter-name>时必须的,<filter-classes>元素也是必须的。<init-param>元素时可选的,可以有多个<init_param>元素

    <filter>
        <filter-name>FirstFilter</filter-name>
        <filter-class>FirstFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>GB2312</param-value>
        </init-param>
    </filter>

      2. 映射Filter

      <filter-mapping>元素用于设置一个Filter所负责拦截器资源。一个Filter拦截器的资源可以通过两种方式来指定:资源的访问请求路径和Servlet名称

      指定资源的访问路径

      

    <filter-mapping>
        <filter-name>FirstFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

      <url-pattern> 元素中的访问路径的设置遵循Servlet URL映射规范

        /*:表示拦截所有的访问路径

        /filter/*:表示拦截filter目录下的所有的访问请求,如:http://localhost:8888/testFilter-000/filter/xxxxxxx.

        /text.html:表示拦截根目录下以test.html为资源名的访问请求,访问链接只会是:http://localhost:8888/text.html

      2.1 指定servlet名称

    <filter-mapping>
        <filter-name>FirstFilter</filter-name>
        <servlet-name>default></servlet-name>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

        <servlet-name>元素于<url-pattern>元素是二选一的关系,其值是某个Servlet在web.xml文件中的注册名称

        <dispatcher>元素有4钟:REQUEST,INCLUDE,FORWARDERROR分别对应Servlet容器调用资源的四种方式

          正常调用

          通过RequestDispatche.include方法调用

          通过RequestDispatcher.forward方法调用

          作为错误响应资源调用

    七一个传统的Filter程序示例

    FitstFilter.java
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Enumeration;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
     
    public class FirstFilter implements Filter {
        private FilterConfig filterConfig = null;
        String paramValue = null;
     
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            this.filterConfig = filterConfig;
            paramValue = filterConfig.getInitParameter("encoding");
        }
        
        @Override
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            System.out.println("begin headers-------------------");
            Enumeration<?> headerNames = ((HttpServletRequest)request).getHeaderNames();
            
            while(headerNames.hasMoreElements()) {
                String headerName = (String)headerNames.nextElement();
                System.out.println(headerName + ": " + ((HttpServletRequest)request).getHeader(headerName));
            }
            System.out.println("end headers-------------------");
            
            //在调用目标前写入响应内容
            response.setContentType("text/html; charset=gb2312");
            PrintWriter out = response.getWriter();
            out.println("IP地址为:" + request.getRemoteHost() + "<br>");
     
            chain.doFilter(request, response);
            
            //在目标返回后写入响应内容
            out.println("<br>名称为encoding的初始化参数的值为:" + paramValue);
            out.println("<br>当前Web程序的真实路径为:" + filterConfig.getServletContext().getRealPath("/"));
            
            //out.println("<br>修改了test.html文件!");
        }
        
        @Override
        public void destroy() {
            this.filterConfig = null;
        }
    }
    <filter>
        <filter-name>FirstFilter</filter-name>
        <filter-class>FirstFilter</filter-class>
        <init-param>
        <param-name>encoding</param-name>
        <param-value>GB2312</param-value>
        </init-param>
    </filter>
        
    <filter-mapping>
        <filter-name>FirstFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    test.html(位于WebContent路径的filter目录中)
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    这就是test.html页面的原始内容!
    </body>
    </html>

    访问:http://localhost:8888/testFilter_001/filter/test.html

  • 相关阅读:
    JAVA基础——编程练习(二)
    JAVA基础——面向对象三大特性:封装、继承、多态
    JVM内存
    50. Pow(x, n) (JAVA)
    47. Permutations II (JAVA)
    46. Permutations (JAVA)
    45. Jump Game II (JAVA)
    43. Multiply Strings (JAVA)
    42. Trapping Rain Water (JAVA)
    41. First Missing Positive (JAVA)
  • 原文地址:https://www.cnblogs.com/dousil/p/12895334.html
Copyright © 2011-2022 走看看