问题描述
我有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组装起来是多余的。