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是多余的。
我有 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是多余的。