|
@@ -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;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|