Parcourir la source

add 增加 gateway 全局缓存过滤器 解决body不能重复读问题

疯狂的狮子li il y a 4 ans
Parent
commit
ada28231bd

+ 0 - 1
config/dev/ruoyi-gateway.yml

@@ -46,7 +46,6 @@ spring:
             - Path=/auth/**
           filters:
             # 验证码处理
-            - CacheRequestFilter
             - ValidateCodeFilter
             - StripPrefix=1
         # 代码生成

+ 0 - 91
ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/CacheRequestFilter.java

@@ -1,91 +0,0 @@
-package com.ruoyi.gateway.filter;
-
-import org.springframework.cloud.gateway.filter.GatewayFilter;
-import org.springframework.cloud.gateway.filter.GatewayFilterChain;
-import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
-import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
-import org.springframework.core.io.buffer.DataBuffer;
-import org.springframework.core.io.buffer.DataBufferFactory;
-import org.springframework.core.io.buffer.DataBufferUtils;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
-import org.springframework.stereotype.Component;
-import org.springframework.web.server.ServerWebExchange;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * 获取body请求数据(解决流不能重复读取问题)
- *
- * @author ruoyi
- */
-@Component
-public class CacheRequestFilter extends AbstractGatewayFilterFactory<CacheRequestFilter.Config> {
-    public CacheRequestFilter() {
-        super(Config.class);
-    }
-
-    @Override
-    public String name() {
-        return "CacheRequestFilter";
-    }
-
-    @Override
-    public GatewayFilter apply(Config config) {
-        CacheRequestGatewayFilter cacheRequestGatewayFilter = new CacheRequestGatewayFilter();
-        Integer order = config.getOrder();
-        if (order == null) {
-            return cacheRequestGatewayFilter;
-        }
-        return new OrderedGatewayFilter(cacheRequestGatewayFilter, order);
-    }
-
-    public static class CacheRequestGatewayFilter implements GatewayFilter {
-        @Override
-        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
-            // GET DELETE 不过滤
-            HttpMethod method = exchange.getRequest().getMethod();
-            if (method == null || method.matches("GET") || method.matches("DELETE")) {
-                return chain.filter(exchange);
-            }
-            return DataBufferUtils.join(exchange.getRequest().getBody()).map(dataBuffer -> {
-                byte[] bytes = new byte[dataBuffer.readableByteCount()];
-                dataBuffer.read(bytes);
-                DataBufferUtils.release(dataBuffer);
-                return bytes;
-            }).defaultIfEmpty(new byte[0]).flatMap(bytes -> {
-                DataBufferFactory dataBufferFactory = exchange.getResponse().bufferFactory();
-                ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
-                    @Override
-                    public Flux<DataBuffer> getBody() {
-                        if (bytes.length > 0) {
-                            return Flux.just(dataBufferFactory.wrap(bytes));
-                        }
-                        return Flux.empty();
-                    }
-                };
-                return chain.filter(exchange.mutate().request(decorator).build());
-            });
-        }
-    }
-
-    @Override
-    public List<String> shortcutFieldOrder() {
-        return Collections.singletonList("order");
-    }
-
-    static class Config {
-        private Integer order;
-
-        public Integer getOrder() {
-            return order;
-        }
-
-        public void setOrder(Integer order) {
-            this.order = order;
-        }
-    }
-}

+ 39 - 0
ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/GlobalCacheRequestFilter.java

@@ -0,0 +1,39 @@
+package com.ruoyi.gateway.filter;
+
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
+import org.springframework.core.Ordered;
+import org.springframework.http.HttpMethod;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+/**
+ * 全局缓存获取body请求数据(解决流不能重复读取问题)
+ *
+ * @author Lion Li
+ */
+@Component
+public class GlobalCacheRequestFilter implements GlobalFilter, Ordered {
+
+    @Override
+    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+        // GET DELETE 不过滤
+        HttpMethod method = exchange.getRequest().getMethod();
+        if (method == null || method.matches("GET") || method.matches("DELETE")) {
+            return chain.filter(exchange);
+        }
+        return ServerWebExchangeUtils.cacheRequestBodyAndRequest(exchange, (serverHttpRequest) -> {
+            if (serverHttpRequest == exchange.getRequest()) {
+                return chain.filter(exchange);
+            }
+            return chain.filter(exchange.mutate().request(serverHttpRequest).build());
+        });
+    }
+
+    @Override
+    public int getOrder() {
+        return 0;
+    }
+}