Filter详解(转)

以前以为Filter只是一个特殊点的Servlet,用进只需在web.xml中配置一下拦截路径就可以了,可经过这两天的深入学习,才知道以前对Filter类的了解和使用都太过浅薄了。

在网上看了很多篇相关的技术文章,现提取它们中的精髓(我认为能说明问题的东西)及我个人的一些学习经验作如下总结,希望能帮助大家更好地理解Filter的过滤机制。

要学习Filter,就必须先理解和掌握servlet的调用机制和流程。关于servlet,网上也有很多相关文章,大家若有不明白的可以到百度中搜一下,我这里为了突出重点就不多说了。好,下面进入正题。

一、什么是Filter

Filter 技术是servlet 2.3 新增加的功能.servlet2.3是sun公司与2000年10月发布的,它的开发者包括许多个人和公司团体,充分体现了sun公司所倡导的代码开放性原则.由于众多的参与者的共同努力,servlet2.3比以往功能都强大了许多,而且性能也有了大幅提高.

  它新增加的功能包括:

  1. 应用程序生命周期事件控制;

  2. 新的国际化;

  3. 澄清了类的装载规则;

  4. 新的错误及安全属性;

  5. 不赞成使用HttpUtils 类;

  6. 各种有用的方法;

  7. 阐明并扩展了几个servlet DTD;

  8. filter功能.

  其中最重要的就是filter功能.它使用户可以改变一个request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开servlet时处理response.换种说法,filter其实是一个”servlet chaining”(servlet 链).一个filter 包括:

  1. 在servlet被调用之前截获;

  2. 在servlet被调用之前检查servlet request;

  3. 根据需要修改request头和request数据;

  4. 根据需要修改response头和response数据;

  5. 在servlet被调用之后截获.

你能够配置一个filter 到一个或多个servlet;单个servlet或servlet组能够被多个filter 使用.几个实用的filter 包括:用户辨认filter,日志filter,审核filter,加密filter,符号filter,能改变xml内容的XSLT filter等.

一个filter必须实现javax.servlet.Filter接口定义的三个方法: doFilter、init和destroy。(在三个方法在后面后有详细的介绍).

二、Filter体系结构

 2.1、Filter工作原理(执行流程)

当客户端发出Web资源的请求时,Web服务器根据应用程序配置文件设置的过滤规则进行检查,若客户请求满足过滤规则,则对客户请求/响应进行拦截,对请求头和请求数据进行检查或改动,并依次通过过滤器链,最后把请求/响应交给请求的Web资源处理。请求信息在过滤器链中可以被修改,也可以根据条件让请求不发往资源处理器,并直接向客户机发回一个响应。当资源处理器完成了对资源的处理后,响应信息将逐级逆向返回。同样在这个过程中,用户可以修改响应信息,从而完成一定的任务。

************************************************************************************************************************

在这里,我要插几句——关于过滤链的问题:上面说了,当一个请求符合某个过滤器的过滤条件时该请求就会交给这个过滤器去处理。那么当两个过滤器同时过滤一个请求时谁先谁后呢?这就涉及到了过滤链FilterChain。

所有的奥秘都在Filter的FilterChain中。服务器会按照web.xml中过滤器定义的先后循序组装成一条链,然后一次执行其中的doFilter()方法。(注:这一点Filter和Servlet是不一样的,具体请参看我的另一篇文章:Servlet和Filter映射匹配原则之异同)执行的顺序就如下图所示,执行第一个过滤器的chain.doFilter()之前的代码,第二个过滤器的chain.doFilter()之前的代码,请求的资源,第二个过滤器的chain.doFilter()之后的代码,第一个过滤器的chain.doFilter()之后的代码,最后返回响应。


        这里还有一点想补充:大家有没有想过,上面说的“执行请求的资源”究竟是怎么执行的?对于“执行第一个过滤器的chain.doFilter()之前的代码,第二个过滤器的chain.doFilter()之前的代码”这些我可以理解,无非就是按顺序执行一句句的代码,但对于这个“执行请求的资源”我刚开始却是怎么也想不明白。直到我见到上面这张图片才恍然大悟(我说过了,这篇文章中的资料都是我从网上收集来的,当我看到上面的文字时是没有图片看的)。其实是这样的:

