从使用上看Servlet分为简单Servlet,过滤Servlet(过滤器)和监听Servlet(监听器),这里重点介绍过滤器。
基本概念:
Filter是Servlet2.3之后增加的新功能,当需要限制用户访问某些资源或者在处理请求时,提前处理某些资源时,可使用过滤器。
过滤器是以一种组件的形式绑定到Web应用程序中的,支持热插拔。
过滤器采用链的方式处理
过滤器实现:
1.实现Filter接口
直接让类实现javax.servlet.Filter接口,就定义了一个Filter,该接口定义了3个操作方法;
public void init(FilterConfig filterConfig) throws ServletException {
//过滤器初始化时调用,通过FilterConfig取得配置的初始化参数。 参数在Web.xml中配置<inti-param>
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
<span style="white-space:pre"> </span>//完成具体过滤操作,通过FilterChain,链式传递下去;
}
public void destroy() { //销毁时使用
}
doFilter方法为核心方法,参数中的FilterChain接口,可以将请求向下继续传递给其他过滤器或者Servlet;
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
<span style="white-space:pre"> </span>//请求向下继续传递
}
2.配置Web.xml文件
1.配置Filter映射的类,<filter-class>
2.配置Filter初始化参数;<init-param>
3.配置过滤器的过滤位置;<url-pattern>
(1)扩展匹配 *.jsp
(2)路径前缀匹配,包含一个目录和一个/*
(3)全部匹配 /*
<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对那些文件起作用;这里设置对Jsp页面起作用; -->
<filter-mapping>
<filter-name>CharsetEncodingFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
3.调用过程
过滤器初始化时,初始化方法在容器中自动加载,通过FilterConfig的getInitParameter()方法读取配置的初始化参数,只初始化一次.
doFilter方法会在请求和响应时分别调用。调用两次;
应用:
filter可用来进行字符编码的过滤,检测用户是否登陆的过滤,禁止页面缓存等。
Filter是以一种组件的形式,横切入请求中的,支持热插拔,不会对代码产生影响;
Filter加入前
Filter加入后
为了解决中文乱码问题,在所有的请求中都加入了对于字符集的设置。这样会造成大量重复的代码,这里用Servlet中的过滤器Filter统一设置字符集,将编码格式的设置放入到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;
/**
* 采用Filter统一处理字符集
* @author fxq
*
*/
public class CharsetEncodingFilter implements Filter {
private String encoding;
public void init(FilterConfig filterConfig) throws ServletException {
this.encoding=filterConfig.getInitParameter("encoding");
System.out.println("CharsetEncodingFilter.init()-->>encoding="+encoding);
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("CharsetEncodingFilter---->>>begin");
//设置字符集
request.setCharacterEncoding("GB18030");
//继续往下执行,并返回来;
chain.doFilter(request, response);
System.out.println("CharsetEncodingFilter---->>>end");
}
public void destroy() {
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<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对那些文件起作用;这里设置对Jsp页面起作用; -->
<filter-mapping>
<filter-name>CharsetEncodingFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
</web-app>
通过Web.xml中配置,Filter只对所有的Jsp起作用,当向Jsp发送请求时,会先通过过滤器执行init和doFilter方法,设置字符集,进行统一配置;
总结
Filter在请求前,先进行处理,并决定是否继续往下链式传递,帮助我们解决类似字符统一的共享问题,减少代码重复。在使用的过程中应该考虑过滤和性能问题,把需要通过过滤的请求,做的详细而不是让所有的都执行过滤器。