实例:

package com.zillion.app.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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger; import com.util.AppConfig;
import com.util.SpringContextUtil;
import com.util.ThreadlocalUtil;
/**
* loginToken拦截处理器
*
*/
public class LoginTokenFilter implements Filter{ private static final Logger log = Logger.getLogger(LoginTokenFilter.class); @Override
public void destroy() {
// TODO Auto-generated method stub } @Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
try{ HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
boolean isOptions = StringUtils.equals("OPTIONS", request.getMethod());
ThreadlocalUtil.setIsOptions(isOptions);
ThreadlocalUtil.setNewVersion(false);
//跨域设置
AppConfig appConfig = (AppConfig) SpringContextUtil.getBean("appConfig");
if(StringUtils.equals("1", appConfig.getCrossDomainFlag())){
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
response.setHeader("Access-Control-Allow-Headers", "Content-Type,Authorization,Accept,X-Requested-With,POWERED-BY-MENGXIANHUI,logintoken,userID");
}
chain.doFilter(request, res);
} catch (Exception e){
log.error("LoginTokenFilter is error!",e);
throw e;
}
} @Override
public void init(FilterConfig arg0) throws ServletException { } }
  <!-- loginToken : http-header中的转换到request参数中 -->
<filter>
<filter-name>loginTokenFilter</filter-name>
<filter-class>com.zillion.app.filter.LoginTokenFilter</filter-class>
</filter> <filter-mapping>
<filter-name>loginTokenFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

一、Filter的基本工作原理

1、Filter程序是一个实现了特殊接口的Java类,与Servlet类似,也是由Servlet容器进行调用和执行的。

2、当在web.xml注册了一个Filter来对某个Servlet程序进行拦截处理时,它可以决定是否将请求继续传递给Servlet程序,以及对请求和响应消息是否进行修改。

3、当Servlet容器开始调用某个Servlet程序时,如果发现已经注册了一个Filter程序来对该Servlet进行拦截,那么容器不再直接调用Servlet的service方法,而是调用Filter的doFilter方法,再由doFilter方法决定是否去激活service方法。

4、但在Filter.doFilter方法中不能直接调用Servlet的service方法,而是调用FilterChain.doFilter方法来激活目标Servlet的service方法,FilterChain对象时通过Filter.doFilter方法的参数传递进来的。

5、只要在Filter.doFilter方法中调用FilterChain.doFilter方法的语句前后增加某些程序代码,这样就可以在Servlet进行响应前后实现某些特殊功能。

6、如果在Filter.doFilter方法中没有调用FilterChain.doFilter方法,则目标Servlet的service方法不会被执行,这样通过Filter就可以阻止某些非法的访问请求。

二、Filter链

1、在一个Web应用程序中可以注册多个Filter程序,每个Filter程序都可以对一个或一组Servlet程序进行拦截。如果有多个Filter程序都可以对某个Servlet程序的访问过程进行拦截,当针对该Servlet的访问请求到达时,Web容器将把这多个Filter程序组合成一个Filter链(也叫过滤器链)。

2、Filter链中的各个Filter的拦截顺序与它们在web.xml文件中的映射顺序一致,上一个Filter.doFilter方法中调用FilterChain.doFilter方法将激活下一个Filter的doFilter方法,最后一个Filter.doFilter方法中调用的FilterChain.doFilter方法将激活目标Servlet的service方法。

3、只要Filter链中任意一个Filter没有调用FilterChain.doFilter方法,则目标Servlet的service方法都不会被执行。

三、Filter接口

一个Filter程序就是一个Java类,这个类必须实现Filter接口。javax.servlet.Filter接口中定义了三个方法:init、doFilter、destory。

1、init方法

(1)、在Web应用程序启动时,Web服务器(Web容器)将根据其web.xml文件的配置信息来创建每个注册的Filter的实例对象,并将其保存在内存中。

(2)、Web容器创建Filter的实例对象后,将立即调用该Filter对象的init方法。init方法在Filter生命周期中仅被执行一次,Web容器在调用init方法时,会传递一个包含Filter的配置和运行环境信息的FilterConfig对象。

(3)开发人员可以在init方法中完成与构造方法类似的初始化功能,要注意的是:如果初始化代码要使用到FilterConfig对象,这些代码只能在init方法中编写,而不能在构造方法中编写(尚未调用init方法,即并没有创建FilterConfig对象,要使用它则必然出错)。

2、doFilter方法

当一个Filter对象能够拦截访问请求时,Servlet容器将调用Filter对象的doFilter方法。

