在Java Web开发中,过滤器(Filter)是一种重要的组件,用于拦截客户端的请求和响应,实现对请求和响应的预处理和后处理,通过过滤器,开发者可以统一处理诸如身份验证、日志记录、字符编码转换、数据压缩等共通功能,从而提高代码的复用性和可维护性,本文将详细介绍Java中创建过滤器的完整流程、核心配置及常见应用场景。

创建过滤器类的基本步骤
创建Java过滤器需要实现javax.servlet.Filter接口,该接口包含三个核心方法:init()、doFilter()和destroy(),以下是具体实现步骤:
-
实现Filter接口
定义一个类并实现Filter接口,import javax.servlet.*; import java.io.IOException; public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化代码,如读取配置参数 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 预处理逻辑 chain.doFilter(request, response); // 放行请求 // 后处理逻辑 } @Override public void destroy() { // 资源清理代码 } } -
重写核心方法
init():在容器创建过滤器实例后调用,用于执行初始化操作,例如读取web.xml中配置的参数。doFilter():过滤器的核心方法,负责处理请求和响应,通过chain.doFilter()决定是否将请求传递给下一个资源(如Servlet或其他过滤器)。destroy():在容器销毁过滤器实例前调用,用于释放资源,如关闭数据库连接或文件流。
配置过滤器的两种方式
过滤器创建后,需要通过配置使其生效,Java Web应用支持两种配置方式:传统XML配置和注解配置。
-
XML配置(web.xml)
在web.xml文件中添加<filter>和<filter-mapping>标签,指定过滤器名称、类名及URL映射规则:
<filter> <filter-name>MyFilter</filter-name> <filter-class>com.example.MyFilter</filter-class> <!-- 可选:初始化参数 --> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/*</url-pattern> <!-- 拦截所有请求 --> <!-- 或指定具体路径,如 <url-pattern>/api/*</url-pattern> --> </filter-mapping> -
注解配置(推荐)
在过滤器类上使用@WebFilter注解,直接指定URL模式,无需修改web.xml:import javax.servlet.annotation.WebFilter; @WebFilter(urlPatterns = "/*", initParams = { @WebInitParam(name = "encoding", value = "UTF-8") }) public class MyFilter implements Filter { // 实现方法同上 }注解方式更简洁,但需确保Servlet版本支持(如Servlet 3.0+)。
过滤器的执行顺序与链式调用
当多个过滤器映射到同一URL时,容器的执行顺序遵循以下规则:
- XML配置:按
<filter-mapping>在web.xml中声明的顺序执行。 - 注解配置:按类名的字典序执行,或通过
@WebFilter的dispatcherTypes和urlPatterns组合控制。
过滤器的链式调用通过FilterChain对象实现,若有过滤器A和B,且A先配置,则执行流程为:
客户端请求 → A的doFilter() → A调用chain.doFilter() → B的doFilter() → B调用chain.doFilter() → 目标资源 → 返回时B的后处理 → A的后处理 → 客户端。
常见应用场景
-
字符编码处理
统一设置请求和响应的字符编码,解决乱码问题:
request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); -
身份验证与授权
检查用户是否登录,未登录则重定向至登录页:if (request.getSession().getAttribute("user") == null) { response.sendRedirect("login.jsp"); return; // 终止过滤器链 } -
日志记录
记录请求的IP、时间、路径等信息:System.out.println("Request from: " + request.getRemoteAddr()); System.out.println("Request URI: " + request.getRequestURI()); -
敏感数据过滤
过滤请求参数中的非法字符,防止XSS攻击:String input = request.getParameter("data"); String sanitized = input.replaceAll("<script>", ""); request.setAttribute("sanitizedData", sanitized);
注意事项
- 性能优化:避免在
doFilter()中执行耗时操作,必要时使用异步过滤器(AsyncContext)。 - 线程安全:过滤器实例是单例的,若需存储状态,应使用线程局部变量(
ThreadLocal)。 - 异常处理:捕获
doFilter()中的异常,避免未处理的异常导致过滤器链中断。
通过合理使用过滤器,开发者可以将业务逻辑与横切关注点分离,构建更清晰、更易维护的Web应用,无论是传统企业级项目还是现代微服务架构,过滤器都是不可或缺的技术工具。