通常我们所访问的资源是一个servlet或jsp页面,而jsp其实是一个被封装了的servlet(每个jsp执行前都会被转化为一个标准的servlet,这点若还有不明白的请自己到网上查一下吧),于是我们就可以统一地认为我们每次访问的都是一个Servlet,而每当我们访问一个servlet时,web容器都会调用该Servlet的service方法去处理请求。而在service方法又会根据请求方式的不同(Get/Post)去调用相应的doGet()或doPost()方法,实际处理请求的就是这个doGet或doPost方法。写过servlet的朋友都应该知道,我们在doGet(或doPost)方法中是通过response.getWriter()得到客户端的输出流对象,然后用此对象对客户进行响应。

到这里我们就应该理解了过滤器的执行流程了:执行第一个过滤器的chain.doFilter()之前的代码——>第二个过滤器的chain.doFilter()之前的代码——>……——>第n个过滤器的chain.doFilter()之前的代码——>所请求servlet的service()方法中的代码——>所请求servlet的doGet()或doPost()方法中的代码——>第n个过滤器的chain.doFilter()之后的代码——>……——>第二个过滤器的chain.doFilter()之后的代码——>第一个过滤器的chain.doFilter()之后的代码。

以上是我的理解,若有不对之处,还有大家不吝指教啊,大家一起学习!!

************************************************************************************************************************

2.2、 Servlet过滤器API
          Servlet过滤器API包含了3个接口,它们都在javax.servlet包中,分别是Filter接口、FilterChain接口和FilterConfig接口。
       2.2.1     public Interface Filter
                    所有的过滤器都必须实现Filter接口。该接口定义了init,doFilter0,destory()三个方法:
    (1) public void init (FilterConfig filterConfig) throws   ServletException.
          当开始使用servlet过滤器服务时,Web容器调用此方法一次,为服务准备过滤器;然后在需要使用过滤器的时候调用doFilter(),传送给此方法的FilterConfig对象,包含servlet过滤器的初始化参数。
    (2)public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)
                                              throws java.io.IOException,ServletException.

每个过滤器都接受当前的请求和响应,且FilterChain过滤器链中的过滤器(应该都是符合条件的)都会被执行。doFilter方 法中,过滤器可以对请求和响应做它想做的一切,通过调用他们的方法收集数据,或者给对象添加新的行为。过滤器通过传送至 此方法的FilterChain参数,调用chain.doFilterO将控制权传送给下一个过滤器。当这个调用返回后,过滤器可以在它的 Filter方法的最后对响应做些其他的工作。如果过滤器想要终止请求的处理或得到对响应的完全控制,则可以不调用下一个过滤 器,而将其重定向至其它一些页面。当链中的最后一个过滤器调用chain.doFilterO方法时,将运行最初请求的Servlet。
     (3)public void destroy()
        一旦doFilterO方法里的所有线程退出或已超时,容器调用
此方法。服务器调用destoryO以指出过滤器已结束服务,用于释
放过滤器占用的资源。

2.2.2 public interface FilterChain
      public void doFilter(ServletRequest request,ServletResponse response)
    thlows java.io.IOException,ServletException
      此方法是由Servlet容器提供给开发者的,用于对资源请求过滤链的依次调用,通过FilterChain调用过滤链中的下一个过滤   器,如果是最后一个过滤器,则下一个就调用目标资源。

2.2.3 public interface FilterConfig
      FilterConfig接口检索过滤器名、初始化参数以及活动的Servlet上下文。该接口提供了以下4个方法:
     (1)public java.1ang.String getFilterName0
           返回web.xml部署文件中定义的该过滤器的名称。
     (2)public ServletContext getServletContextO
          返回调用者所处的servlet上下文。
     (3)public java.1ang.String getlnitParameter(java.1ang.String name)
          返回过滤器初始化参数值的字符串形式,当参数不存在时,返回nul1.name是初始化参数名。
     (4)public java.util.Enumeration getlnitParameterNames()
          以Enumeration形式返回过滤器所有初始化参数值,如果没有初始化参数,返回为空。

 2.3、过滤器相关接口工作流程
   从编程的角度看,过滤器类将实现Filter接口,然后使用这个过滤器类中的FilterChain和FilterConfig接口。该过滤器类的