其中,参数request和response为Web容器或Filter链中上一个Filter传递过来的请求和响应对象;参数chain为代表当前Filter链的对象

3、destroy方法

该方法在Web容器卸载Filter对象之前被调用,也仅执行一次。可以完成与init方法相反的功能,释放被该Filter对象打开的资源,例如:关闭数据库连接和IO流。

四、FilterChain接口

该接口用于定义一个Filter链的对象应该对外提供的方法,这个接口只定义了一个doFilter方法。

FilterChain接口的doFilter方法用于通知Web容器把请求交给Filter链中的下一个Filter去处理,如果当前调用此方法的Filter对象是Filter链中的最后一个Filter,那么将把请求交给目标Servlet程序去处理。

五、FilterConfig接口

1、与普通的Servlet程序一样,Filter程序也很可能需要访问Servlet容器。Servlet规范将代表ServletContext对象和Filter的配置参数信息都封装到一个称为FilterConfig的对象中。

2、FilterConfig接口则用于定义FilterConfig对象应该对外提供的方法,以便在Filter程序中可以调用这些方法来获取ServletContext对象,以及获取在web.xml文件中为Filter设置的友好名称和初始化参数。

3、FilterConfig接口定义的各个方法:

  • getFilterName方法,返回<filter-name>元素的设置值。

  • getServletContext方法,返回FilterConfig对象中所包装的ServletContext对象的引用。

  • getInitParameter方法,用于返回在web.xml文件中为Filter所设置的某个名称的初始化的参数值。

  • getInitParameterNames方法,返回一个Enumeration集合对象。

六、Filter的注册与映射

1、注册Filter

一个<filter>元素用于注册一个Filter。其中,<filter-name>元素是必需的,<filter-class>元素也是必需的,<init-param>元素是可选的,可以有多个<init-param>元素。

2、映射Filter

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

第一种:指定资源的访问路径

<url-pattern>元素中的访问路径的设置方式遵循Servlet的URL映射规范。http://my.oschina.net/u/1171518/blog/220147。eg:

