Spring Boot过滤器是Web应用程序中处理请求和响应的一种重要机制。过滤器能够在请求到达Servlet之前以及响应离开Servlet之后,对其进行预处理或后处理。这些处理可以包括日志记录、安全检查、数据压缩等。本文将详细介绍Spring Boot过滤器,从基础概念到高级应用,涵盖各类过滤器的使用场景、实现方法和最佳实践。

1. Spring Boot过滤器概述

1.1 过滤器的定义与作用

过滤器(Filter)是一种Java EE标准,允许在请求到达Servlet之前和响应离开Servlet之后对其进行处理。它们主要用于以下任务:

  • 请求和响应的日志记录
  • 安全性检查和认证
  • 请求参数的修改和校验
  • 响应的压缩和编码

1.2 过滤器的生命周期

过滤器的生命周期包括初始化(init)、处理(doFilter)和销毁(destroy)三个阶段:

  • init:在过滤器实例被创建时调用,通常用于资源初始化。
  • doFilter:在每次请求到达Servlet之前和响应离开Servlet之后调用,是主要的处理逻辑。
  • destroy:在过滤器实例被销毁时调用,通常用于资源释放。

2. 创建Spring Boot过滤器

2.1 基础过滤器实现

在Spring Boot中创建一个过滤器需要实现javax.servlet.Filter接口,并重写其方法。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import java.io.IOException;
  4. public class MyFilter implements Filter {
  5. @Override
  6. public void init(FilterConfig filterConfig) throws ServletException {
  7. // 初始化逻辑
  8. }
  9. @Override
  10. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  11. throws IOException, ServletException {
  12. HttpServletRequest req = (HttpServletRequest) request;
  13. System.out.println("Request URI is: " + req.getRequestURI());
  14. chain.doFilter(request, response); // 调用下一个过滤器或目标资源
  15. }
  16. @Override
  17. public void destroy() {
  18. // 资源释放逻辑
  19. }
  20. }

2.2 注册过滤器

在Spring Boot中,可以通过两种方式注册过滤器:使用@Bean注解或通过FilterRegistrationBean类。

使用@Bean注解注册过滤器
  1. import org.springframework.boot.web.servlet.FilterRegistrationBean;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. @Configuration
  5. public class FilterConfig {
  6. @Bean
  7. public FilterRegistrationBean<MyFilter> loggingFilter() {
  8. FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();
  9. registrationBean.setFilter(new MyFilter());
  10. registrationBean.addUrlPatterns("/api/*");
  11. return registrationBean;
  12. }
  13. }
使用FilterRegistrationBean类注册过滤器
  1. import org.springframework.boot.web.servlet.FilterRegistrationBean;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. @Configuration
  5. public class FilterConfig {
  6. @Bean
  7. public FilterRegistrationBean<MyFilter> loggingFilter() {
  8. FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();
  9. registrationBean.setFilter(new MyFilter());
  10. registrationBean.addUrlPatterns("/api/*");
  11. registrationBean.setOrder(1); // 设置过滤器顺序
  12. return registrationBean;
  13. }
  14. }

3. 常见过滤器类型

3.1 日志记录过滤器

日志记录过滤器用于记录请求和响应的详细信息,方便后续的分析和调试。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import java.io.IOException;
  4. public class LoggingFilter implements Filter {
  5. @Override
  6. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  7. throws IOException, ServletException {
  8. HttpServletRequest req = (HttpServletRequest) request;
  9. long startTime = System.currentTimeMillis();
  10. chain.doFilter(request, response);
  11. long endTime = System.currentTimeMillis();
  12. System.out.println("Request URI: " + req.getRequestURI() + ", Time taken: " + (endTime - startTime) + " ms");
  13. }
  14. }

3.2 安全过滤器

