过滤器Filter,是从Servlet2.3开始新增的一个功能。也是一个由Servlet容器管理的对象,结构和Servlet相类似。
其功能是在源数据与目的数据之间起过滤功能的组件
其主要应用是:权限控制、日志记录、图像转换、数据压缩等。
特点:
1.Servlet过滤器本身并不生成请求和响应对象,只是提供过滤功能。
2.Servlet过滤器能够在Servlet被调用之前检查Request对象,并修改Request Header和Request内容;
3.在Servlet被调用之后检查Response对象,修改Response Header和Response的内容。
4.Servlet过滤器可以过滤的Web组件包括Servlet,JSP和HTML等文件。
5.Filter类似于IO中的过滤流,实现也类似于Servlet。
一个简单的Servlet Filter的结构如下:
public class FilterOne implements Filter {
public FilterOne(){
System.out.println("======= FilterOne 构造函数 =======");
}
/**
* servlet启动时会执行此方法
* 与Servlet的init方法有区别:
* servlet的init方法是在servlet第一次被执行的时候启动的
* 过滤器的init方法是在容器启动的时候就执行了
* @param config
* @throws ServletException
*/
public void init(FilterConfig config) throws ServletException {
System.out.println("======= FilterOne 初始化方法 =======");
//返回以param参数命名的初始化参数的值,返回字符串类型的参数,如果参数不存在则返回空
String initParam=config.getInitParameter("param");
System.out.println("param== "+initParam);
}
/**
* 具体的业务逻辑执行方
* @param req
* @param resp
* @param chain
* @throws ServletException
* @throws IOException
*/
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("======= 开始执行FilterOne的doFilter方法 =======");
chain.doFilter(req, resp);
System.out.println("======= 结束执行FilterOne的doFilter方法 =======");
}
/**
* 销毁过滤器,此方法基本不会使用
*/
public void destroy() {
System.out.println("======= FilterOne销毁方法 =======");
}
}
其中包括init、doFilter、destroy三个方法。
init方法:初始化方法,会在Servlet容器启动时执行
doFilter方法:过滤器业务处理代码执行方法,用于配置具体的过滤器规则
destroy方法:过滤器的销毁方法,基本不会使用
接下来还得在web.xml文件中配置Filter
其中init-param标签可以用来储存一些默认的属性信息,
可以在Filter中通过getInitParameter方法来读取。
<!--过滤器filter配置信息-->
<filter>
<filter-name>FilterOne</filter-name>
<filter-class>com.icarus.filter.FilterOne</filter-class>
<init-param>
<param-name>param</param-name>
<param-value>wangxin</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>FilterOne</filter-name>
<!--设置需要过滤的url-->
<url-pattern>/*</url-pattern>
</filter-mapping>
Servlet过滤器链介绍:
过滤器链中过滤器的执行顺序是按照部署描述符中的顺序执行的。
过滤器链体现了一种职责链模式
责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。职责链模式能够解决发送者与接收者之间的耦合关系
对于过滤器而言,请求传递给具体的web资源之前都会经过具体的过滤器的处理,
在web资源处理完该请求之后,返回响应给客户端之前也会给过滤器处理一遍。
接下来我们在项目中使用下过滤器,
项目要求:让用户可以使用中文账号来登录系统。
首先我们知道中文和英文的编码格式是不一样的,当我们使用英文的编码表去解码中文时会出现乱码的情况。
这时我们就得使用UTF-8编码表来解码中文就可以将中文输出出来了。
所以我们得使用过滤器来指定UTF-8编码方法来解码从客户端获取到的表单数据。
过滤器配置代码:
public class EncodingFilter implements Filter {
//保存当前应用的字符集名称
private String charEncoding=null;
public void init(FilterConfig config) throws ServletException {
//获取配置好的编码格式
charEncoding=config.getInitParameter("encoding");
//未设置编码信息则抛出异常
if (charEncoding==null){
throw new ServletException("EncodingFilter中的编码信息设置为空!!!");
}
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//如果当前默认的编码值与请求中的编码值不一致,
//则将请求中的编码设置为默认的编码
if (!charEncoding.equals(req.getCharacterEncoding())){
req.setCharacterEncoding(charEncoding);
}
//将响应信息的编码格式也设置为默认格式
resp.setCharacterEncoding(charEncoding);
chain.doFilter(req,resp);
}
public void destroy() {
}
}
在web.xml中配置Filter信息,保存默认编码格式
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>com.icarus.filter.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<!--设置需要过滤的url-->
<url-pattern>/*</url-pattern>
</filter-mapping>