【SpringCloudGateway】SpringCloudGateway修改响应数据

一.背景

  项目中的微服务使用了MDC在网关侧生成了请求链路ID,将链路ID传递到下游微服务中,然后需要将该链路ID写入到Gateway的响应中,作为本次客户端本地请求的标识

二.想法

  通过自定义全局过滤器来实现对Gateway响应数据的修改,添加链路ID(trackId)返回给客户端

三.实现

  
/**
 * @version 1.0
 * @author: Sam.yang
 * @DATE: 2020-12-26 16:06
 */
@Slf4j
@Component
public class ResponseFilter extends AbstractFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("开始进入Gateway.ResponseFilter");
        ServerHttpResponse originalResponse = exchange.getResponse();
        String trackId = MDC.get(HeaderParamUtil.TRACKID);
        ServerHttpResponseDecorator responseDecorated = new ServerHttpResponseDecorator(originalResponse) {
            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                if (body instanceof Flux) {
                    Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;
                    return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
                        DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
                        DataBuffer join = dataBufferFactory.join(dataBuffers);
                        byte[] content = new byte[join.readableByteCount()];
                        join.read(content);
                        DataBufferUtils.release(join);// 释放掉内存
                        String bodyStr = new String(content, Charset.forName("UTF-8"));
                        try {
                            if (JSONUtil.isJson(bodyStr)) {
                                JSONObject jsonObject = JSON.parseObject(bodyStr);
                                jsonObject.put(HeaderParamUtil.TRACKID, trackId);
                                bodyStr = JSON.toJSONString(jsonObject, SerializerFeature.WriteMapNullValue);
                            }
                        } catch (Exception e) {
                            log.error("Gateway.ResponseFilter=>响应新增trackId异常,bodyStr:{}", bodyStr);
                        }
                        log.debug("Gateway.ResponseFilter.Response:{}", bodyStr);
                        getDelegate().getHeaders().setContentLength(bodyStr.getBytes().length);
                        return bufferFactory().wrap(bodyStr.getBytes());
                    }));
                }
                return super.writeWith(body);
            }
        };
        return chain.filter(exchange.mutate().response(responseDecorated).build());
    }

    public int getOrder() {
    return GatewayFilterOrderConstant.API_RESPONSE_FILTER;
    }
}

  注意 拦截器的顺序  GatewayFilterOrderConstant.API_RESPONSE_FILTER 必须要在 
   [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@7e017f47}, order = -1]拦截器之前
  否则不生效

posted @ 2023-12-23 17:33  听风是雨  阅读(844)  评论(0)    收藏  举报
/* 看板娘 */