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

Spring Gateway自定义过滤器配置疑问:能否在application.properties中注册路由过滤器及无代码路由配置下的生效方案

解决Spring Gateway自定义过滤器在配置文件路由中生效的问题

针对你的需求,我们可以通过两种方案来实现——全局过滤器(推荐,适合全路由生效的场景) 或者 正确配置过滤器工厂(适合按需给指定路由添加的场景),下面分别说明:


方案一:将JWT过滤器改为全局过滤器(无需在路由中单独配置)

如果你的JWT验证逻辑需要对所有路由生效(除了/login、/register这类白名单),最简洁的方式是把JwtAuthenticationFilter实现GlobalFilter和Ordered接口,这样它会自动作用于所有路由,不管路由是在配置文件还是代码中定义的。

修改你的JwtAuthenticationFilter代码:

@Component
public class JwtAuthenticationFilter implements GlobalFilter, Ordered {
    @Value("${dolphin.gateway.jwt.verify:true}")
    private boolean jwtVerify;
    final static List<String> apiEndpoints = List.of("/register", "/login");
    final static Predicate<ServerHttpRequest> isApiSecured = r -> apiEndpoints.stream()
            .noneMatch(uri -> r.getURI().getPath().contains(uri));

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 这里写你的JWT验证逻辑,比如从header取token、验证有效性
        if (jwtVerify && isApiSecured.test(exchange.getRequest())) {
            // 示例验证逻辑(根据实际需求调整):
            // String token = exchange.getRequest().getHeaders().getFirst("Authorization");
            // if (token == null || !validateToken(token)) {
            //     exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            //     return exchange.getResponse().setComplete();
            // }
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        // 设置过滤器执行顺序,数值越小越先执行,根据你的需求调整
        return -100;
    }
}

这样修改后,你可以完全删除GatewayConfig类(代码中的路由定义),只保留application.properties中的路由配置即可,过滤器会自动对所有路由生效,同时你的白名单逻辑也能正常工作。


方案二:修复过滤器工厂(针对指定路由配置过滤器)

如果你只想给部分路由添加这个JWT过滤器,那需要修正你的过滤器工厂写法——Spring Gateway对过滤器工厂的命名有严格规范:

  1. 过滤器工厂类名必须以GatewayFilterFactory结尾(比如MyJwtGatewayFilterFactory),这样配置时可以简写为MyJwt
  2. 确保过滤器工厂被Spring正确扫描到

修改你的过滤器工厂代码:

@Component
public class MyJwtGatewayFilterFactory extends AbstractGatewayFilterFactory<MyJwtGatewayFilterFactory.Config> {
    private final JwtAuthenticationFilter jwtAuthenticationFilter;

    // 构造注入,避免@Autowired,符合Spring最佳实践
    public MyJwtGatewayFilterFactory(JwtAuthenticationFilter jwtAuthenticationFilter) {
        super(Config.class);
        this.jwtAuthenticationFilter = jwtAuthenticationFilter;
    }

    @Override
    public GatewayFilter apply(Config config) {
        return jwtAuthenticationFilter;
    }

    public static class Config {
        // 如果需要给过滤器配置参数,可以在这里添加字段和getter/setter,比如开关验证的参数
    }
}

然后在application.properties中配置路由时,指定过滤器:

# dolphin music
spring.cloud.gateway.discovery.locator.enabled=true
spring.cloud.gateway.discovery.locator.lower-case-service-id=true
spring.cloud.gateway.routes[0].id=dolphin-music-service
spring.cloud.gateway.routes[0].uri=http://10.107.64.246:11014
spring.cloud.gateway.routes[0].predicates[0]=Path=/music/**
# 配置过滤器,用类名去掉GatewayFilterFactory后的部分
spring.cloud.gateway.routes[0].filters[0]=MyJwt

为什么之前的过滤器工厂没生效?

  • 你的类名是MyFilterFactory,不符合Spring Gateway的过滤器工厂命名规范(必须以GatewayFilterFactory结尾),所以Spring无法识别这是一个网关过滤器工厂,配置文件中的MyFilterFactory也就找不到对应的实现。
  • 另外,构造注入比@Autowired更稳定,也更符合现代Spring的编码习惯。

总结

  • 如果是全局生效的验证逻辑,优先用GlobalFilter,无需在路由中做任何配置,最简洁灵活。
  • 如果需要针对特定路由配置,按照规范写GatewayFilterFactory,然后在配置文件中指定过滤器名称即可。
  • 完全不需要在代码中定义路由,你可以保留application.properties的路由配置方式,保持灵活性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 12:32:31