AbstractNameValueGatewayFilterFactory中的@Order不起作用

问题描述

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

但是当我实现Ordered或使用批注@Order或通过OrderedGatewayFilter时,我无法调用BodyRewrite类(获取响应主体)。当我尝试将其用于全局过滤器(已实现的GlobalFilter)时,效果很好。

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

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

Jwt过滤器类:

@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,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,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;
    }
}

要接收响应正文的类:

@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用于特殊路由,因此应将其绑定到路由。GlobalFilter将对所有路由生效。

将GatewayFilter与GatewayFilter组装起来是多余的。