zoukankan      html  css  js  c++  java
  • Servlet过滤器

    一、Filter的介绍及使用

    什么是过滤器?

    与Servlet相似,过滤器是一些web应用程序组件,可以绑定到一个web应用程序中。但是与其他web应用程序组件不同的是,过滤器是"链"在容器的处理过程中的。这就意味着它们会在servlet处理器之前访问一个进入的请求,并且在外发响应信息返回到客户前访问这些响应信息。这种访问使得过滤器可以检查并修改请求和响应的内容。

    过滤器适用于那些地方?

    l  为一个web应用程序的新功能建立模型(可被添加到web应用程序中或者从web应用程序中删除而不需要重写基层应用程序代码);

    l  向过去的代码添加新功能。

    过滤器放在容器结构的什么位置?

    过滤器放在web资源之前,可以在请求抵达它所应用的web资源(可以是一个Servlet、一个Jsp页面,甚至是一个HTML页面)之前截获进入的请求,并且在它返回到客户之前截获输出请求。Filter:用来拦截请求,处于客户端与被请求资源之间,目的是重用代码。Filter链,在web.xml中哪个先配置,哪个就先调用。在filter中也可以配置一些初始化参数。

    Java中的Filter 并不是一个标准的Servlet ,它不能处理用户请求,也不能对客户端生成响应。 主要用于对HttpServletRequest 进行预处理,也可以对HttpServletResponse 进行后处理,是个典型的处理链。 

    Filter 有如下几个用处:

    l  在HttpServletRequest 到达Servlet 之前,拦截客户的HttpServletRequest 。 

    l  根据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据。 

    l  在HttpServletResponse 到达客户端之前,拦截HttpServletResponse 。 

    l  根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据。

    Filter 有如下几个种类:

    l  用户授权的Filter: Filter 负责检查用户请求,根据请求过滤用户非法请求。 

    l  日志Filter: 详细记录某些特殊的用户请求。 

    l  负责解码的Filter: 包括对非标准编码的请求解码。 

    l  能改变XML 内容的XSLTFilter 等。 

    一个Filter 可负责拦截多个请求或响应:一个请求或响应也可被多个请求拦截。 

    创建一个Filter 只需两个步骤: 
    (1)创建Filter 处理类: 

    (2)在web.xml 文件中配置Filter 。 
    创建Filter 必须实现javax.servlet.Filter 接口,在该接口中定义了三个方法。 
    • void init(FilterConfig config): 用于完成Filter 的初始化。 
    • void destroy(): 用于Filter 销毁前,完成某些资源的回收。 
    • void doFilter(ServletRequest request, ServletResponse response,FilterChain chain): 实现过滤功能,该方法就是对每个请求及响应增加的额外处理。 

    过滤器Filter也具有生命周期:init()->doFilter()->destroy(),由部署文件中的filter元素驱动。在servlet2.4中,过滤器同样可以用于请求分派器,但须在web.xml中声明,<dispatcher>INCLUDE或FORWARD或REQUEST或ERROR</dispatcher>该元素位于filter-mapping中。 

    Filter常用的场景:

    一个实例

    首先来看一下web.xml的配置:

       

     <!-- 请求url日志记录过滤器 -->    
    
        <filter>    
            <filter-name>logfilter</filter-name>    
            <filter-class>com.weijia.filterservlet.LogFilter</filter-class>    
        </filter>    
        <filter-mapping>    
            <filter-name>logfilter</filter-name>    
            <url-pattern>/*</url-pattern>    
        </filter-mapping>  
          
    <!-- 编码过滤器 -->    
        <filter>    
            <filter-name>setCharacterEncoding</filter-name>    
            <filter-class>com.weijia.filterservlet.EncodingFilter</filter-class>    
            <init-param>    
                <param-name>encoding</param-name>    
                <param-value>utf-8</param-value>    
            </init-param>    
        </filter>    
        <filter-mapping>    
            <filter-name>setCharacterEncoding</filter-name>    
            <url-pattern>/*</url-pattern>    
        </filter-mapping>    

    然后看一下编码过滤器:

    package com.weijia.filterservlet;  
      
    import java.io.IOException;  
    import java.util.Enumeration;  
    import java.util.HashMap;  
      
    import javax.servlet.Filter;  
    import javax.servlet.FilterChain;  
    import javax.servlet.FilterConfig;  
    import javax.servlet.ServletException;  
    import javax.servlet.ServletRequest;  
    import javax.servlet.ServletResponse;  
      
    public class EncodingFilter implements Filter {    
        private String encoding;    
        private HashMap<String,String> params = new HashMap<String,String>();    
        // 项目结束时就已经进行销毁    
        public void destroy() {    
            System.out.println("end do the encoding filter!");    
            params=null;    
            encoding=null;    
        }    
        public void doFilter(ServletRequest req, ServletResponse resp,FilterChain chain) throws IOException, ServletException {    
            System.out.println("before encoding " + encoding + " filter!");    
            req.setCharacterEncoding(encoding);    
            chain.doFilter(req, resp);          
            System.out.println("after encoding " + encoding + " filter!");    
            System.err.println("----------------------------------------");    
        }    
         
        // 项目启动时就已经进行读取    
        public void init(FilterConfig config) throws ServletException {    
            System.out.println("begin do the encoding filter!");    
            encoding = config.getInitParameter("encoding");    
            for (Enumeration<?> e = config.getInitParameterNames(); e.hasMoreElements();) {    
                String name = (String) e.nextElement();    
                String value = config.getInitParameter(name);    
                params.put(name, value);    
            }    
        }    
     }    


    日志过滤器:

    package com.weijia.filterservlet;  
      
    import java.io.IOException;  
      
    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 LogFilter implements Filter {    
          
        public FilterConfig config;    
         
        public void destroy() {    
            this.config = null;    
            System.out.println("end do the logging filter!");  
        }    
         
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {    
            System.out.println("before the log filter!");    
            // 将请求转换成HttpServletRequest 请求    
            HttpServletRequest hreq = (HttpServletRequest) req;    
            // 记录日志    
            System.out.println("Log Filter已经截获到用户的请求的地址:"+hreq.getServletPath() );    
            try {    
                // Filter 只是链式处理,请求依然转发到目的地址。    
                chain.doFilter(req, res);    
            } catch (Exception e) {    
                e.printStackTrace();    
            }    
            System.out.println("after the log filter!");    
        }    
         
        public void init(FilterConfig config) throws ServletException {    
            System.out.println("begin do the log filter!");    
            this.config = config;    
        }    
         
     }    


    测试Servlet:

    package com.weijia.filterservlet;  
      
    import java.io.IOException;  
      
    import javax.servlet.ServletException;  
    import javax.servlet.http.HttpServlet;  
    import javax.servlet.http.HttpServletRequest;  
    import javax.servlet.http.HttpServletResponse;  
      
    public class FilterServlet extends HttpServlet {  
      
        private static final long serialVersionUID = 1L;  
      
        public void doGet(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
            response.setDateHeader("expires", -1);  
        }  
      
        public void doPost(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
        }  
      
    }  

    访问FilterServlet

    运行结果:

    before the log filter!
    Log Filter已经截获到用户的请求的地址:/FilterServlet
    before encoding utf-8 filter!
    after encoding utf-8 filter!
    ----------------------------------------
    after the log filter!


    我们从运行结果可以看到这个过滤器的调用关系:

    类似于C++中的构造函数和析构函数的调用顺序,

    这里我们在web.xml中注册的是先注册日志过滤器的,然后再注册

    当我们重新部署应用的时候发现:

    会先销毁上次的过滤器,然后再重新注册一下

  • 相关阅读:
    Debate
    图形算法
    OpenGL Notes
    How to Write an Ethics Paper
    Thesis
    addWindowListener -> WindowAdapter -> windowClosing
    Thesis
    Bootcamp: An error occurred while partitioning the disk
    What Is XML Schema
    What Is XML
  • 原文地址:https://www.cnblogs.com/ChrisMurphy/p/5202770.html
Copyright © 2011-2022 走看看