Spring中的过滤器实际生产中的应用
过滤器主要用于拦截和处理 HTTP 请求和响应。它在 Web 开发中有许多实际用途,以下是一些常见场景和源码例子:
1. 安全性
用途:
-
检查用户是否登录(身份认证)。
-
验证用户的权限(权限校验)。
-
防范常见的安全攻击(如 SQL 注入、XSS)。
示例代码:验证用户是否登录
@WebFilter(urlPatterns = "/secure/*")
public class AuthFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// 检查用户是否已登录
Object user = httpRequest.getSession().getAttribute("user");
if (user == null) {
httpResponse.sendRedirect("/login"); // 未登录则跳转到登录页面
return;
}
chain.doFilter(request, response); // 已登录则继续执行请求
}
}
实际用途:
-
在企业级应用中,保护
/admin/*或/secure/*路径,确保只有已登录用户能访问。
2. 日志记录
用途:
-
记录请求的访问路径、参数、IP 地址、处理时间。
-
提供系统的运行日志,用于调试和性能分析。
示例代码:记录请求和响应日志
@WebFilter(urlPatterns = "/*")
public class LoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
long startTime = System.currentTimeMillis();
System.out.println("Request URL: " + httpRequest.getRequestURI());
System.out.println("Client IP: " + httpRequest.getRemoteAddr());
chain.doFilter(request, response); // 执行下一个过滤器或目标资源
long duration = System.currentTimeMillis() - startTime;
System.out.println("Request processed in " + duration + " ms");
}
}
实际用途:
-
分析系统的性能瓶颈。
-
追踪特定用户的行为,便于审计。
3. 数据压缩
用途:
-
对响应内容进行压缩,减少网络传输的大小,提高响应速度。
示例代码:使用 GZIP 压缩响应
@WebFilter(urlPatterns = "/*")
public class GzipFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
// 包装响应流,进行 GZIP 压缩
GzipResponseWrapper wrappedResponse = new GzipResponseWrapper(httpResponse);
chain.doFilter(request, wrappedResponse);
wrappedResponse.finish();
}
}
// 自定义 GzipResponseWrapper
class GzipResponseWrapper extends HttpServletResponseWrapper {
private GZIPOutputStream gzipOutputStream;
private ServletOutputStream outputStream;
public GzipResponseWrapper(HttpServletResponse response) throws IOException {
super(response);
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
if (outputStream == null) {
gzipOutputStream = new GZIPOutputStream(getResponse().getOutputStream());
outputStream = new ServletOutputStream() {
@Override
public void write(int b) throws IOException {
gzipOutputStream.write(b);
}
@Override
public void close() throws IOException {
gzipOutputStream.close();
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setWriteListener(WriteListener writeListener) {
}
};
}
return outputStream;
}
public void finish() throws IOException {
if (gzipOutputStream != null) {
gzipOutputStream.finish();
}
}
}
实际用途:
-
对静态资源(如 HTML、CSS、JavaScript)和 API 响应进行压缩,优化带宽使用。
4. 跨域请求处理
用途:
-
设置 CORS(跨域资源共享)头,允许前端跨域访问后端服务。
示例代码:CORS 过滤器
@WebFilter(urlPatterns = "/*")
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
// 设置 CORS 响应头
httpResponse.setHeader("Access-Control-Allow-Origin", "*");
httpResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
httpResponse.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
chain.doFilter(request, response);
}
}
实际用途:
-
用于前后端分离项目中,解决跨域访问的问题。
5. 统一编码处理
用途:
-
统一设置请求和响应的字符编码,防止中文乱码。
示例代码:统一字符编码
@WebFilter(urlPatterns = "/*")
public class EncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
}
实际用途:
-
在国际化应用中,确保字符编码一致。
6. 请求限流
用途:
-
限制特定时间窗口内的请求次数,防止流量攻击。
示例代码:简单的限流逻辑
@WebFilter(urlPatterns = "/*")
public class RateLimitingFilter implements Filter {
private final Map<String, Integer> requestCounts = new HashMap<>();
private final int LIMIT = 10; // 每分钟限制 10 次请求
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String clientIP = httpRequest.getRemoteAddr();
requestCounts.putIfAbsent(clientIP, 0);
int requests = requestCounts.get(clientIP);
if (requests >= LIMIT) {
httpResponse.setStatus(429); // Too Many Requests
httpResponse.getWriter().write("Too many requests. Please try again later.");
return;
}
requestCounts.put(clientIP, requests + 1);
chain.doFilter(request, response);
}
}
实际用途:
-
防止恶意用户或爬虫频繁访问接口。
总结
-
安全性(身份认证、权限校验)。
-
性能优化(日志记录、请求压缩)。
-
前后端协作(跨域处理)。
-
国际化支持(字符编码)。
-
流量控制(限流)。

浙公网安备 33010602011771号