— 个引用将传递给FilterChain对象,以允许过滤器把控制权传递给链中的下一个资源。FilterConfig对象将由容器提供给过滤
器,以允许访问该过滤器的初始化数据。详细流程如下图所示:

2.4、过滤器配置
    过滤器通过Web应用程序中的配置描述符web.xml文件中的明,包括部分:过滤器定义,由<filter>
元素表示,主要包括<filter-name>和<f‘flter-class>两个必须的子元素和<icon>、<init-param>,<display-name>,<description>这4个可选的子元素。<filter-name>子元素定义了—个过滤器的名字,<filter-class>指定了由容器载入的实际类,<init-param>子元素为过滤器提供初始化参数。

<filter-mapping> 主要由<filter-name>,<servlet-name>和<url-pattem>子元素组成。<servlet-name>将过滤器映射到一个或多个Servlet上,<url-pattem>将过滤器映射到—个或多个任意特征的URL的JSP页面。

三、应用实例
          从上面分析可知,实现Servlet过滤器,需要两步:第一步开发过滤器,设计—个实现Fiker接口的类;第二步通过web.xml配置过滤器,实现过滤器和Servlet、JSP页面之间的映射。以下设计一个简单的IP地址过滤器,根据用户的IP地址进行对网站的访问控制。
(1)过滤器的设计ipfilter.java
package ipf;
imp0rt java.io.IOException;
imp0rt javax.servlet.*;
public class ipfilter implements Filter//实现Filter接口
{protected FilterConfig config;
protected String rejectedlP;
public void init(FilterConfig filterConfig)throws
ServletException
{this.config=filterConfig;//从Web)lE务器获取过滤器配置对象
rejectedlP=config.getlnitParameter( RejectedlP”):
,,从配置中取得过滤lP
if(rejectedlP=:nul1)‘rejectedlP= )
)
public void doFilter(ServletRequest request,
ServletResponse response.FilterChain chain)throws
IOException,ServletException
{RequestDispatcher dispatcher=request.getRequestDispatcher("");
String remotelP=request.getRemoteAddrO;//获取客户请求lP
int i=remotelP.1astlndexOf(".");
int r=rejectedlP.1astlndexOf(”.”):
String relPscope=rejectedlP.substring(0,r);//过滤lP段
if(relPscope.equals(remotelP.substring(O.i)))
{      dispatcher.forward(request,response);//重定向到rejectedError.jsp页面
        retum;//阻塞,直接返Web回客户端
}
else{chain.doFilter(request,response);//调用过滤链上的下一个过滤器
}
}
public void destroy()
       //过滤器功能完成后,由Web服务器调用执行,回收过滤器资源
注意:chain.doFilterO语句以前的代码用于对客户请求的处理;以后的代码用于对响应进行处理。
(2)配置过滤器
    在应用程序Web—INF目录下的web.xml描述符文件中添加以下代码:

