SpringCloud GateWay 网关 在GlobalFilter 拿出返回数据response

简介: SpringCloud GateWay 网关 在GlobalFilter 拿出返回数据response

前言



文章主旨:   将返回数据拿出来,然后各种处理。


正文


 

先看该篇文章的示例接口:


image.png


红色框框里面就是返回的 response 数据 。


现在我们想要的就是 在返回给到调用方(前端、第三方等)前,我们抓出来数据,随便改一下东西。


例如: 我要把里面的message 提示语改了。


新建一个全局过滤器:


WrapperResponseGlobalFilter.java


import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.reactivestreams.Publisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.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.Charset;
import java.util.List;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR;
/**
 * @Author JCccc
 * @Description 拦截返回数据, 修改返回数据
 * @Date 2021/8/16 19:22
 */
@Component
public class WrapperResponseGlobalFilter implements GlobalFilter, Ordered {
    private static final Logger log = LoggerFactory.getLogger(WrapperResponseGlobalFilter.class);
    @Override
    public int getOrder() {
        // -1 is response write filter, must be called before that
        return -2;
    }
    private static Joiner joiner = Joiner.on("");
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpResponse originalResponse = exchange.getResponse();
        DataBufferFactory bufferFactory = originalResponse.bufferFactory();
        ServerHttpResponseDecorator response = new ServerHttpResponseDecorator(originalResponse) {
            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                if (getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) {
                    // 获取ContentType,判断是否返回JSON格式数据
                    String originalResponseContentType = exchange.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR);
                    if (StringUtils.isNotBlank(originalResponseContentType) && originalResponseContentType.contains("application/json")) {
                        Flux<? extends DataBuffer> fluxBody = Flux.from(body);
                        //(返回数据内如果字符串过大,默认会切割)解决返回体分段传输
                        return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
                            List<String> list = Lists.newArrayList();
                            dataBuffers.forEach(dataBuffer -> {
                                try {
                                    byte[] content = new byte[dataBuffer.readableByteCount()];
                                    dataBuffer.read(content);
                                    DataBufferUtils.release(dataBuffer);
                                    list.add(new String(content, "utf-8"));
                                } catch (Exception e) {
                                    log.info("加载Response字节流异常,失败原因:{}", Throwables.getStackTraceAsString(e));
                                }
                            });
                            String responseData = joiner.join(list);
                            System.out.println("responseData:"+responseData);
                            byte[] uppedContent = new String(responseData.getBytes(), Charset.forName("UTF-8")).getBytes();
                            originalResponse.getHeaders().setContentLength(uppedContent.length);
                            return bufferFactory.wrap(uppedContent);
                        }));
                    }
                }
                return super.writeWith(body);
            }
            @Override
            public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
                return writeWith(Flux.from(body).flatMapSequential(p -> p));
            }
        };
        return chain.filter(exchange.mutate().response(response).build());
    }
}


调用接口可以看到,response数据已经被我们拎出来了:


image.png


那么我们简单做个处理,


image.png

    /**
     * 返回数据处理
     *
     * @param responseData
     * @return
     */
    private String responseHandle(String responseData) {
        String responseResultJson = null;
        try {
            JSONObject jsonObject = JSONObject.parseObject(responseData);
            jsonObject.put("message", "JCccc 收藏+关注");
            responseResultJson = jsonObject.toJSONString();
        } catch (Exception e) {
            log.info("返回数据处理转化失败,异常信息={}",e.getMessage());
            return responseData;
        }
        return responseResultJson;
    }


再次请求,可以看到:


返回数据里面的message已经被我们修改成功了


image.png


PS:


还有类似,既然个人信息这么敏感,是不是类似一些接口返回数据需要做统一的加密呢?


如需要,那么也可以通过配置化读取需要加密的ur列表,然后通过exchange把url拿出来做匹对,对responseData  做加密处理。


ServerHttpRequest request = exchange.getRequest();
URI url = request.getURI();
String urlPath = url.getPath();
System.out.println("当前请求url是:"+urlPath);


好了,该篇就到这。

相关文章
|
19天前
|
负载均衡 Java 应用服务中间件
Gateway服务网关
Gateway服务网关
29 1
Gateway服务网关
|
1月前
|
XML Java 数据格式
如何使用 Spring Cloud 实现网关
如何使用 Spring Cloud 实现网关
37 3
|
2月前
|
负载均衡 Java Nacos
SpringCloud基础2——Nacos配置、Feign、Gateway
nacos配置管理、Feign远程调用、Gateway服务网关
SpringCloud基础2——Nacos配置、Feign、Gateway
|
2月前
|
Java 开发者 Spring
Spring Cloud Gateway 中,过滤器的分类有哪些?
Spring Cloud Gateway 中,过滤器的分类有哪些?
63 3
|
2月前
|
负载均衡 Java 网络架构
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
117 5
|
1月前
|
负载均衡 Java API
【Spring Cloud生态】Spring Cloud Gateway基本配置
【Spring Cloud生态】Spring Cloud Gateway基本配置
41 0
|
2月前
|
安全 Java 开发者
强大!Spring Cloud Gateway新特性及高级开发技巧
在微服务架构日益盛行的今天,网关作为微服务架构中的关键组件,承担着路由、安全、监控、限流等多重职责。Spring Cloud Gateway作为新一代的微服务网关,凭借其基于Spring Framework 5、Project Reactor和Spring Boot 2.0的强大技术栈,正逐步成为业界的主流选择。本文将深入探讨Spring Cloud Gateway的新特性及高级开发技巧,助力开发者更好地掌握这一强大的网关工具。
243 6
|
3月前
|
安全 API
【Azure API 管理】APIM Self-Host Gateway 自建本地环境中的网关数量超过10个且它们的出口IP为同一个时出现的429错误
【Azure API 管理】APIM Self-Host Gateway 自建本地环境中的网关数量超过10个且它们的出口IP为同一个时出现的429错误
|
3月前
|
存储 容器
【Azure 事件中心】为应用程序网关(Application Gateway with WAF) 配置诊断日志,发送到事件中心
【Azure 事件中心】为应用程序网关(Application Gateway with WAF) 配置诊断日志,发送到事件中心
|
1月前
|
安全 5G 网络性能优化
下一篇
无影云桌面