/*:表示拦截所有的访问请求

/filter/*:表示拦截filter目录下的所有访问请求,如:http://localhost:8888/testFilter_001/filter/xxxxxx

/test.html:表示拦截根目录下以test.html为资源名的访问请求,访问链接只会是:http://localhost:8888/test.html

第二种:指定Servlet的名称

(1)、<servlet-name>元素与<url-pattern>元素是二选一的关系,其值是某个Servlet在web.xml文件中的注册名称。

(2)、<dispatcher>元素的设置值有4种:REQUEST、INCLUDE、FORWARD、ERROR,分别对应Servlet容器调用资源的4种方式:

  • 通过正常的访问请求调用;

  • 通过RequestDispatcher.include方法调用;

  • 通过RequestDispatcher.forward方法调用;

  • 作为错误响应资源调用。

如果没有设置<dispatcher>子元素,则等效于REQUEST的情况。也可以设置多个<dispatcher>子元素,用于指定Filter对资源的多种调用方式都进行拦截。

七、Filter程序示例

1、

FitstFilter.java

web.xml

test.html(位于WebContent路径的filter目录中)

访问:http://localhost:8888/testFilter_001/filter/test.html

浏览器显示页面:

Tomcat后台(第一次访问):

2、

把FirstFilter.java中如下语句的注释去掉:(整个过程,并未特意或无意改变了test.html文件的内容)

等Tomcat Reload完成,刷新页面,惊奇地发现浏览器页面并未发生改变,Tomcat后天多了三个请求头:

原因(存在疑问,是否真的是If-Modified-Since标签来决定是否采用缓存):

(1)、缓存里存储的不只是网页文件,还有服务器发过来的该文件的最后服务器修改时间;

(2)、客户端发HTTP请求时,使用If-Modified-Since标签,把上次服务器告诉它的文件最后修改时间返回到服务器端了;

(3)、服务器会把这个时间与服务器上实际文件的最后修改时间进行比较;

(4)、如果时间一致,那么返回HTTP状态码304,尽管FirstFilter程序在拦截处理中向ServletResponse对象中写入的数据也传送给了浏览器。但是浏览器因为收到304则显示原来缓存的内容;

(5)、如果时间不一致,就返回HTTP状态码200,浏览器接到之后,会丢弃旧文件,把新文件缓存起来,并显示到浏览器中。

解决:

在test.html文件中增加一个空格又删去这个空格,造成text.html文件被修改过的假象,然后在浏览器刷新test.html页面的访问。

Filter,FilterChain,FilterConfig的更多相关文章

  1. [原创]java WEB学习笔记44:Filter 简介,模型,创建,工作原理,相关API,过滤器的部署及映射的方式,Demo

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  2. Servlet - Listener、Filter、Decorator

    Servlet 标签 : Java与Web Listener-监听器 Listener为在Java Web中进行事件驱动编程提供了一整套事件类和监听器接口.Listener监听的事件源分为Servle ...

  3. 干货,一文带你超详细了解 Filter 的原理及应用

    提出问题 1.我们在访问后台很多页面时都需要登录,只有登录的用户才能查看这些页面,我们需要   在每次请求的时候都检查用户是否登陆,这样做很麻烦,有没有一种方法可以在我们请求之   前就帮我们做这些事 ...

  4. Servlet 过滤器Filter

    特点 1)Filter是依赖于Servlet容器,属于Servlet规范的一部分,在Servlet API中定义了三个接口类:Filter, FilterChain, FilterConfig. 2) ...

  5. 认识Filter

    1). Filter 是什么 ? ①. JavaWEB 的一个重要组件, 可以对发送到 Servlet 的请求进行拦截, 并对响应也进行拦截. ②. Filter 是实现了 Filter 接口的 Ja ...

  6. Filter(过滤器)(有待补充)

    Filter(过滤器) 一.Filter(过滤器)简介 Filter 的基本功能是对 Servlet 容器调用 Servlet 的过程进行拦截,从而在 Servlet 进行响应处理的前后实现一些特殊的 ...

  7. JavaWeb(八):Filter和Listener

    一.Filter 1.1 概述 Filter 的基本功能是对 Servlet 容器调用 Servlet 的过程进行拦截,从而在 Servlet 进行响应处理的前后实现一些特殊的功能.在 Servlet ...

  8. Servlet之过滤器

    Servlet的介绍: Servlet API 中定义了三个接口类来开供开发人员编写 Filter 程序:Filter, FilterChain, FilterConfig Filter 程序是一个实 ...

  9. LogFilter

    (一)Filter 在Java EE中,Filter是一个可以将请求和响应的头部或内容进行转换的一个对象.包括 (1)认证Filter    (2)日志和审核Filter    (3)图片转换Filt ...

随机推荐

  1. Python内置函数(2)——divmod

    英文文档: divmod(a, b) Take two (non complex) numbers as arguments and return a pair of numbers consisti ...

  2. 前端开发必备之Chrome开发者工具(一)

    本文介绍的 Chrome 开发者工具基于 Chrome 65版本,如果你的 Chrome 开发者工具没有下文提到的那些内容,请检查下 Chrome 的版本 简介 Chrome 开发者工具是一套内置于 ...

  3. ssh整合之二hibernate单独搭建

    1.首先我们需要去拷贝我们的hibernate所需的jar包  这里还需要加入我们C3P0的jar包,因为我们hibernate中使用的C3P0连接池 2. 编写我们的关系映射文件Customer.c ...

  4. 最新IP数据库 存储优化 查询性能优化 每秒解析上千万

    高性能IP数据库格式详解 每秒解析1000多万ip  qqzeng-ip-ultimate.dat 3.0版 编码:UTF8     字节序:Little-Endian 返回规范字段(如:亚洲|中国| ...

  5. python的错误处理

    一.python的错误处理 在程序运行的过程中,如果发生了错误,可以事先约定返回一个错误代码,这样,就可以知道是否有错以及出错的原因. 在操作系统提供的调用中,返回错误码非常常见.比如打开文件的函数o ...

  6. TP-LINK | TL-WR842N设置无线转有线

    首先点击右上角的"高级设置". 点击左侧的"无线设置"栏,点击"WDS无线桥接",然后一步步设置可以使路由器连接到当前的一个无线网络. 然后 ...

  7. Java内存回收机制.md

    1.java的内存 java的内存结构分为 堆 (是gc的主要区域) 线程共享,主要是用于分配实例对象和数组 栈 线程私有,它的生命周期和线程相同,又分成 虚拟机栈和本地方法栈,只有它会报 Stack ...

  8. [LeetCode] Sentence Similarity 句子相似度

    Given two sentences words1, words2 (each represented as an array of strings), and a list of similar ...

  9. [LeetCode] Next Closest Time 下一个最近时间点

    Given a time represented in the format "HH:MM", form the next closest time by reusing the ...

  10. [LeetCode] Relative Ranks 相对排名

    Given scores of N athletes, find their relative ranks and the people with the top three highest scor ...