返回

揭秘Spring Boot 3.1.2使用javax.servlet.Filter的坑与技巧

后端

在 Spring Boot 3.1.2 中注册 Filter:指南和故障排除

在 Spring Boot 3.1.2 版本中,Filter 注册方式发生了改变,如果不遵循新方法,Filter 可能会无法正常工作。本文将详细介绍在 Spring Boot 3.x 中注册 Filter 的两种方法,并提供疑难解答提示以解决 Filter 不起作用的情况。

注册 Filter 的方法

1. 使用 @ServletComponentScan 注解

最简单的方法是使用 @ServletComponentScan 注解,它将扫描带有 @WebServlet 注解的类并自动注册为 Filter。在 Spring Boot 启动类中添加该注解:

@SpringBootApplication
@ServletComponentScan
public class MyApp {}

2. 实现 ServletContainerInitializer 接口

此方法涉及实现 ServletContainerInitializer 接口并注册 Filter:

public class MyServletContainerInitializer implements ServletContainerInitializer {

  @Override
  public void onStartup(Set<Class<?>> c, ServletContext ctx) {
    FilterRegistration.Dynamic filter = ctx.addFilter("myFilter", MyFilter.class);
    filter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
  }
}

并在启动类中指定实现类:

@SpringBootApplication
@ServletComponentScan(basePackageClasses = {MyServletContainerInitializer.class})
public class MyApp {}

Filter 不起作用的疑难解答

  • 检查 Filter 注册: 确保已正确注册 Filter,使用 @ServletComponentScan 注解或 ServletContainerInitializer
  • 检查 Filter 实现: init()doFilter() 方法是否正确实现,包括正确的日志和过滤逻辑。
  • 检查 Filter 规则: 确保 Filter 的过滤规则正确配置(例如 URL 模式)。
  • 检查 Filter 依赖项: 如果 Filter 依赖于其他 bean,确保已正确注入。
  • 检查 Filter 日志级别: 确保 Filter 的日志级别设置为所需级别,以查看输出。

常见问题解答

  1. Filter 没有输出日志,但已经实现 init()destroy() 方法?
    • Spring Boot 3.x 中默认禁用了 Filter 日志记录,需要修改日志级别或在 Filter 中手动添加日志记录。
  2. Filter 注册后为什么没有阻塞数据?
    • 检查 Filter 的过滤规则是否正确配置,并且 Filter 不会立即放行数据(例如使用 FilterChain.doFilter(request, response);)。
  3. 如何使用基于注解的 Filter?
    • 使用 @WebFilter 注解代替 @WebServlet 注解,然后使用 @ServletComponentScan 扫描并自动注册。
  4. Filter 顺序是如何确定的?
    • Filter 的顺序由注册顺序和 @Order 注解(如果有)确定。
  5. 如何访问 Servlet 上下文中的信息?
    • 在 Filter 的 init() 方法中使用 getServletContext() 方法访问 Servlet 上下文信息。