一、概述
过滤器可以拦截请求,并控制响应,对此,servlet一无所知。与servlet非常类似,过滤器就是java组件,它主要用于对用户请求(HttpServletRequest)进行预处理,也可以对服务器响应(HttpServletResponse)进行后处理,是个典型的处理链。请求发送到servlet之前,可以用过滤器截获并处理请求,另外,servlet结束工作之后,在响应发回给客户端之前,可以用过滤器处理响应。
过滤器可以链接在一起,一个接一个的运行,过滤器并不关心他前面运行了哪些过滤器,也不关系他后边还会运行哪个过滤器。过滤器的运行顺序由web.xml部署文件控制。
二、过滤器的生命周期
过滤器必须实现Filter接口中的三个方法:
void init(FilterConfig var1) throws ServletException; void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException; void destroy();
1. init()方法:
容器决定实例化一个过滤器时,在init()方法中完成调用过滤器之前的所有初始化任务。例如,保存一个FilterConfig对象的一个引用。
2. doFilter()方法:
每次容器认为应该对当前请求应用过滤器时,就会调用doFilter()方法,doFilter()方法中做过滤器具体的工作。
3. destroy()方法:
容器决定删除一个过滤器实例时,会调用destroy()方法,可以在该方法中做实例被撤销之前的一些清理工作。
三、FilterChain
前文中提到过,过滤器可以链接在一起,共同完成一些事情,达到这一目的主要依靠FilterChain。我们知道,过滤器并不知道请求所涉及到的其他过滤器,那么如何保证过滤器链接的顺序性呢?通过FilterChain可以,FilterChain知道过滤器执行的顺序。
过滤器的调用顺序可以以栈上的方法进行理解,如下图所示:
四、示例
以下是一个过滤器的示例,该过滤器的作用是设置请求即响应的编码格式,解决中文字符集乱码的问题。
<!-- 声明过滤器 -->
<filter>
<filter-name>Encoding</filter-name>
<filter-class>com.wyf.filter.EncodingFilter</filter-class>
<init-param>
<param-name>ENCODING</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<!-- 过滤器映射 -->
<filter-mapping>
<filter-name>Encoding</filter-name>
<url-pattern>/*</url-pattern> <!-- url-pattern 元素定义了哪些web应用资源要使用该过滤器 --> <!-- /*是对所有的文件进行拦截 -->
</filter-mapping>
public class EncodingFilter implements Filter {
private String encoding = "UTF-8"; // 默认编码UTF-8
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 如果用户配置了编码,则将encoding设置为用户编码
if(filterConfig.getInitParameter("ENCODING")!=null){
encoding = filterConfig.getInitParameter("ENCODING");
}
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 设置请求与响应的编码
servletRequest.setCharacterEncoding(encoding);
servletResponse.setCharacterEncoding(encoding);
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
encoding = null;
}
}