Filter,FilterChain,FilterConfig
实例:
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的更多相关文章
- [原创]java WEB学习笔记44:Filter 简介,模型,创建,工作原理,相关API,过滤器的部署及映射的方式,Demo
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- Servlet - Listener、Filter、Decorator
Servlet 标签 : Java与Web Listener-监听器 Listener为在Java Web中进行事件驱动编程提供了一整套事件类和监听器接口.Listener监听的事件源分为Servle ...
- 干货,一文带你超详细了解 Filter 的原理及应用
提出问题 1.我们在访问后台很多页面时都需要登录,只有登录的用户才能查看这些页面,我们需要 在每次请求的时候都检查用户是否登陆,这样做很麻烦,有没有一种方法可以在我们请求之 前就帮我们做这些事 ...
- Servlet 过滤器Filter
特点 1)Filter是依赖于Servlet容器,属于Servlet规范的一部分,在Servlet API中定义了三个接口类:Filter, FilterChain, FilterConfig. 2) ...
- 认识Filter
1). Filter 是什么 ? ①. JavaWEB 的一个重要组件, 可以对发送到 Servlet 的请求进行拦截, 并对响应也进行拦截. ②. Filter 是实现了 Filter 接口的 Ja ...
- Filter(过滤器)(有待补充)
Filter(过滤器) 一.Filter(过滤器)简介 Filter 的基本功能是对 Servlet 容器调用 Servlet 的过程进行拦截,从而在 Servlet 进行响应处理的前后实现一些特殊的 ...
- JavaWeb(八):Filter和Listener
一.Filter 1.1 概述 Filter 的基本功能是对 Servlet 容器调用 Servlet 的过程进行拦截,从而在 Servlet 进行响应处理的前后实现一些特殊的功能.在 Servlet ...
- Servlet之过滤器
Servlet的介绍: Servlet API 中定义了三个接口类来开供开发人员编写 Filter 程序:Filter, FilterChain, FilterConfig Filter 程序是一个实 ...
- LogFilter
(一)Filter 在Java EE中,Filter是一个可以将请求和响应的头部或内容进行转换的一个对象.包括 (1)认证Filter (2)日志和审核Filter (3)图片转换Filt ...
随机推荐
- 为什么 asnyc await 可以提高web程序的吞吐量
(转网上一段话) Web程序天生就是多线程的,且web线程都是跑的线程池线程(使用线程池线程是为了避免不断创建.销毁线程所造成的资源成本浪费),而线程池线程可使用线程数量是一定的,尽管可以设置,但它还 ...
- Web Api 利用 cors 实现跨域
一.安装 cors 二.修改 Web.config <appSettings> <add key="cors:allowedMethods" value=&quo ...
- Mysql数据库主从配置
一.为什么要使用数据库主从架构 一个网站损耗资源最厉害的就是数据库,最易崩溃的也是数据库,而数据库崩溃带来的后果是非常严重的.数据库分为读和写操作,在实际的应用中,读操作的损耗远比写操作多太多,因此读 ...
- php最新版本配置mysqli
从官网上下载php后(我下的是php7.2.3版本),本想做个mysql的连接,但是无论怎么配置mysqli扩展,发现mysqli都没法用. 从百度上搜的那些方法都没法用,发现都是一些在php.ini ...
- less初学手记
less语言学习手记 工具下载 在less学习中,我们都会需要随时编译我们的less文件,查看生成的css样式表是否正确,以及是否符合我们的要求.推荐一款编译软件供大家下载使用:koala,本软件支持 ...
- 广度优先(bfs)和深度优先搜索(dfs)的应用实例
广度优先搜索应用举例:计算网络跳数 图结构在解决许多网络相关的问题时直到了重要的作用. 比如,用来确定在互联网中从一个结点到另一个结点(一个网络到其他网络的网关)的最佳路径.一种建模方法是采用无向图, ...
- 最新的Windows环境搭建zeroMQ并使用java代码运行zeromq详细教程
最近项目要用zeromq,linux上很好配置使用,但是windows上配置与使用没有找到合适的解决方案,看的很头疼,这里自己总结下供大家参考 准备工作: 1.libzmq下载地址:https://g ...
- CodeForces 912d fishes(优先队列+期望)
While Grisha was celebrating New Year with Ded Moroz, Misha gifted Sasha a small rectangular pond of ...
- SQL Server 查询性能优化——创建索引原则(二)
三:索引的建立原则 一般来说,建立索引要看数据使用的场景,换句话来说哪些访问数据的SQL语句是常用的,而这些语句是否因为缺少索引(也有可能是索引过多)变的效率低下.但绝不是所有的SQL语句都要建立索引 ...
- No mapping found for HTTP request with URI [/user/login.do] in DispatcherServlet with name 'dispatcher'错误
1.警告的相关信息 七月 24, 2017 3:53:04 下午 org.springframework.web.servlet.DispatcherServlet noHandlerFound警告: ...