安全过滤器用于检查请求的合法性,如验证用户身份、权限等。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import java.io.IOException;
  5. public class SecurityFilter implements Filter {
  6. @Override
  7. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  8. throws IOException, ServletException {
  9. HttpServletRequest req = (HttpServletRequest) request;
  10. HttpServletResponse res = (HttpServletResponse) response;
  11. String authHeader = req.getHeader("Authorization");
  12. if (authHeader == null || !authHeader.startsWith("Bearer ")) {
  13. res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
  14. return;
  15. }
  16. // 验证token逻辑
  17. String token = authHeader.substring(7);
  18. if (!validateToken(token)) {
  19. res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
  20. return;
  21. }
  22. chain.doFilter(request, response);
  23. }
  24. private boolean validateToken(String token) {
  25. // token验证逻辑
  26. return "valid_token".equals(token);
  27. }
  28. }

3.3 压缩过滤器

压缩过滤器用于压缩响应数据,提高传输效率。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletResponse;
  3. import java.io.IOException;
  4. import java.util.zip.GZIPOutputStream;
  5. public class CompressionFilter implements Filter {
  6. @Override
  7. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  8. throws IOException, ServletException {
  9. HttpServletResponse res = (HttpServletResponse) response;
  10. CompressionResponseWrapper wrappedResponse = new CompressionResponseWrapper(res);
  11. chain.doFilter(request, wrappedResponse);
  12. wrappedResponse.finishResponse();
  13. }
  14. class CompressionResponseWrapper extends HttpServletResponseWrapper {
  15. private GZIPOutputStream gzipOutputStream = null;
  16. private ServletOutputStream servletOutputStream = null;
  17. private PrintWriter printWriter = null;
  18. public CompressionResponseWrapper(HttpServletResponse response) throws IOException {
  19. super(response);
  20. }
  21. @Override
  22. public ServletOutputStream getOutputStream() throws IOException {
  23. if (servletOutputStream == null) {
  24. servletOutputStream = createOutputStream();
  25. }
  26. return servletOutputStream;
  27. }
  28. @Override
  29. public PrintWriter getWriter() throws IOException {
  30. if (printWriter == null) {
  31. printWriter = new PrintWriter(new OutputStreamWriter(getOutputStream(), getCharacterEncoding()));
  32. }
  33. return printWriter;
  34. }
  35. private ServletOutputStream createOutputStream() throws IOException {
  36. gzipOutputStream = new GZIPOutputStream(getResponse().getOutputStream());
  37. return new ServletOutputStream() {
  38. @Override
  39. public void write(int b) throws IOException {
  40. gzipOutputStream.write(b);
  41. }
  42. @Override
  43. public void close() throws IOException {
  44. gzipOutputStream.close();
  45. }
  46. @Override
  47. public void flush() throws IOException {
  48. gzipOutputStream.flush();
  49. }
  50. @Override
  51. public boolean isReady() {
  52. return false;
  53. }
  54. @Override
  55. public void setWriteListener(WriteListener writeListener) {
  56. }
  57. };
  58. }
  59. public void finishResponse() throws IOException {
  60. if (printWriter != null) {
  61. printWriter.close();
  62. }
  63. if (gzipOutputStream != null) {
  64. gzipOutputStream.close();
  65. }
  66. }
  67. }
  68. }

4. 过滤器的高级应用

4.1 过滤器链

过滤器链(Filter Chain)是多个过滤器依次执行的过程。每个过滤器在调用chain.doFilter()方法时会将请求传递给下一个过滤器。

配置多个过滤器
  1. @Configuration
  2. public class FilterConfig {
  3. @Bean
  4. public FilterRegistrationBean<LoggingFilter> loggingFilter() {
  5. FilterRegistrationBean<LoggingFilter> registrationBean = new FilterRegistrationBean<>();
  6. registrationBean.setFilter(new LoggingFilter());
  7. registrationBean.addUrlPatterns("/api/*");
  8. registrationBean.setOrder(1);
  9. return registrationBean;
  10. }
  11. @Bean
  12. public FilterRegistrationBean<SecurityFilter> securityFilter() {
  13. FilterRegistrationBean<SecurityFilter> registrationBean = new FilterRegistrationBean<>();
  14. registrationBean.setFilter(new SecurityFilter());
  15. registrationBean.addUrlPatterns("/api/*");
  16. registrationBean.setOrder(2);
  17. return registrationBean;
  18. }
  19. }

