过滤器

转载:http://www.cnblogs.com/5ishare/p/6557079.html

一、由来

客户端发起请求,那服务器不能什么请求都做出响应,做拦截处理,不仅能减轻服务器的压力,还能保护数据的安全,同样服务端做出响应给客户端时有时也需要进行过滤,比如我们常见的图片添加水印。为了处理这些问题,于是过滤器出现了。有时不仅仅对请求与响应进行一层的过滤,可能会过滤多层,所以提出了滤镜链(FilterChain)的概念.

二、使用

在使用它之前先熟悉下它的作用的地方。过滤器作用在请求Request到达Servlet之前以及响应Response到达浏览器之前会依次经过过虑链。有些类似asp.net中的httpmodule.使用Filter主要是实现javax.servlet.filter接口。查看API可看到有3个方法。

1.public void init(FilterConfig filterConfig) throws ServletException

由 Web 容器调用,指示将放入服务中的过滤器。servlet 容器只在实例化过滤器之后调用一次 init 方法。在要求过滤器做任何过滤工作之前,init 方法必须成功完成。如果 init 方法抛出 ServletException或没有在 Web 容器定义的时间段内返回,则 Web 容器无法将过滤器放入服务中。这个和Servlet的生命周期有点类似,也是只初始化一次,destroy()也是执行一次。

2.public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException

每次由于对链末尾的某个资源的客户端请求而通过链传递请求/响应对时,容器都会调用 Filter 的 doFilter 方法。传入此方法的 FilterChain 允许 Filter 将请求和响应传递到链中的下一个实体。
此方法的典型实现遵循以下模式:
1. 检查请求
2. 有选择地将带有自定义实现的请求对象包装到用于输入过滤的过滤器内容或头中 
3. 有选择地将带有自定义实现的响应对象包装到用于输出过滤的过滤器内容或头中 
4. a) 既可以使用 FilterChain 对象 (chain.doFilter()) 调用链中的下一个实体, 
4. b) 也可以不将请求/响应对传递给过滤器链中的下一个实体,从而阻塞请求处理
5. 在调用过滤器链中的下一个实体之后直接设置响应上的头。

3.public void destroy()

由 Web 容器调用,指示将从服务中取出的过滤器。此方法仅在过滤器的 doFilter 方法中的所有线程都已退出之后调用一次,或者在过了超时期之后调用。在调用此方法之后,Web 容器不会再对此过滤器实例调用 doFilter 方法。此方法为过滤器提供了一个清除持有的所有资源(比如内存、文件句柄和线程)的机会,并确保任何持久状态都与内存中该过滤器的当前状态保持同步。

原文地址:https://www.cnblogs.com/fengli9998/p/6557688.html