spring-cloud / spring-cloud/spring-cloud-gateway
Read resposeBody
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 4.9k
- Forks
- 3.5k
- Avg merge
- 20h 57m
- Merged PRs (30d)
- 8
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);
}
};
}
}`
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No repository file or test is named. Start by tracing the GlobalFilter and ServerHttpResponseDecorator example, especially writeWith and the response-body buffering behavior, then determine whether the framework should define a supported access path. Done would require an agreed scope and tests for the standardized response-body behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring, spring-boot
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100