Quellcode durchsuchen

后置返回过滤器

mac vor 2 Jahren
Ursprung
Commit
c091ba9d64
1 geänderte Dateien mit 115 neuen und 0 gelöschten Zeilen
  1. 115 0
      kxs-gateway/src/main/java/com/kxs/gateway/api/filter/ResponseFilter.java

+ 115 - 0
kxs-gateway/src/main/java/com/kxs/gateway/api/filter/ResponseFilter.java

@@ -0,0 +1,115 @@
+package com.kxs.gateway.api.filter;
+
+import cn.hutool.core.util.StrUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jetbrains.annotations.NotNull;
+import org.reactivestreams.Publisher;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.core.Ordered;
+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.HttpStatus;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR;
+
+/**
+ * 响应过滤器
+ *
+ * @author 没秃顶的码农
+ * @date 2024-04-30
+ */
+@Component
+@Slf4j
+public class ResponseFilter implements GlobalFilter, Ordered {
+
+    @Override
+    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+
+        ServerHttpRequest request = exchange.getRequest();
+        String path = request.getURI().getPath();
+
+        ServerHttpResponse originalResponse = exchange.getResponse();
+
+        DataBufferFactory bufferFactory = originalResponse.bufferFactory();
+
+        ServerHttpResponseDecorator response = new ServerHttpResponseDecorator(originalResponse) {
+            @NotNull
+            @Override
+            public Mono<Void> writeWith(@NotNull Publisher<? extends DataBuffer> body) {
+                if (Objects.equals(getStatusCode(), HttpStatus.OK) && body instanceof Flux) {
+                    // 获取ContentType,判断是否返回JSON格式数据
+
+                    String originalResponseContentType = exchange.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR);
+
+                    if (StrUtil.isNotBlank(originalResponseContentType) && originalResponseContentType.contains("application/json")) {
+                        Flux<? extends DataBuffer> fluxBody = Flux.from(body);
+
+                        //(返回数据内如果字符串过大,默认会切割)解决返回体分段传输
+                        return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
+                            List<String> list = new ArrayList<>();
+
+                            dataBuffers.forEach(dataBuffer -> {
+                                try {
+                                    byte[] content = new byte[dataBuffer.readableByteCount()];
+
+                                    dataBuffer.read(content);
+
+                                    DataBufferUtils.release(dataBuffer);
+
+                                    list.add(new String(content, StandardCharsets.UTF_8));
+
+                                } catch (Exception e) {
+                                    log.error("加载Response字节流异常,失败原因:{} ", e.getMessage(), e);
+                                }
+
+                            });
+
+                            String responseData = String.join("", list);;
+
+                            log.info("responseData:" + responseData);
+
+                            byte[] uppedContent = new String(responseData.getBytes(), StandardCharsets.UTF_8).getBytes();
+
+                            originalResponse.getHeaders().setContentLength(uppedContent.length);
+
+                            return bufferFactory.wrap(uppedContent);
+
+                        }));
+                    }
+
+                }
+                return super.writeWith(body);
+            }
+
+            @NotNull
+            @Override
+            public Mono<Void> writeAndFlushWith(@NotNull Publisher<? extends Publisher<? extends DataBuffer>> body) {
+                return writeWith(Flux.from(body).flatMapSequential(p -> p));
+
+            }
+
+        };
+        return chain.filter(exchange.mutate().response(response).build());
+
+    }
+
+
+    @Override
+    public int getOrder() {
+        return -1;
+    }
+}