Filter基础

一、概要

  简单的说,Filter的作用就是拦截Tomcat的service(Request,Response)方法,拿到Request、Response对象进行处理,然后释放控制,继续自动流转。其运用的还是“分层”的思想。

  至于为什么要加入这一层,为什么要对Request、Response对象进行拦截,个人感觉根本原因是为了对多个服务器资源(Servlet、JSP等)的请求、相应进行一些公共的设置,这里强调的是“多个”。如果是一个资源,就没有设置Filter的必要,因为只需要在这个资源需要的地方(之前)设置Request、Response即可,也就是“设置”放到哪里都可以,因为很多请求、响应有很多共同的设置,所以将共同之处抽出来作为一层,就是所谓的Filter。作用如下图:

传统调用:

加上Filter:

二、FilterChain

  当几个Servlet有一些相同的设置(过滤),而另几个Servlet有其它相同的设置……,这样一个Filter是不能完成所有的过滤,所以就需要多个Filter协作来共同完成这项任务。于是著名的FilterChain就出来了。那么这个FilterChain中的多个Filter是如何协作的呢?

  每个Filter的职能不同,当一个Servlet的请求到达后,这个请求就会沿着这条Filter链,一个一个走过,走到它需要的Filter时,这个Filter就会进行对它的Request、Response进行操作,完毕后自动向下流转。这就是所谓的职责链模式。

  每个Filter有3个方法:

  ?  init(FilterConfig filterConfig)

  ?  doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

  ?  destroy()

  三个方法(下面进行详细介绍)依次执行,一个Filter链中的多个Filter的执行顺序如下图:

  

  即:执行第一个过滤器的chain.doFilter()之前的代码---->第二个过滤器的chain.doFilter()之前的代码---->……---->第n个过滤器的chain.doFilter()之前的代码---->所请求servlet的service()方法中的代码——>所请求servlet的doGet()或doPost()方法中的代码---->第n个过滤器的chain.doFilter()之后的代码---->……---->第二个过滤器的chain.doFilter()之后的代码---->第一个过滤器的chain.doFilter()之后的代码。

三、主要接口与方法

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

  ?  所有的过滤器都必须实现Filter接口。该接口定义了init(),doFilter(),destory()三个方法。

  ?  FilterChain接口作为了doFilter0方法的参数:  doFilter(ServletRequest request, ServletResponse response,FilterChain chain)

  ?  FilterConfig接口作为了init()方法的参数: init(FilterConfig filterConfig)

  也就是,过滤器类将实现Filter接口,然后使用这个过滤器类中的FilterChain和FilterConfig接口。该过滤器类的—个引用将传递给FilterChain对象,以允许过滤器把控制权传递给链中的下一个资源。FilterConfig对象将由容器提供给过滤器,以允许访问该过滤器的初始化数据。下面对3个接口与所包含的方法进行简要介绍:

Filter接口

  1)       public void init (FilterConfig filterConfig) throws  ServletException.

  当开始使用servlet过滤器服务时,Web容器调用此方法一次,为服务准备过滤器;即通过FilterConfig对象拿到过滤器的初始化参数,即配置文件中配置的信息。然后在需要使用过滤器的时候调用doFilter(),并传递配置信息。

  2)       public voiddoFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException

  每个过滤器都接受当前的请求和响应,且FilterChain过滤器链中的过滤器(应该都是符合条件的)都会被执行。doFilter方法中,过滤器可以对请求和响应做它想做的一切,通过调用他们的方法收集数据,或者给对象添加新的行为。

  过滤器通过传送至此方法的FilterChain参数,调用chain.doFilter()将控制权传送给下一个过滤器。当这个调用返回后,过滤器可以在它的 Filter方法的最后对响应做些其他的工作。如果过滤器想要终止请求的处理或得到对响应的完全控制,则可以不调用下一个过滤器,而将其重定向至其它一些页面。当链中的最后一个过滤器调用chain.doFilter()方法时,将运行最初请求的Servlet。

  3)       public voiddestroy()

  如果doFilter()法里的所有线程退出或已超时,容器调用此方法。服务器调用destory()以指出过滤器已结束服务,用于释

放过滤器占用的资源。

FilterChain接口

  1)     public voiddoFilter(ServletRequest request,ServletResponse response)   throws
