Java过滤器的基本概念与作用
Java过滤器(Filter)是Servlet规范中的一种重要组件,主要用于对请求和响应进行预处理和后处理,它可以在请求到达目标资源之前拦截请求,或在响应返回客户端之前修改响应内容,过滤器常用于实现日志记录、权限验证、字符编码转换、数据压缩等通用功能,通过复用过滤器代码,可以减少重复开发,提升系统的可维护性。

过滤器的核心实现步骤
要编写一个Java过滤器,需遵循以下核心步骤:
创建过滤器类并实现接口
创建一个类并实现javax.servlet.Filter接口,该接口包含三个关键方法:
init(FilterConfig config):过滤器初始化时调用,用于加载配置参数或执行初始化操作。doFilter(ServletRequest request, ServletResponse response, FilterChain chain):过滤器的核心逻辑,每次请求匹配过滤器时都会调用。destroy():过滤器销毁时调用,用于释放资源(如关闭数据库连接、清理临时文件等)。
示例代码框架如下:
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化逻辑,例如读取配置参数
String param = filterConfig.getInitParameter("paramName");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 预处理逻辑(如字符编码设置、权限检查)
request.setCharacterEncoding("UTF-8");
// 放行请求,传递到下一个过滤器或目标资源
chain.doFilter(request, response);
// 后处理逻辑(如修改响应内容、记录日志)
response.setContentType("text/html;charset=UTF-8");
}
@Override
public void destroy() {
// 资源清理逻辑
}
}
配置过滤器映射
过滤器需要通过web.xml配置文件或注解@WebFilter与URL模式绑定,才能拦截对应的请求。

使用web.xml配置
在web.xml中添加以下配置:
<filter>
<filter-name>myFilter</filter-name>
<filter-class>com.example.MyFilter</filter-class>
<!-- 初始化参数(可选) -->
<init-param>
<param-name>paramName</param-name>
<param-value>paramValue</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<!-- 拦截所有请求 /* -->
<url-pattern>/*</url-pattern>
<!-- 可选:指定拦截的Servlet <servlet-name>servletName</servlet-name> -->
</filter-mapping>
使用注解配置(Servlet 3.0+)
在过滤器类上直接添加@WebFilter注解,简化配置:
import javax.servlet.annotation.WebFilter;
@WebFilter(urlPatterns = "/*", initParams = {
@WebInitParam(name = "paramName", value = "paramValue")
})
public class MyFilter implements Filter {
// 实现同上
}
过滤器的实际应用场景
字符编码过滤器
解决POST请求乱码问题,是最常见的过滤器类型之一:
@WebFilter("/*")
public class EncodingFilter implements Filter {
private String encoding = "UTF-8";
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
request.setCharacterEncoding(encoding);
response.setCharacterEncoding(encoding);
chain.doFilter(request, response);
}
}
权限验证过滤器
用于检查用户是否登录,未登录则重定向到登录页面:

@WebFilter("/admin/*")
public class AuthFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpSession session = req.getSession();
if (session.getAttribute("user") == null) {
req.getRequestDispatcher("/login.jsp").forward(request, response);
return;
}
chain.doFilter(request, response);
}
}
日志记录过滤器
记录请求的URL、IP地址、访问时间等信息:
@WebFilter("/*")
public class LogFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
String uri = req.getRequestURI();
String ip = req.getRemoteAddr();
long startTime = System.currentTimeMillis();
System.out.println("请求URI: " + uri + ", IP: " + ip + ", 时间: " + new Date());
chain.doFilter(request, response);
long endTime = System.currentTimeMillis();
System.out.println("请求处理耗时: " + (endTime - startTime) + "ms");
}
}
过滤器的执行顺序与链式调用
当多个过滤器映射同一URL时,过滤器的执行顺序由web.xml中的<filter-mapping>配置顺序决定(配置靠前的先执行),或通过注解@WebFilter的dispatcherTypes和urlPatterns顺序控制,过滤器的执行流程为:
- 请求到达时,按顺序执行每个过滤器的预处理逻辑。
- 调用
chain.doFilter()后,请求传递到下一个过滤器或目标资源。 - 目标资源处理完成后,按相反顺序执行每个过滤器的后处理逻辑。
注意事项
- 性能优化:避免在过滤器中执行耗时操作(如数据库查询),影响请求响应速度。
- 资源释放:在
destroy()方法中确保关闭资源(如文件流、数据库连接)。 - 异常处理:合理捕获并处理
doFilter()中的异常,避免因过滤器错误导致请求中断。 - 线程安全:过滤器实例是单例的,避免在过滤器中定义线程不安全的成员变量(如
SimpleDateFormat)。
通过以上步骤和示例,可以快速掌握Java过滤器的编写方法,过滤器作为Servlet生态中的重要工具,能够有效分离通用逻辑与业务代码,提升系统的模块化程度和开发效率。















