AbstractNameValueGatewayFilterFactory 中的@Order 不起作用

@Order in AbstractNameValueGatewayFilterFactory doesn't work

我有 2 个 classes: 过滤器和 class 来获取响应正文。据我所知,我需要指定顺序 NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER-1 以便过滤器将获得响应正文。

但是当我实现 Ordered 或使用注释 @Order 或通过 OrderedGatewayFilter 时,我无法调用 BodyRewrite class(它获取响应主体)。当我尝试将它用于全局过滤器(已实现的 GlobalFilter)时,它工作正常。

可能是因为我扩展了 AbstractNameValueGatewayFilterFactory 而我无法为其指定顺序?

完整代码:https://github.com/artem-kurilko/NettyFilter

Jwt过滤器class:

@Component
public class JWTFilter extends AbstractNameValueGatewayFilterFactory {
    private final ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory;
    private final BodyRewrite bodyRewrite;

    @Autowired
    public JWTFilter(ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory, BodyRewrite bodyRewrite, ErrorWebExceptionHandler errorWebExceptionHandler) {
        this.modifyResponseBodyGatewayFilterFactory = modifyResponseBodyGatewayFilterFactory;
        this.bodyRewrite = bodyRewrite;
    }

    @Override
    public GatewayFilter apply(NameValueConfig config) {
        System.out.println("\n          JWT FILTER\n");

        return new OrderedGatewayFilter((exchange, chain) -> {
            GatewayFilter delegate = modifyResponseBodyGatewayFilterFactory.apply(new ModifyResponseBodyGatewayFilterFactory.Config()
                    .setRewriteFunction(byte[].class, byte[].class, bodyRewrite));
            return delegate.filter(exchange, chain).then(Mono.fromRunnable(() -> System.out.println("\nPost JWTFilter executed\n")));
        }, NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER-1);
    }

}

全局过滤器:

@Component
public class ModifyResponseBodyFilter implements GlobalFilter, Ordered {
    private final ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory;
    private final BodyRewrite bodyRewrite;

    @Autowired
    public ModifyResponseBodyFilter(ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory, BodyRewrite bodyRewrite, ErrorWebExceptionHandler errorWebExceptionHandler) {
        this.modifyResponseBodyGatewayFilterFactory = modifyResponseBodyGatewayFilterFactory;
        this.bodyRewrite = bodyRewrite;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        if (exchange.getRequest().getURI().getPath().equals("/key/login")) {
            return exchange.getResponse().setComplete();
        }

        GatewayFilter delegate=modifyResponseBodyGatewayFilterFactory.apply(new ModifyResponseBodyGatewayFilterFactory.Config()
                .setRewriteFunction(byte[].class, byte[].class, bodyRewrite));
        return delegate.filter(exchange, chain).then(Mono.fromRunnable(() -> System.out.println("\nPost GlobalFilter executed\n")));
    }

    @Override
    public int getOrder() {
        return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER-1;
    }
}

Class接收响应正文:

@Component
class BodyRewrite implements RewriteFunction<byte[], byte[]> {

    @Override
    public Publisher<byte[]> apply(ServerWebExchange exchange, byte[] body) {
        String originalBody = body==null?"":new String(body);
        if (!ServerWebExchangeUtils.isAlreadyRouted(exchange)) {
            return Mono.just(originalBody.getBytes());
        } else {
            System.out.println("------------------------------------");
            System.out.println("got response body: " + originalBody);
            System.out.println("------------------------------------");

            return Mono.just(body);
        }
    }

}

application.yml

spring:
  cloud:
    gateway:
      routes:
        - id: global_route
          uri: http://httbin.org
          predicates:
            - Path=/key/login
          filters:
            - JWTFilter=RSA512,HS512
        - id: global_route
          uri: http://httbin.org
          predicates:
            - Path=/**
          filters:
            - RewritePath=/service(?<segment>/?.*), $\{segment}
server:
  port: 8082

在 jwt 过滤路由上输出

Stopped global filter as it is jwt filter route

Post JWTFilter executed

全局过滤路由输出

got response body: Something

Post GlobalFilter executed

所以当我尝试通过 JWTFilter 调用 BodyRewrite 时它不起作用,但是使用全局过滤器它可以正常工作。

首先,你应该知道GatewayFilter是针对特殊路由使用的,所以绑定到一个route.GlobalFilter会对所有路由生效

并且用GatewayFilter组装GatewayFilter是多余的。