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

  • 相关阅读:
    回调函数
    TFS(Team Foundation Server)介绍和入门
    android widget 开发实例 : 桌面便签程序的实现具体解释和源代码 (上)
    非常多人不愿意承认汉澳sinox已经超过windows
    vim: 自己定义颜色主题(colorscheme)
    银行家算法
    一道百度架构题
    select poll使用
    LDAPserver的安装
    在eclipse中启动tomcat时报错:could not create java virtual machine... a fatal error...
  • 原文地址:https://www.cnblogs.com/dousil/p/12895334.html
Copyright © 2011-2022 走看看