spring-webflux中Flux 轉String


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如下:

還有一些其他的方式,如

  1.  
    AtomicReference<String> bodyRef = new AtomicReference<>();
  2.  
    body.subscribe(buffer -> {
  3.  
    CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
  4.  
    DataBufferUtils.release(buffer);
  5.  
    bodyRef. set(charBuffer.toString());
  6.  
    });
  7.  
    //獲取request body
  8.  
    String bodyStr = bodyRef. get();
  9.  
    System. out.println(bodyStr);

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM