1.什么是过滤器?
过滤器是Java Web中的一种预处理/后处理机制,位于客户端与服务器资源之间,可以拦截请求和响应进行统一处理。它是Servlet规范定义的组件,工作在Servlet容器层面。
核心特性:
基于责任链模式(Chain of Responsibility)
可配置多个过滤器形成过滤链
不依赖于任何框架(Servlet规范原生支持)
2.过滤器能解决什么问题?
通用预处理:
字符编码设置
敏感词过滤
请求参数预处理
安全控制:
身份认证与授权
XSS/SQL注入防御
CSRF防护
性能优化:
响应压缩(Gzip)
缓存控制
请求限流
日志监控:
访问日志记录
请求耗时统计
异常统一捕获
跨域处理:
CORS头设置
跨域请求预检处理
3.使用步骤(以Java Web为例)
1. 创建过滤器类(实现javax.servlet.Filter)
public class LoggingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
// 初始化逻辑(通常读取配置参数)
System.out.println("日志过滤器初始化完成");
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
// 1. 预处理(记录请求开始时间)
long startTime = System.currentTimeMillis();
System.out.println("收到请求: " + httpRequest.getRequestURI());
// 2. 放行请求(关键操作)
chain.doFilter(request, response);
// 3. 后处理(记录响应耗时)
long duration = System.currentTimeMillis() - startTime;
System.out.println("请求处理完成,耗时: " + duration + "ms");
}
@Override
public void destroy() {
// 销毁逻辑(释放资源)
System.out.println("日志过滤器被销毁");
}
}
2. 注册过滤器(web.xml配置)
<filter>
<filter-name>loggingFilter</filter-name>
<filter-class>com.example.LoggingFilter</filter-class>
<!-- 可配置初始化参数 -->
<init-param>
<param-name>logLevel</param-name>
<param-value>DEBUG</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>loggingFilter</filter-name>
<!-- URL匹配模式 -->
<url-pattern>/*</url-pattern>
<!-- 可指定Servlet名称 -->
<!-- <servlet-name>servletName</servlet-name> -->
<!-- 支持Dispatcher类型 -->
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
3. 基于注解的配置(Servlet 3.0+)
@WebFilter(
urlPatterns = "/*",
initParams = {
@WebInitParam(name = "logLevel", value = "DEBUG")
},
servletNames = {
"servletName"},
dispatcherTypes = {
DispatcherType.REQUEST, DispatcherType.FORWARD}
)
public class LoggingFilter implements Filter {
// ...实现同上
}
4.Spring Boot中的过滤器
1. 创建Spring Bean过滤器
@Component
public class AuthFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String token = httpRequest.getHeader("Authorization");
if (!validateToken(token)) {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
chain.doFilter(request, response);
}
private boolean validateToken(String token) {
// 实现token验证逻辑
return true;
}
}
控制过滤器顺序(实现Ordered接口)
@Component
public class CorsFilter implements Filter, Ordered {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Authorization");
chain.doFilter(req, res);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE; // 最高优先级(最先执行)
}
}
3. 使用FilterRegistrationBean(精确控制)
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<LoggingFilter> loggingFilter() {
FilterRegistrationBean<LoggingFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new LoggingFilter());
registration.addUrlPatterns("/*");
registration.setOrder(Ordered.LOWEST_PRECEDENCE); // 最低优先级
return registration;
}
}
5.过滤器最佳实践
职责单一:每个过滤器只处理一个特定功能
性能注意:
避免在过滤器中执行耗时操作
合理使用Filter链的短路机制(如认证失败直接return)
异常处理:
重定向到错误页面
返回标准错误JSON(针对API请求)
路径匹配策略:
<!-- 精确匹配 -->
<url-pattern>/api/users</url-pattern>
<!-- 后缀匹配 -->
<url-pattern>*.jsp</url-pattern>
<!-- 路径匹配 -->
<url-pattern>/admin/*</url-pattern>
常见应用场景实现:
// 跨域过滤器
response.setHeader("Access-Control-Allow-Origin", "*");
// 编码过滤器
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
// XSS防御过滤器
String safeHtml = HtmlUtils.htmlEscape(rawInput);
6.与拦截器(Interceptor)的区别
维度 | 过滤器(Filter) | 拦截器(Interceptor) |
---|---|---|
规范层级 | Servlet规范 | Spring框架 |
执行位置 | Servlet容器层面 | Spring MVC处理流程中 |
依赖关系 | 不依赖任何框架 | 依赖Spring框架 |
作用范围 | 所有请求 | 仅针对Spring管理的Controller请求 |
获取上下文 | 只能获取Servlet API | 可获取Spring上下文和处理器方法信息 |
执行效率 | 更高效(更底层) | 相对稍慢 |
典型应用 | 编码设置、全局安全 | 权限检查、业务日志 |
暂无评论内容