过滤器
过滤器
过滤器基本概念
- 过滤器(Filter) 是一种用于在请求到达目标资源(如 Servlet、JSP)之前或响应返回客户端之前执行某些操作的组件。
- Tomcat 作为 Java Web 服务器,完全支持 Servlet 规范中的过滤器机制。过滤器通常用于实现以下功能:
- 日志记录:记录请求和响应的详细信息。
- 权限验证:检查用户是否有权限访问某些资源。
- 数据压缩:对响应数据进行压缩。
- 字符编码转换:统一请求和响应的字符编码。
- 跨域处理:设置跨域请求头
过滤器工作原理
- 过滤器是基于 责任链模式 实现的。多个过滤器可以形成一个链,请求和响应会依次经过这些过滤器,最后到达目标资源。
- 过滤器的工作流程如下:
- 客户端发送请求。
- 请求经过过滤器链:
- 每个过滤器可以对请求进行处理(如修改请求头、验证权限等)。
- 请求到达目标资源(如 Servlet 或 JSP)。
- 响应经过过滤器链:
- 每个过滤器可以对响应进行处理(如修改响应头、压缩数据等)。
- 响应返回客户端。
过滤器核心接口
- 过滤器是通过实现
javax.servlet.Filter接口来创建的。 - 该接口定义了以下三个方法
void init(FilterConfig filterConfig)- 作用:初始化过滤器。
- 参数:
filterConfig:提供过滤器的配置信息。
- 调用时机:在 Web 应用启动时调用。
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)- 作用:执行过滤逻辑。
- 参数:
request:客户端请求对象。response:服务器响应对象。chain:过滤器链,用于调用下一个过滤器或目标资源。
- 调用时机:每次请求经过过滤器时调用。
void destroy()- 作用:销毁过滤器。
- 调用时机:在 Web 应用关闭时调用。
过滤器的配置
使用 web.xml 配置
-
在
web.xml中定义过滤器和过滤器映射: -
<filter> <filter-name>MyFilter</filter-name> <filter-class>com.example.MyFilter</filter-class> <init-param> <param-name>param1</param-name> <param-value>value1</param-value> </init-param> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/*</url-pattern> <servlet-name>demo01</servlet-name> </filter-mapping>-
<url-pattern>:指定过滤器应用的 URL 模式。 -
<servlet-name>:指定过滤器应用的 Servlet 名称。-
<servlet> <servlet-name>MyServlet</servlet-name> <servlet-class>com.example.MyServlet</servlet-class> </servlet> -
@WebServlet(name = "MyServlet", urlPatterns = {"/my-servlet"}) public class MyServlet extends HttpServlet { // Servlet 的实现代码 }
-
-
可以对应多个URL模式或者Servlet名称
-
使用注解配置
-
在过滤器类上使用
@WebFilter注解: -
@WebFilter( filterName = "MyFilter", urlPatterns = "/*", initParams = { @WebInitParam(name = "param1", value = "value1") } ) public class MyFilter implements Filter { // 过滤器实现 }
过滤器的示例代码
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")
public class LoggingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化逻辑
System.out.println("LoggingFilter initialized.");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
long startTime = System.currentTimeMillis();
// 记录请求 URL
String requestUrl = ((HttpServletRequest) request).getRequestURL().toString();
System.out.println("Request URL: " + requestUrl);
// 调用下一个过滤器或目标资源
chain.doFilter(request, response);
// 记录处理时间
long endTime = System.currentTimeMillis();
System.out.println("Request processed in " + (endTime - startTime) + " ms");
}
@Override
public void destroy() {
// 销毁逻辑
System.out.println("LoggingFilter destroyed.");
}
}
过滤器的常见应用场景
-
权限验证
- 在过滤器中检查用户是否已登录或具有访问权限。
- 如果未通过验证,可以重定向到登录页面或返回错误响应。
-
字符编码转换
-
在过滤器中统一设置请求和响应的字符编码。
-
request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8");
-
-
数据压缩
-
在过滤器中压缩响应数据,减少网络传输量。
-
response.setHeader("Content-Encoding", "gzip");
-
-
跨域处理
-
在过滤器中设置跨域请求头,支持跨域请求。
-
response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); response.setHeader("Access-Control-Allow-Headers", "Content-Type");
-
过滤器执行顺序
- 在
web.xml中,过滤器的执行顺序由<filter-mapping>标签的声明顺序决定。- 先声明的过滤器先执行。
- 如果使用
@WebFilter注解配置过滤器,执行顺序由过滤器的类名(按字母顺序)决定。- 不是通过
@WebFilter注解中的filterName属性来决定的 - 类名按字母顺序排列,靠前的过滤器先执行。
- 不是通过
- 混合配置的顺序
- 如果同时使用
web.xml和@WebFilter注解配置过滤器,web.xml中配置的过滤器优先执行。 web.xml中的过滤器 > 注解配置的过滤器。
- 如果同时使用
过滤器的生命周期
- 过滤器是单例的,即 Web 容器只会为每个过滤器类创建一个实例
- 这意味着过滤器的
doFilter方法可能会被多个线程同时调用,因此必须确保doFilter方法是线程安全的 - Web 容器通过反射机制调用过滤器的默认构造方法创建实例
- 创建实例后,Web 容器会调用
init方法完成初始化 - 生命周期如下
- 实例化:
- Web 容器调用过滤器的构造方法创建实例。
- 这是过滤器的第一个生命周期阶段。
- 初始化(Initialization):
- 过滤器在 Web 应用启动时或第一次被请求时初始化。
- 初始化阶段会调用过滤器的
init方法。
- 执行(Execution):
- 每次请求经过过滤器时,都会调用过滤器的
doFilter方法。 - 过滤器可以对请求和响应进行处理,并决定是否将请求传递给下一个过滤器或目标资源。
- 每次请求经过过滤器时,都会调用过滤器的
- 销毁(Destruction):
- 过滤器在 Web 应用关闭时或过滤器被移除时销毁。
- 销毁阶段会调用过滤器的
destroy方法。
- 实例化:

浙公网安备 33010602011771号