java.io.IOException,ServletException

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

FilterConfig接口

 FilterConfig接口检索过滤器名、初始化参数以及活动的Servlet上下文。

  1)       public java.lang.StringgetFilterNam()

  2)       public  ServletContext  getServletContex()

  3)       public java.lang.String  getlnitParameter(java.lang.String name)

  4)       public java.util.EnumerationgetlnitParameterNames()

四、配置使用

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

<filter>,主要包括:

  1)       <filter-name>和<f‘flter-class>两个必须的子元素

  2)       <icon>、<init-param>,<display-name>,<description>这4个可选的子元素。

  <filter-name>子元素定义了—个过滤器的名字,<filter-class>指定了由容器载入的实际类,<init-param>子元素为过滤器提供初始化参数。

<filter-mapping>主要由

  1)       <filter-name>,<servlet-name>和<url-pattem>子元素组成。

<servlet-name>将过滤器映射到一个或多个Servlet上,<url-pattem>将过滤器映射到—个或多个任意特征的URL的JSP页面。

<url-pattem>的4种配置方式:

  

  <filter>
  	<filter-name>CharsetEncodingFilter</filter-name>
  	<filter-class>com.bjpowernode.drp.util.filter.CharsetEncodingFilter</filter-class>
  	<init-param>
  		<param-name>encoding</param-name>
  		<param-value>GBK</param-value>
  	</init-param>
  </filter>

  <!--精确匹配,不采用任何修饰符 -->
   <filter-mapping>
  	<filter-name>CharsetEncodingFilter</filter-name>
  	<url-pattern>/servlet/TestServlet</url-pattern>
  </filter-mapping>

  <!--扩展匹配,由*号和扩展名组成 -->
  <filter-mapping>
  	<filter-name>CharsetEncodingFilter</filter-name>
  	<url-pattern>*.jsp</url-pattern>
  </filter-mapping>

  <!--路径前缀匹配,包含一个目录和一个/* -->
  <filter-mapping>
  	<filter-name>CharsetEncodingFilter</filter-name>
  	<url-pattern>/servlet/*</url-pattern>
  </filter-mapping>

  <!--全匹配,使用/* -->
  <filter-mapping>
  	<filter-name>CharsetEncodingFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>

五、代码示例:

Filter类:

package com.bjpowernode.drp.util.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.omg.CORBA.Request;
/**
 * 采用Filter同意处理字符集
 * @author v-wangzhip
 */
public class CharsetEncodingFilter implements Filter {
	private String encoding;
	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		//System.out.println("CharsetEncodingFilter---->begin");
		//设置字符集
		request.setCharacterEncoding(encoding);
		//继续向下执行
		chain.doFilter(request, response);
		//System.out.println("CharsetEncodingFilter---->end");
	}
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		this.encoding=filterConfig.getInitParameter("encoding");
		System.out.println("encoding---->"+ encoding);
	}
}