4.2 异步过滤器

异步过滤器允许在非阻塞模式下处理请求,适用于高并发场景。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import java.io.IOException;
  5. import java.util.concurrent.CompletableFuture;
  6. public class AsyncFilter implements Filter {
  7. @Override
  8. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain
  9. )
  10. throws IOException, ServletException {
  11. HttpServletRequest req = (HttpServletRequest) request;
  12. HttpServletResponse res = (HttpServletResponse) response;
  13. CompletableFuture.runAsync(() -> {
  14. try {
  15. // 异步处理逻辑
  16. chain.doFilter(request, response);
  17. } catch (IOException | ServletException e) {
  18. e.printStackTrace();
  19. }
  20. });
  21. }
  22. }

4.3 自定义过滤器顺序

通过设置过滤器的order属性,可以自定义过滤器的执行顺序。

示例代码
  1. @Configuration
  2. public class FilterConfig {
  3. @Bean
  4. public FilterRegistrationBean<LoggingFilter> loggingFilter() {
  5. FilterRegistrationBean<LoggingFilter> registrationBean = new FilterRegistrationBean<>();
  6. registrationBean.setFilter(new LoggingFilter());
  7. registrationBean.addUrlPatterns("/api/*");
  8. registrationBean.setOrder(1); // LoggingFilter先执行
  9. return registrationBean;
  10. }
  11. @Bean
  12. public FilterRegistrationBean<SecurityFilter> securityFilter() {
  13. FilterRegistrationBean<SecurityFilter> registrationBean = new FilterRegistrationBean<>();
  14. registrationBean.setFilter(new SecurityFilter());
  15. registrationBean.addUrlPatterns("/api/*");
  16. registrationBean.setOrder(2); // SecurityFilter后执行
  17. return registrationBean;
  18. }
  19. }

5. 过滤器的测试

5.1 单元测试

通过Mock框架,如Mockito,可以对过滤器进行单元测试。

示例代码
  1. import org.junit.jupiter.api.Test;
  2. import org.mockito.Mock;
  3. import org.mockito.MockitoAnnotations;
  4. import javax.servlet.FilterChain;
  5. import javax.servlet.ServletException;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.IOException;
  9. import static org.mockito.Mockito.*;
  10. public class LoggingFilterTest {
  11. @Mock
  12. private HttpServletRequest request;
  13. @Mock
  14. private HttpServletResponse response;
  15. @Mock
  16. private FilterChain filterChain;
  17. @Test
  18. public void testDoFilter() throws IOException, ServletException {
  19. MockitoAnnotations.initMocks(this);
  20. LoggingFilter loggingFilter = new LoggingFilter();
  21. when(request.getRequestURI()).thenReturn("/api/test");
  22. loggingFilter.doFilter(request, response, filterChain);
  23. verify(filterChain).doFilter(request, response);
  24. verify(request).getRequestURI();
  25. }
  26. }

5.2 集成测试

通过Spring Boot的测试框架,可以对过滤器进行集成测试。

示例代码
  1. import org.junit.jupiter.api.Test;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.boot.test.context.SpringBootTest;
  4. import org.springframework.boot.test.web.client.TestRestTemplate;
  5. import org.springframework.boot.web.server.LocalServerPort;
  6. import org.springframework.http.ResponseEntity;
  7. import static org.assertj.core.api.Assertions.assertThat;
  8. @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
  9. public class FilterIntegrationTest {
  10. @LocalServerPort
  11. private int port;
  12. @Autowired
  13. private TestRestTemplate restTemplate;
  14. @Test
  15. public void testFilters() {
  16. String url = "http://localhost:" + port + "/api/test";
  17. ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
  18. assertThat(response.getStatusCode().is2xxSuccessful()).isTrue();
  19. // 其他断言逻辑
  20. }
  21. }

6. 过滤器的性能优化

6.1 减少不必要的过滤器处理

