-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Open
Labels
Description
Why isn't there a standardized and simple way to access the responseBody of a response from a GlobalFilter? .
I want to log the responseBody but using ServerHttpResponseDecorator the order logic is not executed properly.
Is this related to the framework's responsibilities? Something like: the gateway shouldn't have access to the response body.
`
@component
@slf4j
public class GlobalPostLoggingFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return doFilter(exchange, chain);
}
@Override
public int getOrder() {
return 4;
}
private Mono<Void> doFilter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpResponse response = exchange.getResponse();
DataBufferFactory dataBufferFactory = response.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = getDecoratedResponse(response, dataBufferFactory);
return chain.filter(exchange.mutate().response(decoratedResponse).build())
.doOnSuccess(s -> {
MDC.put("responseCookies", responseCookies(exchange));
MDC.put("responseStatus", responseStatus(exchange));
MDC.put("responseHeaders", responseHeaders(exchange));
log.info("Sucesso ao executar Gateway forwarding.");
})
.doFinally(s -> MDC.clear());
}
private ServerHttpResponseDecorator getDecoratedResponse(ServerHttpResponse response,
DataBufferFactory dataBufferFactory) {
return new ServerHttpResponseDecorator(response) {
@Override
public Mono<Void> writeWith(final Publisher<? extends DataBuffer> body) {
if (body instanceof Flux) {
Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
DefaultDataBuffer joinedBuffers = new DefaultDataBufferFactory().join(dataBuffers);
byte[] content = new byte[joinedBuffers.readableByteCount()];
joinedBuffers.read(content);
String responseBody = new String(content, StandardCharsets.UTF_8);
MDC.put("responseBody", responseBody);
return dataBufferFactory.wrap(responseBody.getBytes());
}));
}
return super.writeWith(body);
}
};
}
}`