Spring Gateway自定义过滤器启动报错:Unable to find GatewayFilterFactory with name JwtAuthenticationFilterGatewayFilterFactory 求助
你遇到的问题核心是自定义过滤器的实现方式和配置不匹配,Spring Cloud Gateway在解析default-filters配置时,会去寻找实现GatewayFilterFactory接口的Bean,而不是直接实现GatewayFilter的类。下面给你详细的解决步骤:
错误原因分析
你的JwtAuthenticationFilterGatewayFilterFactory直接实现了GatewayFilter接口,这属于单个过滤器实例,但spring.cloud.gateway.default-filters配置项是用来指定过滤器工厂的(后缀为GatewayFilterFactory的类),Spring会自动在容器中查找名称匹配的GatewayFilterFactory实现类,所以才会抛出Unable to find GatewayFilterFactory with name xxx的错误。
解决方案一:改用过滤器工厂模式(推荐)
修改你的过滤器类,让它继承AbstractGatewayFilterFactory(这是Spring提供的过滤器工厂抽象类,简化实现),具体代码如下:
@Component public class JwtAuthenticationFilterGatewayFilterFactory extends AbstractGatewayFilterFactory<JwtAuthenticationFilterGatewayFilterFactory.Config> { @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)); // 构造方法,指定配置类 public JwtAuthenticationFilterGatewayFilterFactory() { super(Config.class); } @Override public GatewayFilter apply(Config config) { // 这里实现你的过滤逻辑 return (exchange, chain) -> { if (jwtVerify && isApiSecured.test(exchange.getRequest())) { // 在这里添加JWT验证的逻辑,比如从请求头获取token并校验 // 示例: // 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); }; } // 配置类,如果不需要自定义配置参数,保持空类即可 public static class Config { // 可以添加需要的配置字段,比如: // private String someParam; // 并提供getter/setter } }
然后修改application.properties中的配置,只需要写过滤器工厂的前缀名称(Spring会自动拼接GatewayFilterFactory后缀去查找):
spring.cloud.gateway.default-filters=JwtAuthenticationFilter
解决方案二:使用全局过滤器(无需配置文件)
如果你不想用过滤器工厂模式,也可以把你的过滤器注册为全局过滤器,这样它会自动作用于所有路由,不需要在配置文件中指定:
@Component public class JwtAuthenticationFilter implements GlobalFilter { @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) { if (jwtVerify && isApiSecured.test(exchange.getRequest())) { // 添加你的JWT验证逻辑 } return chain.filter(exchange); } }
这种方式下,你可以删除application.properties中对应的default-filters配置,Spring会自动识别并加载这个全局过滤器。
验证
修改完成后重启项目,Spring就能正确识别你的自定义过滤器,不会再抛出找不到过滤器工厂的错误了。
内容的提问来源于stack exchange,提问作者Dolphin

