`
javababy1
  • 浏览: 1173918 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

过滤器

 
阅读更多

Filter过滤器

Filter简介

作用:可以被jsp或servlet,静态图片文件或静态html文件等进行拦截,从而实现一些特殊的功能。

Filter技术使用户改变一个request,和修改一个response。

javax.servlet
Interface Filter

Method Summary
void destroy()
Called by the web container to indicate to a filter that it is being taken out of service.
void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)
The doFilter method of the Filter is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain.
void init(FilterConfig filterConfig)
Called by the web container to indicate to a filter that it is being placed into service.

在有多个过滤器的时候,他们的过滤顺序由他们在web.html中的注册顺序有关。

过滤器基础知识

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

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被调用之后截获。

可以捕获servlet运行的结果,比如进行数据压缩等

以上特点可以通过简单案例演示,是学生对Filter有一个初步认识。

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

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

编写一个简单的过滤器对*.jsp文件过滤,演示

chain.doFilter(request,response)

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,于是我们就可以统一地认为我们每次访问的都是一个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()之后的代码。

过滤器的生命周期

过滤器的生命周期:(一定要实现javax.servlet包的Filter接口的三个方法init()、doFilter()、destroy(),空实现也行)
(1)、启动服务器时加载过滤器的实例,并调用init()方法来初始化实例;
(2)、每一次请求时都只调用方法doFilter()进行处理;
(3)、停止服务器时调用destroy()方法,销毁实例。

案例:在三个方法中编写打印语句,然后启动、关闭服务器演示生命周期。

Servlet过滤器API

Servlet过滤器API包含了3个接口,它们都在javax.servlet包中,分别是Filter接口、FilterChain接口和FilterConfig接口。

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)publicvoid destroy()
一旦doFilterO方法里的所有线程退出或已超时,容器调用此方法。服务器调用destoryO以指出过滤器已结束服务,用于释放过滤器占用的资源。

2 public interface FilterChain

public voiddoFilter(ServletRequest request,ServletResponse response)

thlows java.io.IOException,ServletException

此方法是由Servlet容器提供给开发者的,用于对资源请求过滤链的依次调用,通过FilterChain调用过滤链中的下一个过滤 器,如果是最后一个过滤器,则下一个就调用目标资源。

3 public interface FilterConfig

FilterConfig接口检索过滤器名、初始化参数以及活动的Servlet上下文。该接口提供了以下4个方法:

(1)public java.1ang.String getFilterName0
返回web.xml部署文件中定义的该过滤器的名称。
(2)public ServletContext getServletContextO
返回调用者所处的servlet上下文。
(3)public java.1ang.StringgetlnitParameter(java.1ang.String name)
返回过滤器初始化参数值的字符串形式,当参数不存在时,返回nul1.name是初始化参数名。
(4)public java.util.EnumerationgetlnitParameterNames()
以Enumeration形式返回过滤器所有初始化参数值,如果没有初始化参数,返回为空。

过滤器相关接口工作流程

从编程的角度看,过滤器类将实现Filter接口,然后使用这个过滤器类中的FilterChain和FilterConfig接口。该过滤器类的

— 个引用将传递给FilterChain对象,以允许过滤器把控制权传递给链中的下一个资源。FilterConfig对象将由容器提供给过滤
器,以允许访问该过滤器的初始化数据。详细流程如下图所示:

过滤器配置

过滤器通过Web应用程序中的配置描述符web.xml文件中的明,包括部分:

过滤器定义,由<filter>元素表示,主要包括<filter-name>和<filter-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页面。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics