码迷,mamicode.com
首页 > 其他好文 > 详细

Filter in Servlet

时间:2019-04-29 22:31:21      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:选择   port   war   完成后   text   tco   param   滤波   请求   

一、什么是Filter

    过滤器(Filter)是可以转换请求或响应的标题和内容(或两者)的对象。过滤器不同于Web组件,因为过滤器本身通常不会创建响应。相反,过滤器提供的功能可以“附加”到任何类型的Web资源。因此,过滤器不应该对它作为过滤器的Web资源有任何依赖;这样,它可以由多个类型的web资源组成。

二、Filter可执行的主要任务

    过滤器可以执行的主要任务如下。

  • 查询请求并采取相应的行动。
  • 阻止请求和响应对进一步传递。

  • 修改请求头和数据。您可以通过提供自定义版本的请求来做到这一点。

  • 修改响应头和数据。您可以通过提供响应的自定义版本来做到这一点。

  • 与外部资源互动。

    过滤器的应用包括身份验证、日志记录、图像转换、数据压缩、加密、标记流、XML转换等。

    您可以将Web资源配置为按特定顺序由零、一个或多个筛选器链进行筛选。此链是在部署包含组件的Web应用程序时指定的,并在Web容器加载组件时实例化。

三、Filter如何工作

    Filter也是在web.xml中另外一个常用的配置项,可以通过<filter>和<filter-mapping>组合来使用Filter。实际上Filter 可以完成与Servlet同样的工作,甚至比Servlet 使用起来更加灵活,因为它除了提供了request和response对象外,还提供了一个FilterChain对象,这个对象可以让我们更加灵活地控制请求的流转。下面看一下与Filter相关的类结构图,如图3-1所示。

技术图片图3-1 Filter相关的类结构图

    在Tomcat容器中,FilterConfig 和FilterChain的实现类分别是ApplicationFilterConfig和ApplicationFilterChain,而Filter 的实现类由用户自定义,只要实现Filter 接口中定义的三个接口就行,这三个接口与在Servlet中的类似。只不过还有一个ApplicationFilterChain类,这个类可以将多个Filter串联起来,组成一个链,这个链与Jtty中的Handler链有异曲同工之妙。下面详细看一下Filter 类中的三个接口方法。

  • init(FilterConfig):初始化接口,在用户自定义的Filter 初始化时被调用,它与Servlet的init 方法的作用是一样的,FilterConfig 与ServletConfig也类似,除了都能取到容器的环境类ServletContext 对象之外,还能获取在<filter>下配置的<init-param>参数值。
  • doFilter ( ServletRequest, ServletResponse, FilterChain):在每个用户的请求进来时这个方法都会被调用,并在Servlet的service方法之前被调用。而FilterChain就代表当前的整个请求链,所以通过调用FilterChain.doFilter可以将请求继续传递下去。如果想拦截这个请求,可以不调用FilterChain.doFilter, 那么这个请求就直接返回了。所以Filter是一种责任链设计模式。
  • destroy:当Filter 对象被销毁时,这个方法被调用。注意,当Web容器调用这个方法之后,容器会再调用一次doFilter方法。

     Filter类的核心还是传递的FilterChain对象,这个对象保存了到最终Servlet对象的所有Filter对象,这些对象都保存ApplicationFilterChain对象的filters 数组中。在FiterChain链上每执行一个Filter 对象,数组的当前计数都会加1,直到计数等于数组的长度,当FilterChain上所有的Filter对象执行完成后,就会执行最终的Servlet。所以在Applicationitenchain对角山人持有Servlet对象的引用。图3-2是Filter对象的执行时序图。

技术图片图3-2 Filter执行时序图

    Fiter 存在的意义就好比是你要去北京,它是你的目的地,但是提供一个机制让你在去的途中可以做一些拦截工作, 如可以将你的些行李包存放在某个 “存放处”,当你返回时你可以再从这个地方取回。总之它可以在你的途中增加一些东西,或者减少些东西。

