一、用途
对web的请求或响应进行拦截并做一些业务逻辑判断和处理。
例如:可以使用过滤器拦截一个request来做一些预处理,然后再交给下一个过滤器或servlet进一步处理(也可以对返回的response进行拦截过滤)。
应用场景:
1.身份验证
2.记录和审核
3.图像转换
4.数据压缩
5.加密
6....
二、工作原理
流程图
过滤器是随着web应用的启动而启动的,只会初始化一次,之后便可以拦截过滤相关的请求或响应,当web应用停止或重新部署的时候才会被销毁。
下面我们通过代码示例来学习如何使用它。
三、上代码
Filter接口源码:
package javax.servlet;
import java.io.IOException;
public interface Filter {
public default void init(FilterConfig filterConfig) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException;
public default void destroy() {}
}
可以看到,在Filter接口中定义了一个doFilter方法,该方法正是过滤器执行过滤动作的方法;
每个过滤器都有权访问filterConfig对象,并从中获取初始化参数;
当我们编写好Filter的实现类,并在web应用程序的部署描述符「web.xml」中配置好需要拦截过滤的web资源后,web服务器就会在调用web资源的service方法之前先调用这个doFilter方法 。
此时你就可以针对需要拦截过滤的web资源(Request、Response)进行业务逻辑判断和处理,从而简化操作。
例如:统一设置字符编码、判断用户是否已经登陆、判断有没有权限访问页面等...
Filter的开发主要分为2步:
1.编写java类,实现Filter接口及其方法
package com.ys.test;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.util.Enumeration;
@WebFilter(filterName = "TestFilter")
public class TestFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
System.out.println("TestFilter初始化...");
Enumeration paramNames = config.getInitParameterNames();
while (paramNames.hasMoreElements()) {
String paramName = paramNames.nextElement();
String paramValue = config.getInitParameter(paramName);
System.out.println(paramName + "=" + paramValue);
}
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
chain.doFilter(req, resp);
System.out.println("TestFilter被执行...");
// 针对req和resp统一设置字符编码
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
// 放行,顺着过滤链继续往下走,若下一个目标仍是Filter,则执行该Filter的doFilter方法
// 若下一个目标是Servlet,则调用Servlet的service方法
chain.doFilter(req, resp);
}
public void destroy() {
System.out.println("TestFilter被销毁!");
}
}
2.配置需要拦截过滤的web资源
在web.xml 文件中使用和元素对编写的Filter实现类进行注册,并设置它所能拦截的web资源
统一字符编码过滤器
characterEncodingFilter
com.ys.test.TestFilter
初始化参数1
encoding1
GBK
初始化参数2
encoding2
UTF-8
characterEncodingFilter
*.do
REQUEST
FORWARD
INCLUDE
ERROR
ASYNC
也可以直接在Filter的实现类中使用@WebFilter注解来注册
@WebFilter(filterName = "TestFilter",
// 配置初始化参数
initParams = {@WebInitParam(name = "encoding1", value = "GBK"), @WebInitParam(name = "encoding2", value = "UTF-8")},
// 配置要拦截的资源
urlPatterns = "*.do",
// 配置拦截的类型
dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ERROR, DispatcherType.ASYNC})
public class TestFilter implements Filter {
...
四、拦截方式配置
拦截方式配置也就是指定过滤器的调度模式,主要有下面几种:
REQUEST
默认值,浏览器直接请求资源。
FORWARD
转发访问资源:RequestDispatcher.forward();
如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用。
INCLUDE
包含访问资源:RequestDispatcher.include();
如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。
ERROR
错误跳转资源:被声明式异常处理机制调用的时候;
如果目标资源是通过声明式异常处理机制调用时,那么过滤器被将被调用。
ASYNC(Servlet3.0新增加)
支持异步处理