在spring cloud gateway出现这个问题的时候我们第一反应应该很简单,但是真正实现的时候却有点困难。我看了很多相关的文档,感觉太多都不清晰而且解决不了问题。下面我就把我的方便理解的解决方案写下来。
1. 先重写请求体(过滤器优先级一定要在要获取body之前执行)
这个全局过滤器的目的就是把原有的request请求中的body内容读出来(原有的body都是以流的形式被传递),并且使用ServerHttpRequestDecorator这个请求装饰器对request进行包装,重写getBody方法,并把包装后的请求放到过滤器链中传递下去。可以满足多次获取请求。
// 重写请求体
@Component
public class GetBodyGlobalFilter implements Ordered, GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
if (exchange.getRequest().getHeaders().getContentType() == null && !HttpMethod.POST.name().equalsIgnoreCase(method)) {
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;
}
};
return chain.filter(exchange.mutate().request(mutatedRequest).build());
});
}
}
@Override
public int getOrder() {
return -2;
}
}
2.写出具体的实现逻辑,及获取请求体
// 过滤器请求逻辑
@Component
public class GatewayGlobalFilter implements Ordered, GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest httpRequest = exchange.getRequest();
// 获取请求体
Flux<DataBuffer> body = httpRequest.getBody();
AtomicReference<String> bodyRef = new AtomicReference<>();
body.subscribe(buffer -> {
CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
DataBufferUtils.release(buffer);
bodyRef.set(charBuffer.toString());
});
String body = bodyRef.get();
// 打印请求体
System.out.print(body);
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1;
}
}
经过多方面的查看资料得出以上两个步骤就能完美的解决gateway过滤器中获取请求体的方案。文章来源:https://www.toymoban.com/news/detail-594859.html
总结:先把请求体从流的方式读取出来,然后再往下进行传递,避免在处理业务的时候出现请求题为空的情况。文章来源地址https://www.toymoban.com/news/detail-594859.html
到了这里,关于从Spring Cloud Gateway过滤器中获取请求体的最优方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!