<filter>
<filter-name>ipfIter</filter-name>//过滤器名称
<filter-class>ipf.ipfiIter</filter-class>//实现过滤器的类
<init—param>
<param—name>RejectedlP</param-name>//过滤器初始化参数名RejectedlP
<param-value>192.168.12.*/param-value>
</init—pamm>
</filter>
<filter-mapping>//过滤器映射(规律规则)
<filter-name>ipfiIter</filter-name>
<url—pattem>/*</ud-pattem>
//映射到Web应用根目录下的所有JSP文件
</filter-mapping>
通过以上设计与配置,就禁止了IP地址处在192.168.12网段的用户对网站的访问。

四、 结束语
Servlet过滤器功能强大,应用广泛,除支持Servlet和JSP页面的基本功能,比如13志记录、性能、安全、会话处理、XSLT转换等外,在J2EE应用程序中使用Java Servlet过滤器转换其输出,以便兼容任何类型客户端也表现出了很好的前景。Servlet过滤器能够侦测到来自使用WAP协议(无线应用协议)的移动客户端的呼叫,并且将答复内容转换成WML(无线标记语言)格式。Servlet过滤器也能检测到来自iMode无线客户的呼叫,并将其转变成cHTML(紧凑HTML)格式等等。因而,深刻理解Servlet过滤器的工作机制,熟练掌握编程技术,在实际的开发过程中,可以不断地发现新的用途,增强组件的可重用性,提高Web应用程序的可维护性。

时间: 2024-09-29 10:14:03

Filter详解(转)的相关文章

开启 J2EE(六)— Servlet之Filter详解及乱码处理实例

定义和功能 Filter:过滤器,它能够在request到达Servlet之前预处理request,也可以在离开Servlet时处理response,通过对request或response的处理已达到过滤功能.但是Filter只是对request和response请求进行了拦截处理,通常不产生请求或者响应. 实现的接口 我们写Servlet需要继承一个类,Filter也一样,要实现一个接口(扩展性的体现啊):javax.servlet.Filter,并实现该接口的三个方法: <span styl

布隆过滤器(Bloom Filter)详解

布隆过滤器(Bloom Filter)详解 2012-07-13 18:35 by Haippy, 29358 阅读, 6 评论, 收藏, 编辑   布隆过滤器[1](Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False positives,即Bloom Fi

java web之Filter详解

java web之Filter详解 2012-10-20 0 个评论 作者:chenshufei2 收藏 我要投稿 .概念: Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能.例如实现URL级别的权限访问控制.过滤敏感词汇.压缩响应信息等一些高级功能. 二.Filter简介 Servlet API中提供

JAVA学习篇--javaweb之Filter详解

在DRP项目中,多次提到了Filter,它解决了字符集的统一设置以及统一控制简单WebCache,从中我们可以体会到,它给我们带来的好处不仅仅是减少代码量这么简单,它的出现避免了我们每个页面重复的编写相同的代码,减少了我们的工作量,而且给维护带来了极大的便利,那么它是如何实现统一管理的呢?既然它能统一管理某些重复的操作,那么它和AOP有什么关系呢? Filter简介 ServletAPI中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过

【甘道夫】HBase(0.96以上版本)过滤器Filter详解及实例代码

说明: 本文参考官方Ref Guide,Developer API和众多博客,并结合实测代码编写,详细总结HBase的Filter功能,并附上每类Filter的相应代码实现. 本文尽量遵从Ref Guide中"9.4. Client Request Filters"的行文顺序,便于读者对比查看,但内容比官方文档更加详实. 欢迎转载,请注明来源: http://blog.csdn.net/u010967382/article/details/37653177 目录: 引言 -- 参数基础

javaweb之Filter详解

一.概念:Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能.例如实现URL级别的权限访问控制.过滤敏感词汇.压缩响应信息等一些高级功能. 二.Filter简介Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filte

[转载] 布隆过滤器(Bloom Filter)详解

转载自http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html   布隆过滤器[1](Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False positives,即Bloom Filter报告某一

JSP中filter详解以及应用实例(转载)

filter功能.它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开 servlet时处理response.换种说法,filter其实是一个”servlet chaining”(servlet 链). 一个filter 包括: 1. 在servlet被调用之前截获; 2. 在servlet被调用之前检查servlet reques

Servlet之Filter详解

Filter,过滤器,顾名思义,即是对数据等的过滤,预处理过程.为什么要引入过滤器呢?在平常访问网站的时候,有时候发一些敏感的信息,发出后显示时 就会将敏感信息用*等字符替代,这就是用过滤器对信息进行了处理.这只是一个简单的例子,当然,过滤器那么强大,它的功能也不可能局限于此,它不仅能预处 理数据,只要是发送过来的请求它都是可以预处理的,同时,它还可以对服务器返回的响应进行预处理,这样,大大减轻了服务器的压力.例如,实现URL级别的 权限访问控制.过滤敏感词汇.压缩响应信息等一些高级功能.下面来

bloom filter 详解[转]

Bloom Filter概念和原理 焦萌 2007年1月27日 Bloom Filter是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合.Bloom Filter的这种高效是有一定代价的:在判断一个元素是否属于某个集合时,有可能会把不属于这个集合的元素误认为属于这个集合(false positive).因此,Bloom Filter不适合那些“零错误”的应用场合.而在能容忍低错误率的应用场合下,Bloom Filter通过极少的错误换取了存储空