Web.xml配置:

  <filter>
  	<filter-name>CharsetEncodingFilter</filter-name>
  	<filter-class>com.bjpowernode.drp.util.filter.CharsetEncodingFilter</filter-class>
  	<init-param>
  		<param-name>encoding</param-name>
  		<param-value>GBK</param-value>
  	</init-param>
  </filter>
  <filter-mapping>
  	<filter-name>CharsetEncodingFilter</filter-name>
  	<url-pattern>*.jsp</url-pattern>
  </filter-mapping>
    <filter-mapping>
  	<filter-name>CharsetEncodingFilter</filter-name>
  	<url-pattern>/servlet/*</url-pattern>
  </filter-mapping>

六、总结

  个人感觉,Filter是将多个请求-响应中公共的需要设置的东西提出来插入到请求-响应之间的一个中间层。多个Filter组成一个FilterChain,每个Filter有自己的职能,能按照一定规则来处理到达的请求和响应,体现了职责链模式。Filter只对post请求起作用,它提供了一种声明式服务,具有可插拔能力,即可以随意开启和关闭。

时间: 2024-08-24 00:43:05

Filter基础的相关文章

Filter编程:(1)Filter基础

Filter简介 从功能角度来说,Filter能做什么? 从API角度来说,如何实现Filter? 从原理角度来说,Filter是如何实现拦截的? Filter生命周期和Filter链 Filter生命周期的三个方法:init.doFilter和destory Filter链及其调用顺序 Filter高级开发 HttpServletRequestWrapper HttpServletResponseWrapper 动态代理 Filter映射 Filter案例 1.Filter简介 1.1.从功能

重新学javaweb---过滤器 Filter基础知识

Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter.通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如下所示: web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对象,它也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法,调用该方法,则web

DirectShow Filter 基础与简单的示例程序

DirectShow 是一个 Windows 平台上的流媒体框架,提供了高质量的多媒体流采集和回放功能. Filter 实质是一个 COM 组件,所以学习开发 Filter 前你应该对 COM 相关知识有点了解.COM 组件的实质是实现了纯虚指针接口的 C++ 对象. 应用程序开发者只需要基本的 COM 组件知识:实例化COM组件.调用接口.管理接口的引用计数.Filter 开发者则需要更多. 选择一个基类,声明自己的类. 应该清楚这个 Filter 在整个 Filter Graph 的位置,这

java web filter 基础

本文主要对Filter的使用进行讲解. 1.Filter是什么? Filter 技术是servlet 2.3 新增加的功能.Filter翻译过来的意思就是过滤器,能对客户端的消息进行预处理,然后将请求转发给其它的web组件,可以对ServletHttpRequest和ServletHttpResponse进行修改和检查.例如:在Filter中可以检查用户是否登录,对未登录的用户跳转到登陆界面. 2.过滤器快速入门 要定义一个过滤器,则需要实现javax.servlet.Filter接口,一个过滤

JAVA–利用Filter和session防止页面重复提交

JAVA–利用Filter和session防止页面重复提交解决思路:1 用户访问表单页面,先经过过滤器,过滤器设置一个随机id作为token令牌, 并将该token放入表单隐藏域中.2 表单响应到浏览器,用户填充数据后提交请求;3 请求经过过滤器,过滤器获取表单中的令牌进行验证,如果和之前生成的令牌一致,则将请求放行,并且清空令牌;4 如果用户重复提交表单,请求经过过滤器,过滤器进行验证.因为第一次放行后令牌已经清空失效,令牌不一致,不放行.跳转到提醒界面. 需用知识:1 过滤器基础知识2 se

Maven 工程从一个properties 用属性占位符引用另一个properties的内容

1.pom xml 配置 <!--filter--> <build> <filters> <filter>src/main/resource/test.properties</filter><!--基础文件--> </filters> <resources> <resource> <directory>src/main/resource</directory><!--需

化茧成蝶,开源NetWorkSocket通讯组件

前言 前后历时三年,期间大量参考.Net Framework和Asp.net MVC源代码,写写删删再重构,组件如今更新到V1.5.x了.从原来的丑小鸭,变成今天拥有稳定和强大的tcp协议支持基础层,原生支持http.websocket.flash策略服务,以及内置可快速构建tcp通讯的fast协议,最重要的是可基于此组件,很方便开发自己定义的某种tcp上层协议服务器和客户端.如果有人以支持的功能多为荣,我却以支持的扩展性强为傲,从WebForm到MVC的 时候,被其可依赖注入.可Filter过

java web 开发三剑客 -------电子书

Internet,人们通常称为因特网,是当今世界上覆盖面最大和应用最广泛的网络.根据英语构词法,Internet是Inter + net,Inter-作为前缀在英语中表示“在一起,交互”,由此可知Internet的目的是让各个net交互.所以,Internet实质上是将世界上各个国家.各个网络运营商的多个网络相互连接构成的一个全球范围内的统一网,使各个网络之间能够相互到达.各个国家和运营商构建网络采用的底层技术和实现可能各不相同,但只要采用统一的上层协议(TCP/IP)就可以通过Internet

2017最新传智播客黑马java 32期全套培训资料

HTML&CSSJavaScriptJQuery基础与实战BootStrap响应式页面开发mysql&jdbc回顾mysql多表&jdbcjdbc连接池&dbutilxmlHttp&TomcatJavaWeb核心技术JDBC加强AJAX&JqueryListenerFilter基础加强LinuxredisJavaWeb综合项目实战hibernatestrutsspringssh综合项目实战oraclemaven实战物流BOS系统mybatis基础mybati