Spring WebFlux既支持像Tomcat,Jetty這樣的的傳統容器(前提是支持Servlet 3.1 Non-Blocking IO API),又支持像Netty,Undertow那樣的異步容器。不管是何種容器,Spring WebFlux都會將其輸入輸出流適配成Flux<DataBuffer>格式,以便進行統一處理。
在使用SpringCloud-gateway時,在各個filter里,都有ServerWebExchange對象,exchange里面攜帶着用戶的request,request里帶着用戶請求的數據。

如果是Get請求傳的參數,我們可以直接通過下圖紅框這樣的方式獲取參數的值,但是post請求的值就取不到了。

post的值都封裝在了 Flux<DataBuffer> 對象中,那么我們怎么將它轉為可讀的String呢?
@Component @Slf4j @AllArgsConstructor public class HttpPostBodyFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); String method = request.getMethodValue(); String contentType = request.getHeaders().getFirst("Content-Type"); if ("POST".equals(method) && contentType.startsWith("multipart/form-data")){ return DataBufferUtils.join(exchange.getRequest().getBody()) .flatMap(dataBuffer -> { byte[] bytes = new byte[dataBuffer.readableByteCount()]; dataBuffer.read(bytes); try { String bodyString = new String(bytes, "utf-8"); log.info(bodyString); exchange.getAttributes().put("POST_BODY",bodyString); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } DataBufferUtils.release(dataBuffer); Flux<DataBuffer> cachedFlux = Flux.defer(() -> { DataBuffer buffer = exchange.getResponse().bufferFactory() .wrap(bytes); return Mono.just(buffer); }); ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator( exchange.getRequest()) { @Override public Flux<DataBuffer> getBody() { return cachedFlux; } }; return chain.filter(exchange.mutate().request(mutatedRequest) .build()); }); } return chain.filter(exchange); } @Override public int getOrder() { return -200; } }
這里面就是一種方式,post傳的參數如下

上面代碼處理后的bodyString如下:
![]()
還有一些其他的方式,如
-
AtomicReference<String> bodyRef = new AtomicReference<>();
-
body.subscribe(buffer -> {
-
CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
-
DataBufferUtils.release(buffer);
-
bodyRef. set(charBuffer.toString());
-
});
-
//獲取request body
-
String bodyStr = bodyRef. get();
-
System. out.println(bodyStr);

大家可以去看一下DataBuffer的方法,里面有多個方法可以讀取里面的值。

