过滤器(Filter)

2018-06-26  本文已影响49人  禅与发现的乐趣

Filter的基本功能是对Servlet容器调用Servlet的过程进行拦截,从而在Servlet进行响应处理的前后实现一些特俗功能,例如,纪录所有客户端的每次访问信息,同级静态HTML页面的访问次数,验证访问者的身份,修改Servlet容器传递给Servlet的请求信息,修改Servlet回送给Servlet容器的响应结果。

Filter的基本工作原理

Filter程序是一个实现了特殊接口(javax.servlet.Filter)的Java类,与Servlet程序相似,由Servlet容器进行调用和执行。

Filter程序需要在web.xml文件中进行注册和设置它所能拦截的资源,当Servlet容器开始调用某个Servlet程序时,如果发现已经注册了一个Filter程序来对该Servlet进行拦截,那么Servlet容器将不再直接调用Servlet的service方法,而是调用Filter的doFilter方法,再由doFilter方法决定是否去激活Servlet的service方法。在doFilter中调用FilterChain.doFilter方法来激活目标Servlet的service方法。如果没有调用,那么目标Servlet的service的方法就不会执行,在FilterChain.doFilter调用的前后增加一些处理代码,就可以实现Servlet响应前后的一些特殊处理。

Filter链

一个web程序中可以注册多个Filter程序,每个Filter程序可以对一个或一组Servlet程序进行拦截,如果有多个Filter程序对某个Servlet的程序的访问过程进行拦截,当针对该Servlet的访问请求到达时,这些拦截的FIlter程序就组成了一个Filter链,也称过滤器链。这个链的拦截顺序与他们在web.xml文件中的映射顺序一致,上一个Filter中的doFilter方法调用的FilterChain.doFilter将激活下一个Filter的doFilter方法,最后一个Filter激活目标Servlet的service方法。

Filter接口

public void init(FilterConfig filterConfig) throws ServletException;
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException;
public void destroy();

FilterConfig对应web.xml中的配置:

<filter>
    <filter-name>FirstFilter</filter-name>
    <filter-class>FirstFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>gb2312</param-value>
    </init-param>
</filter>

映射Filter

在web.xml文件中,一个<filter-mapping>元素用于设置一个Filter所负责拦截的资源。这可以通过两种方式来指定:Servlet名称和资源的访问请求路径。

Servlet容器调用一个资源的方式有以下四种:

<filter-mapping>
    <filter-name>FirstFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

<filter-mapping>
    <filter-name>FirstFilter</filter-name>
    <servlet-name>HelloServlet</servlet-name>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

<url-pattern>和<servlet-name>是二选一的,<dispatcher>的值为上面所列出的4个。

如果一个Filter链中多次出现了同一个Filter程序,这个Filter程序的拦截处理过程将被执行多次

Filter的运行过程分析

用Filter实现对资源的集中访问保护

如果一个网站的所有页面都是静态页面,但是我们又需要用户登录以查看,怎么办呢,如果是jsp页面,我们可以直接判断登录进行转发,如果是纯静态的话,我们就可以使用Filte了,在过滤器中进行登录判断和转发到登录页面的处理。

在Filter程序中修改请求和响应消息

要实现上述需求可以在doFilter中使用修饰后的request和response,使用装饰模式继承HttpServletRequestWrapperHttpServletResponseWrapper

用Filter实现文件上传请求的透明处理

我们知道,对于采用POST请求方式提交的multipart/form-data类型的HTTP请求消息,在Servlet程序中无法调用HttpServletResponse实例对象的getParameter等方法来读取表单字段元素的信息。对于这种情况可以通过一个Filter程序进行预处理,让自定义的请求对象的getParameter等方法可以反悔multipart/form-data编码类型的HTTP请求消息中的表单字段元素信息,从而让目标Servlet能够透明地使用request对象的getParameter方法。

用Filter实现响应正文的压缩

HTTP协议支持响应消息的实体内容进行压缩后再进行传递,以便减少网络传输的数据量,从而提高网络的传输效率。压缩的处理可以在Servlet程序中,当然最好是在Filter程序中。

HTTP协议中最常见的压缩方式是gzip和compress两种格式,如果浏览器程序支持对响应消息的压缩,它在请求消息中需要使用一个Accept-Encoding头字段来指明其能够解码的数据压缩格式。如果Web服务器对响应消息中的实体内容进行了压缩,它需要使用Content-Encoding头字段来指明压缩方式,浏览器将采用Content-Encoding头字段中指定的压缩方式对接收到的实体内容进行解压后显示。

上一篇 下一篇

猜你喜欢

热点阅读