四、Programming Filters

    过滤API由FilterFilterChain,和FilterConfig中的接口。javax.servlet包裹。通过实现Filter接口。

    使用@WebFilter注释来定义Web应用程序中的筛选器。此注释是在类上指定的,并包含有关所声明的筛选器的元数据。带注释的筛选器必须指定至少一个URL模式。这是通过使用urlPatternsvalue属性。所有其他属性都是可选的,具有默认设置。使用value当注释中的唯一属性是URL模式时,请使用urlPatterns属性时,也使用其他属性。

    类注释为@WebFilter注释必须实现javax.servlet.Filter接口。

    若要向筛选器添加配置数据,请指定initParams属性的@WebFilter注释这个initParams属性包含@WebInitParam注释下面的代码段定义了一个过滤器,并指定了一个初始化参数:

import javax.servlet.Filter;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;

@WebFilter(filterName = "TimeOfDayFilter",
urlPatterns = {"/*"},
initParams = {
    @WebInitParam(name = "mood", value = "awake")})
public class TimeOfDayFilter implements Filter {
    ...

    中最重要的方法Filter接口是doFilter传递请求、响应和筛选链对象。此方法可以执行以下操作。

  • 检查请求头。

  • 如果筛选器希望修改请求头或数据,请自定义请求对象。

  • 如果筛选器希望修改响应头或数据,则自定义响应对象。

  • 调用筛选链中的下一个实体。如果当前过滤器是以目标Web组件或静态资源结尾的链中的最后一个过滤器,则下一个实体是链末尾的资源;否则,它就是WAR中配置的下一个过滤器。过滤器通过调用doFilter方法,传递被调用的请求和响应或它可能创建的包装版本。或者,过滤器可以选择通过不调用下一个实体来阻止请求。在后一种情况下,过滤器负责填充响应。

  • 在调用链中的下一个过滤器后检查响应头。

  • 抛出异常以指示处理中的错误。

    除了doFilter之外,则必须实现initdestroy方法。这个init方法由容器在实例化筛选器时调用。如果希望将初始化参数传递给筛选器,则可以从FilterConfig对象传递给init.

编写定制的请求和响应

    过滤器可以通过多种方式修改请求或响应。例如,筛选器可以向请求添加属性,也可以在响应中插入数据。

    修改响应的筛选器通常必须在将响应返回给客户端之前捕获响应。为此,您向生成响应的servlet传递一个备用流。备用流阻止servlet在完成时关闭原始响应流,并允许过滤器修改servlet的响应。

    若要将此暂存流传递给servlet,筛选器将创建一个响应包装器,该响应包装器将重写getWritergetOutputStream方法返回此暂存流。包装器被传递给doFilter过滤链的方法。包装方法默认为调用包装请求或响应对象。

    若要重写请求方法,请将请求包装在扩展ServletRequestWrapperHttpServletRequestWrapper。若要重写响应方法,请将响应包装在扩展ServletResponseWrapperHttpServletResponseWrapper.

指定过滤器映射

    Web容器使用筛选器映射来决定如何将筛选器应用到Web资源。过滤器映射通过名称或URL模式将过滤器匹配到Web组件或Web资源。过滤器是按照筛选器映射出现在WAR的筛选映射列表中的顺序调用的。您可以使用NetBeansIDE或使用XML手工编写WAR的筛选器映射列表,从而在其部署描述符中指定筛选器映射列表。

    如果要将每个请求记录到Web应用程序,则可以将点击计数器筛选器映射到URL模式/*.

    可以将筛选器映射到一个或多个Web资源,也可以将多个筛选器映射到Web资源。这在图4-1,其中过滤器F1映射到servlet S1、S2和S3;过滤器F2映射到Servlet S2;过滤器F3映射到servlet S1和S2。

 

技术图片图4-1 Filter到servlet映射

    回想一下,筛选链是传递给doFilter过滤器的方法。该链是通过滤波器映射间接形成的。链中过滤器的顺序与过滤器映射出现在Web应用程序部署描述符中的顺序相同。

    当筛选器映射到Servlet S1时,web容器将调用doFilterF1法这个doFilter方法调用该链中的前面的筛选器调用s1的筛选链中的每个过滤器的方法。chain.doFilter方法。因为S1的过滤器链包含过滤器f1和f3,所以f1调用chain.doFilter调用doFilterF3滤光片法。当F3‘sdoFilter方法完成,控件返回到f1的doFilter方法。

Filter in Servlet

标签:选择   port   war   完成后   text   tco   param   滤波   请求   

原文地址:https://www.cnblogs.com/schhz208/p/10793288.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!