确保每个过滤器只处理它关心的请求路径,避免不必要的处理。

示例代码
  1. @Configuration
  2. public class FilterConfig {
  3. @Bean
  4. public FilterRegistrationBean<LoggingFilter> loggingFilter() {
  5. FilterRegistrationBean<LoggingFilter> registrationBean = new FilterRegistrationBean<>();
  6. registrationBean.setFilter(new LoggingFilter());
  7. registrationBean.addUrlPatterns("/api/log/*"); // 仅处理 /api/log/ 路径
  8. registrationBean.setOrder(1);
  9. return registrationBean;
  10. }
  11. }

6.2 异步处理

使用异步过滤器处理耗时操作,减少对请求处理的阻塞。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import java.io.IOException;
  5. import java.util.concurrent.CompletableFuture;
  6. public class AsyncFilter implements Filter {
  7. @Override
  8. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  9. throws IOException, ServletException {
  10. HttpServletRequest req = (HttpServletRequest) request;
  11. HttpServletResponse res = (HttpServletResponse) response;
  12. CompletableFuture.runAsync(() -> {
  13. try {
  14. // 异步处理逻辑
  15. chain.doFilter(request, response);
  16. } catch (IOException | ServletException e) {
  17. e.printStackTrace();
  18. }
  19. });
  20. }
  21. }

6.3 缓存结果

对于一些固定响应内容的过滤器,可以使用缓存来提升性能。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import java.io.IOException;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7. public class CachingFilter implements Filter {
  8. private final Map<String, String> cache = new HashMap<>();
  9. @Override
  10. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  11. throws IOException, ServletException {
  12. HttpServletRequest req = (HttpServletRequest) request;
  13. HttpServletResponse res = (HttpServletResponse) response;
  14. String requestUri = req.getRequestURI();
  15. if (cache.containsKey(requestUri)) {
  16. res.getWriter().write(cache.get(requestUri));
  17. } else {
  18. CachingResponseWrapper responseWrapper = new CachingResponseWrapper(res);
  19. chain.doFilter(request, responseWrapper);
  20. String content = responseWrapper.getContent();
  21. cache.put(requestUri, content);
  22. res.getWriter().write(content);
  23. }
  24. }
  25. class CachingResponseWrapper extends HttpServletResponseWrapper {
  26. private final StringWriter sw = new StringWriter();
  27. public CachingResponseWrapper(HttpServletResponse response) {
  28. super(response);
  29. }
  30. @Override
  31. public PrintWriter getWriter() throws IOException {
  32. return new PrintWriter(sw);
  33. }
  34. public String getContent() {
  35. return sw.toString();
  36. }
  37. }
  38. }

7. 过滤器的安全性

7.1 防止XSS攻击

使用过滤器对请求参数进行校验,防止XSS攻击。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import java.io.IOException;
  5. public class XSSFilter implements Filter {
  6. @Override
  7. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  8. throws IOException, ServletException {
  9. HttpServletRequest req = (HttpServletRequest) request;
  10. HttpServletResponse res = (HttpServletResponse) response;
  11. XSSRequestWrapper wrappedRequest = new XSSRequestWrapper(req);
  12. chain.doFilter(wrappedRequest, response);
  13. }
  14. }
  15. class XSSRequestWrapper extends HttpServletRequestWrapper {
  16. public XSSRequestWrapper(HttpServletRequest request) {
  17. super(request);
  18. }
  19. @Override
  20. public String getParameter(String name) {
  21. String value = super.getParameter(name);
  22. return cleanXSS(value);
  23. }
  24. private String cleanXSS(String value) {
  25. if (value != null) {
  26. value = value.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
  27. value = value.replaceAll("\\(", "&#40;").replaceAll("\\)", "&#41;");
  28. value = value.replaceAll("'", "&#39;");
  29. value = value.replaceAll("eval\\((.*)\\)", "");
  30. value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
  31. value = value.replaceAll("script", "");
  32. }
  33. return value;
  34. }
  35. }

7.2 防止CSRF攻击

