Skip to content

Read resposeBody #3941

@cardocha

Description

@cardocha

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);
        }
    };
}

}`

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions