@Slf4j
@Component
public class CacheBodyGatewayFilter implements Ordered, GlobalFilter {
public static final String CACHE_REQUEST_BODY_OBJECT_KEY = "cachedRequestBodyObject";
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
if (exchange.getRequest().getHeaders().getContentType() == null ||
isFile(exchange.getRequest().getHeaders().getContentType()) ||
HttpMethod.GET.name().equalsIgnoreCase(exchange.getRequest().getMethodValue())) {
return chain.filter(exchange);
} else {
return DataBufferUtils.join(exchange.getRequest().getBody())
.flatMap(dataBuffer -> {
DataBufferUtils.retain(dataBuffer);
Flux<DataBuffer> cachedFlux = Flux
.defer(() -> Flux.just(dataBuffer.slice(0, dataBuffer.readableByteCount())));
ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody() {
return cachedFlux;
}
};
exchange.getAttributes().put(CACHE_REQUEST_BODY_OBJECT_KEY, cachedFlux);
return chain.filter(exchange.mutate().request(mutatedRequest).build());
});
}
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
private Boolean isFile(MediaType content) {
if (null == content) {
return Boolean.FALSE;
}
log.info("---------CacheBodyGatewayFilter.isFile(), contentType:{}", content);
return MediaType.MULTIPART_FORM_DATA.getType().equals(content.getType())
|| MediaType.MULTIPART_MIXED.getType().equals(content.getType())
|| MediaType.MULTIPART_RELATED.getType().equals(content.getType())
|| MediaType.IMAGE_GIF.getType().equals(content.getType())
|| MediaType.IMAGE_JPEG.getType().equals(content.getType())
|| MediaType.IMAGE_PNG.getType().equals(content.getType());
}
}