Просмотр исходного кода

data-service 中添加获取 request body 的 GetRequestBodyFilter

reghao 8 месяцев назад
Родитель
Сommit
3672f76176

+ 79 - 0
data/data-service/src/main/java/cn/reghao/tnb/data/app/filter/GetRequestBodyFilter.java

@@ -0,0 +1,79 @@
+package cn.reghao.tnb.data.app.filter;
+
+import io.netty.buffer.ByteBufAllocator;
+import org.springframework.core.Ordered;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.core.io.buffer.DataBufferUtils;
+import org.springframework.core.io.buffer.NettyDataBufferFactory;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.WebFilter;
+import org.springframework.web.server.WebFilterChain;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.net.URI;
+import java.nio.CharBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * @author reghao
+ * @date 2025-07-18 15:26:51
+ */
+public class GetRequestBodyFilter implements WebFilter, Ordered {
+    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
+        ServerHttpRequest serverHttpRequest = exchange.getRequest();
+        String method = serverHttpRequest.getMethodValue();
+        //从请求里获取Post请求体
+        String bodyStr = resolveBodyFromRequest(serverHttpRequest);
+
+        //下面的将请求体再次封装写回到request里,传到下一级,否则,由于请求体已被消费,后续的服务将取不到值
+        URI uri = serverHttpRequest.getURI();
+        ServerHttpRequest request = serverHttpRequest.mutate().uri(uri).build();
+        DataBuffer bodyDataBuffer = stringBuffer(bodyStr);
+        Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);
+
+        request = new ServerHttpRequestDecorator(request) {
+            public Flux<DataBuffer> getBody() {
+                return bodyFlux;
+            }
+        };
+        ServerWebExchange newExchange = exchange.mutate().request(request).build();
+        newExchange.getAttributes().put("bodyCache",bodyStr);
+        //封装request,传给下一级
+        return chain.filter(newExchange);
+    }
+
+    /**
+     * 从Flux<DataBuffer>中获取字符串的方法
+     *
+     * @return 请求体
+     */
+    private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {
+        //获取请求体
+        Flux<DataBuffer> body = serverHttpRequest.getBody();
+
+        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
+        return bodyRef.get();
+    }
+
+    private DataBuffer stringBuffer(String value) {
+        byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
+        NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
+        DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
+        buffer.write(bytes);
+        return buffer;
+    }
+
+    public int getOrder() {
+        return 0;
+    }
+}