通过过滤器添加CSRF令牌,防止CSRF攻击。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import java.io.IOException;
  5. public class CSRFTokenFilter implements Filter {
  6. @Override
  7. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  8. throws IOException, ServletException {
  9. HttpServletRequest req = (HttpServletRequest) request;
  10. HttpServletResponse res = (HttpServletResponse) response;
  11. String csrfToken = (String) req.getSession().getAttribute("CSRF_TOKEN");
  12. if (csrfToken == null) {
  13. csrfToken = generateCSRFToken();
  14. req.getSession().setAttribute("CSRF_TOKEN", csrfToken);
  15. }
  16. res.addHeader("CSRF-Token", csrfToken);
  17. chain.doFilter(request, response);
  18. }
  19. private String generateCSRFToken() {
  20. return Long.toHexString(System.currentTimeMillis());
  21. }
  22. }

7.3 防止SQL注入

通过过滤器对请求参数进行校验,防止SQL注入攻击。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import java.io.IOException;
  5. public class SQLInjectionFilter implements Filter {
  6. @Override
  7. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  8. throws IOException, ServletException {
  9. HttpServletRequest req = (HttpServletRequest
  10. ) request;
  11. HttpServletResponse res = (HttpServletResponse) response;
  12. SQLInjectionRequestWrapper wrappedRequest = new SQLInjectionRequestWrapper(req);
  13. chain.doFilter(wrappedRequest, response);
  14. }
  15. }
  16. class SQLInjectionRequestWrapper extends HttpServletRequestWrapper {
  17. public SQLInjectionRequestWrapper(HttpServletRequest request) {
  18. super(request);
  19. }
  20. @Override
  21. public String getParameter(String name) {
  22. String value = super.getParameter(name);
  23. return cleanSQLInjection(value);
  24. }
  25. private String cleanSQLInjection(String value) {
  26. if (value != null) {
  27. value = value.replaceAll("'", "''");
  28. value = value.replaceAll(";", "");
  29. value = value.replaceAll("--", "");
  30. }
  31. return value;
  32. }
  33. }

8. 过滤器的监控和日志

8.1 记录过滤器的执行时间

通过日志记录过滤器的执行时间,便于性能监控和调试。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import java.io.IOException;
  4. public class ExecutionTimeLoggingFilter implements Filter {
  5. @Override
  6. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  7. throws IOException, ServletException {
  8. HttpServletRequest req = (HttpServletRequest) request;
  9. long startTime = System.currentTimeMillis();
  10. chain.doFilter(request, response);
  11. long endTime = System.currentTimeMillis();
  12. System.out.println("Request URI: " + req.getRequestURI() + ", Execution time: " + (endTime - startTime) + " ms");
  13. }
  14. }

8.2 记录请求和响应的详细信息

通过日志记录请求和响应的详细信息,便于分析和调试。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import java.io.IOException;
  5. public class RequestResponseLoggingFilter implements Filter {
  6. @Override
  7. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  8. throws IOException, ServletException {
  9. HttpServletRequest req = (HttpServletRequest) request;
  10. HttpServletResponse res = (HttpServletResponse) response;
  11. System.out.println("Request URI: " + req.getRequestURI());
  12. System.out.println("Request Method: " + req.getMethod());
  13. System.out.println("Request Headers: " + getRequestHeaders(req));
  14. chain.doFilter(request, response);
  15. System.out.println("Response Status: " + res.getStatus());
  16. }
  17. private String getRequestHeaders(HttpServletRequest request) {
  18. StringBuilder headers = new StringBuilder();
  19. request.getHeaderNames().asIterator().forEachRemaining(headerName -> {
  20. headers.append(headerName).append(": ").append(request.getHeader(headerName)).append("\n");
  21. });
  22. return headers.toString();
  23. }
  24. }

9. 过滤器的故障处理

9.1 捕获和处理异常

通过过滤器捕获和处理请求中的异常,提供统一的错误响应。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import java.io.IOException;
  5. public class ExceptionHandlingFilter implements Filter {
  6. @Override
  7. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  8. throws IOException, ServletException {
  9. try {
  10. chain.doFilter(request, response);
  11. } catch (Exception e) {
  12. HttpServletResponse res = (HttpServletResponse) response;
  13. res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  14. res.getWriter().write("Internal Server Error: " + e.getMessage());
  15. }
  16. }
  17. }

9.2 自定义错误页面

通过过滤器实现自定义错误页面,提升用户体验。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import java.io.IOException;
  5. public class CustomErrorPageFilter implements Filter {
  6. @Override
  7. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  8. throws IOException, ServletException {
  9. try {
  10. chain.doFilter(request, response);
  11. } catch (Exception e) {
  12. HttpServletResponse res = (HttpServletResponse) response;
  13. res.sendRedirect("/error-page");
  14. }
  15. }
  16. }

10. 过滤器的最佳实践

10.1 避免长时间阻塞

避免在过滤器中执行长时间阻塞操作,如IO操作或复杂计算。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import java.io.IOException;
  5. public class NonBlockingFilter implements Filter {
  6. @Override
  7. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  8. throws IOException, ServletException {
  9. HttpServletRequest req = (HttpServletRequest) request;
  10. HttpServletResponse res = (HttpServletResponse) response;
  11. new Thread(() -> {
  12. try {
  13. // 异步处理
  14. chain.doFilter(request, response);
  15. } catch (IOException | ServletException e) {
  16. e.printStackTrace();
  17. }
  18. }).start();
  19. }
  20. }

10.2 合理配置过滤器顺序

根据业务逻辑合理配置过滤器的顺序,确保正确的执行顺序。

示例代码
  1. @Configuration
  2. public class FilterConfig {
  3. @Bean
  4. public FilterRegistrationBean<LoggingFilter> loggingFilter() {
  5. FilterRegistrationBean<LoggingFilter> registrationBean = new FilterRegistrationBean<>();
  6. registrationBean.setFilter(new LoggingFilter());
  7. registrationBean.addUrlPatterns("/api/*");
  8. registrationBean.setOrder(1); // LoggingFilter先执行
  9. return registrationBean;
  10. }
  11. @Bean
  12. public FilterRegistrationBean<SecurityFilter> securityFilter() {
  13. FilterRegistrationBean<SecurityFilter> registrationBean = new FilterRegistrationBean<>();
  14. registrationBean.setFilter(new SecurityFilter());
  15. registrationBean.addUrlPatterns("/api/*");
  16. registrationBean.setOrder(2); // SecurityFilter后执行
  17. return registrationBean;
  18. }
  19. }

10.3 使用过滤器链

通过FilterChain有效地组织和管理多个过滤器。

示例代码
  1. import javax.servlet.*;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import java.io.IOException;
  5. public class CombinedFilter implements Filter {
  6. private final Filter[] filters;
  7. public CombinedFilter(Filter... filters) {
  8. this.filters = filters;
  9. }
  10. @Override
  11. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  12. throws IOException, ServletException {
  13. new FilterChain() {
  14. private int index = 0;
  15. @Override
  16. public void doFilter(ServletRequest request, ServletResponse response)
  17. throws IOException, ServletException {
  18. if (index < filters.length) {
  19. filters[index++].doFilter(request, response, this);
  20. } else {
  21. chain.doFilter(request, response);
  22. }
  23. }
  24. }.doFilter(request, response);
  25. }
  26. }

总结

本文详细介绍了Spring Boot过滤器的各个方面,从基础概念到高级应用,涵盖了创建、注册、常见类型、性能优化、安全性、监控、故障处理及最佳实践等内容。通过这些知识,开发者可以更加灵活和高效地处理Web应用程序中的请求和响应,提升应用的性能和安全性。希望这篇文章能帮助您更好地理解和使用Spring Boot过滤器,提高开发效率和代码质量。

在实际开发中,掌握过滤器的使用不仅能够提高代码的可维护性,还能使您的Spring Boot应用更加健壮和灵活。今后,希望大家能多多尝试和应用这些过滤器,并不断总结经验,提升自己的开发技能。