一、概述

  Servlet 过滤器是小型的 Web 组件,它们拦截请求和响应,以便查看、提取或以某种方式操作正在客户机和服务器之间交换的数据。这些组件通过一个配置文件来声明,并动态地处理,当在web.xml注册了一个Filter来对某个Servlet程序进行拦截处理时,它可以决定是否将请求继续传递给Servlet程序,以及对请求和响应消息是否进行修改。

  典型的例子包括记录关于请求和响应的数据、处理安全协议、管理会话属性,例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

  

filter不过滤 java filter过滤servlet_Web

二、Filter工作原理

  过滤器(Filter)的api包括3个接口,嵌套在javax.servlet中:Filter、FilterChain、FilterConfig。

  过滤器类实现Filter接口,然后使用这个类中的FilterChain、FilterConfig接口;FilterConfig对象将由容器提供给过滤器,以允许访问该过滤器的初始化数据;该过滤器类的一个引用将传递给FilterChain 对象,以允许过滤器把控制权传递给链中的下一个资源。

  Filter接口定义了3个方法:init()、doFilter()、destroy()

  • init() :这个方法在容器实例化过滤器时被调用,它主要设计用于使过滤器为处理做准备。该方法接受一个 FilterConfig 类型的对象作为输入。
  • doFilter() :与 servlet 拥有一个 service() 方法(这个方法又调用 doPost() 或者 doGet() )来处理请求一样,过滤器拥有单个用于处理请求和响应的方法  ―― doFilter() 。这个方法接受三个输入参数:一个 ServletRequest 、 response 和一个 FilterChain 对象。
  • destroy() :这个方法执行任何清理操作,这些操作可能需要在自动垃圾收集之前进行。

  

1 package com.yx.servlet.filter;
 3 
 4 import java.io.IOException;
 5 import javax.servlet.Filter;
 6 import javax.servlet.FilterChain;
 7 import javax.servlet.FilterConfig;
 8 import javax.servlet.ServletException;
 9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.annotation.WebFilter;
12 
13 /**
14  * Servlet Filter implementation class ServletFilterTest_01
15  */
16 @WebFilter("/ServletFilterTest_01")
17 public class ServletFilterTest_01 implements Filter {
18     private String encoding;
19     /**
20      * Default constructor.                                      
21      * 
22      */
23     public ServletFilterTest_01() {
24         // TODO Auto-generated constructor stub
25     }
26     
27     /**
28      * @see Filter#destroy()
29      */
30     public void destroy() {
31         // TODO Auto-generated method stub
32     }
33     
34     /**
35      * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
36      */
37     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
38         //只能解决POST请求参数乱码问题        
39         request.setCharacterEncoding(encoding);        
40         //指定输出编码(最后带上,后面会有说明)        
41         response.setCharacterEncoding(encoding);        
42         //指定输出流编码及客户端应使用的码表        
43         response.setContentType("text/html;charset="+encoding);
44 
45         //把请求传回过滤链
46         chain.doFilter(request, response);
47     }
48 
49     /**
50      * @see Filter#init(FilterConfig)
51      */
52     public void init(FilterConfig fConfig) throws ServletException {
53         //得到过滤器的初始化配置信息
54         encoding = fConfig.getInitParameter("encoding");
55         if(encoding==null){
56             encoding = "utf-8";
57         }
58     }
59 
60 }

  在web.xmlll中对过滤器进行配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<filter>
    <filter-name>ServletFilterTest_01</filter-name>
    <filter-class>com.yx.servlet.filter.ServletFilterTest_01</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>

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

</web-app>

三、过滤器链

  

filter不过滤 java filter过滤servlet_xml_02

  运行次序依次是:代码1,代码3,代码5,(Servelt、web资源..),代码6,代码4,代码2。

  web.xml 中的 filter-mapping 元素的顺序决定了 Web 容器应用过滤器到 Servlet 的顺序。若要反转过滤器的顺序,只需要在 web.xml 文件中反转 filter-mapping 元素即可。

  

filter不过滤 java filter过滤servlet_java_03

资源的访问请求路径和Servlet名称。

(1)指定资源的访问路径:

    * 完全路径匹配 :以 / 开始的。如 /aa , /bb , /aa/bb...

    * 目录匹配 :以 / 开始的,以 * 结束。如 /*, /aa/* ,/aa/bb/*

    * 扩展名匹配:不能以 / 开始的。 如 *.jsp  ,*.do , *.action

  注:“/*.action” 的写法是错误的,因为它既属于路径映射,又属于扩展名映射,导致容器无法判断。

  (2)指定Servlet的名称

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

 

参考文档:

(1)https://www.ibm.com/developerworks/cn/java/j-pj2ee10/index.html

(2)http://www.runoob.com/servlet/servlet-writing-filters.html

(3)《深入体验Java Web开发内幕--高级特性》