You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot WebFlux中WebFilter不生效问题排查

问题场景

我编写了如下返回Mono<String>类型结果的Controller:

@RestController
@RequestMapping("api/v1/test")
public class TestController {

    @PostMapping
    public Mono<String> getDraft() {
        return Mono.just("ok");
    }

}

为了在请求到达时执行处理逻辑,我添加了WebFilter类型的Bean,但问题是该Bean中的控制台输出信息未显示,添加断点调试后,测试API时也不会触发断点。在actuator/beans接口中可以看到名为slf4jMdcFilter的Bean,请问是否还需要额外配置?

对应的配置类代码:

@Configuration
public class WebConfig {

    public static final String TRX_ID = "transactionId";
    public static final String PATH_URI = "pathUri";

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    WebFilter slf4jMdcFilter() {
        return (exchange, chain) -> {
            System.out.println("Filtering request");
            String requestId = exchange.getRequest().getId();
            return chain.filter(exchange)
                    .contextWrite(Context.of(TRX_ID, requestId)
                            .put(PATH_URI, exchange.getRequest().getPath()));
        };
    }

}
排查与解决办法

1. 显式指定过滤器匹配路径

默认WebFilter匹配所有路径,但如果应用有特殊路径配置(如server.servlet.context-path),可能导致请求未进入过滤器。可以通过FilterRegistrationBean显式指定匹配路径:

@Configuration
public class WebConfig {

    public static final String TRX_ID = "transactionId";
    public static final String PATH_URI = "pathUri";

    @Bean
    WebFilter slf4jMdcFilter() {
        return (exchange, chain) -> {
            System.out.println("Filtering request");
            String requestId = exchange.getRequest().getId();
            return chain.filter(exchange)
                    .contextWrite(Context.of(TRX_ID, requestId)
                            .put(PATH_URI, exchange.getRequest().getPath()));
        };
    }

    @Bean
    FilterRegistrationBean<WebFilter> slf4jMdcFilterRegistration() {
        FilterRegistrationBean<WebFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(slf4jMdcFilter());
        registrationBean.addUrlPatterns("/api/v1/test/*"); // 匹配你的接口路径
        registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return registrationBean;
    }
}

2. 确认项目环境是WebFlux

WebFilter是Spring WebFlux专属组件,如果你的项目依赖的是spring-boot-starter-web(Spring MVC环境),WebFilter不会生效,需改用Spring MVC的Filter接口:

@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
Filter slf4jMdcFilter() {
    return new Filter() {
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            System.out.println("Filtering request");
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            String requestId = httpRequest.getRequestId();
            try {
                chain.doFilter(request, response);
            } finally {
                // 若使用SLF4J MDC,此处需清理上下文
                // MDC.remove(TRX_ID);
            }
        }
    };
}

3. 检查配置类的组件扫描范围

确保WebConfig所在的包被Spring组件扫描覆盖,比如主启动类的包包含WebConfig的包,或者在WebConfig上添加@ComponentScan指定扫描范围。

4. 验证请求是否正确到达应用

确认测试请求的URL、请求方法(POST)、端口、context-path是否正确,排查是否有网关、反向代理拦截了请求。

5. 排查过滤器优先级冲突

虽然设置了Ordered.HIGHEST_PRECEDENCE,但如果有其他过滤器优先级更高且终止了请求链,会导致你的过滤器不执行。可以暂时去掉@Order测试,或检查其他过滤器的逻辑。

内容的提问来源于stack exchange,提问作者Aymen Kanzari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:26:00