I have a need of capturing the request payloads of every request for auditing purpose, However I am unable to fetch the request body at the GlobalFilter level using the ServerWebExchange object provided.
The following is a snip of my code and have attempted 2 ways based on older questions raised here, Any reference or sample code will be appreciated :
Note : For the second comment block, have attempted the caching of the body via another GlobalFilter
application.yml
spring:
cloud:
gateway:
routes:
- id: service1
uri: http://localhost:8081/
predicates:
- Path=/service1/**
filters:
- CachingRequestBodyFilter
- id: service2
uri: http://localhost:8082/
predicates:
- Path=/service2/**
filters:
- CachingRequestBodyFilter
GlobalFilter
public class PreGlobalFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
HttpHeaders httpHeaders = exchange.getRequest().getHeaders();
// ServerWebExchange serverWebExchange = exchange;
//
// try {
// ByteBuffer byteBuffer = Mono.from(serverWebExchange.getRequest().getBody())
// .toFuture().get().asByteBuffer();
// byte[] bytes = new byte[byteBuffer.capacity()];
// while (byteBuffer.hasRemaining())
// byteBuffer.get(bytes);
// System.out.println(new String(bytes, Charset.forName("UTF-8")));
// }
// catch (Exception e) {
// log.error(e.getStackTrace().toString());
// }
// try {
// StringBuilder cachedBody = new StringBuilder();
// Object cachedBodyAttribute = exchange
// .getAttribute(ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR);
// if (!(cachedBodyAttribute instanceof DataBuffer)) {
// log.error("cachedBodyAttribute is null");
// }
// DataBuffer dataBuffer = (DataBuffer) cachedBodyAttribute;
// cachedBody.append(
// StandardCharsets.UTF_8.decode(dataBuffer.asByteBuffer()).toString());
// String bodyAsJson = cachedBody.toString();
// log.info("body : " + bodyAsJson);
// }
// catch (Exception e) {
// log.error(e.toString());
// }
return chain.filter(exchange);
}
}
CachingRequestBodyFilter
public class CachingRequestBodyFilter
extends AbstractGatewayFilterFactory<CachingRequestBodyFilter.Config> {
public CachingRequestBodyFilter() {
super(Config.class);
}
public static class Config {
}
public GatewayFilter apply(final Config config) {
return (exchange, chain) -> ServerWebExchangeUtils.cacheRequestBody(exchange,
(serverHttpRequest) -> chain
.filter(exchange.mutate().request(serverHttpRequest).build()));
}
}
question from:
https://stackoverflow.com/questions/65937968/fetching-request-body-at-global-filters-using-spring-cloud-gateway 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…