I have 2 classes: filter and class to get response body. As far as I know I need to specify order NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER-1 so filter will get response body.
But when I implement Ordered or use annotation @Order or via OrderedGatewayFilter I cann't call BodyRewrite class(which gets response body). When I try to use this for global filter(implemented GlobalFilter) it works fine.
May it be because I extend AbstractNameValueGatewayFilterFactory and I can't specify order for it?
Full code: https://github.com/artem-kurilko/NettyFilter
Jwt filter 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);
}
}
Global filter:
@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 to receive response body:
@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
Output on jwt filter route
Stopped global filter as it is jwt filter route
Post JWTFilter executed
Output on global filter route
got response body: Something
Post GlobalFilter executed
So when I try to call BodyRewrite via JWTFilter it doesn't work, but with global filter it works correctly.
First, you should know GatewayFilter is used for a special route, so that you should bind it to a route.GlobalFilter will take effect for all routes.
And it's redundant that assembling a GatewayFilter with a GatewayFilter.