您现在的位置是:首页 > 编程 > 

记一次springcloud gateway记录日志响应结果乱码问题

2025-07-23 07:51:30
记一次springcloud gateway记录日志响应结果乱码问题 01、前言最近团队的网关日志发现有不少响应结果记录,出现形如下的乱码代码语言:javascript代码运行次数:0运行复制 �V*.I,IU�JK�)�Q�M-.L�^�m�?��(�钍/�,}�����]O7L|���ŲƧ�MϦnP�Q*K�)*�+���QJ-*�/r�O���{�@8� ��一开始感觉是不是中文乱码,但

记一次springcloud gateway记录日志响应结果乱码问题

01、前言

最近团队的网关日志发现有不少响应结果记录,出现形如下的乱码

代码语言:javascript代码运行次数:0运行复制
 �V*.I,IU�JK�)�Q�M-.L�^�m�?��(�钍/�,}�����]O7L|���ŲƧ�MϦnP�Q*K�)*�+���QJ-*�/r�O���{�@8� ��

一开始感觉是不是中文乱码,但是后面发现有些日志不是中文,也是乱码,而有些记录的日志又能正常显示。于是搜索了一圈,在

在这篇文章到的思路以及解决答案。

02、如何解决

根据上面博文介绍是因为请求的headers中加了有"Accept-Encoding"属性,值为"gzip, deflate, br",导致响应结果乱码。解决思路就是将Accept-Encoding置为空“”就可以解决,按他的思路,我就写了一个过滤器

代码语言:javascript代码运行次数:0运行复制
@RequiredArgsCtructor
public class RemoveGzipHeaderGlobalFilter implements Ordered, GlobalFilter {

    private final GwCommonProperty gwCommonProperty;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        if (isSkipRemoveGzipHeaderEnabled(exchange)) {
            return chain.filter(exchange);
        } else {
            ServerHttpRequest request = exchange.getRequest().mutate()
                    .header(HttpHeaders.ACCEPT_ECODIG, "").build();
            return chain.filter(().request(request).build());

        }
    }

    private boolean isSkipRemoveGzipHeaderEnabled(ServerWebExchange exchange){
        if(!gwCommonProperty.isRemoveGzipHeaderEnabled()){
            return true;
        }
        String gzipHeader = exchange.getRequest().getHeaders().getFirst(HttpHeaders.ACCEPT_ECODIG);

        if(!StringUtils.hasText(gzipHeader)){
            return true;
        }
        return !("gzip");

    }

@Override
public int getOrder() {
    return Ordered.HIGHEST_PRECEDECE;
    }
}

后面果然不再出现乱码。既然是Accept-Encoding引起的乱码问题,我们就来聊下Accept-Encoding

Accept-Encoding

1、常见编码方式:

gzip: 使用 Lempel-Ziv 编码(LZ77)和 Huffman 编码进行压缩的算法。 deflate: 使用 zlib 库和 deflate 压缩算法进行压缩。 br(Brotli): Google 开发的一种新的数据压缩算法,旨在提供比 gzip 和 deflate 更高的压缩率。

2、字段格式:

Accept-Encoding 字段的值是一个由逗号分隔的列表,其中包含了客户端支持的内容编码方式。例如:Accept-Encoding: gzip, deflate, br

、工作流程:

客户端在发送 HTTP 请求时,会在请求头部中包含 Accept-Encoding 字段,列出它支持的内容编码方式。

服务器在收到请求后,会检查 Accept-Encoding 字段,并根据客户端支持的内容编码方式来选择合适的压缩算法来压缩响应数据。

如果服务器选择了一种内容编码方式,它会在响应头部的 Content-Encoding 字段中指定所使用的编码方式。

0、网关日志记录响应结果乱码原因

介绍完Accept-Encoding,我们继续探讨一下为啥Accept-Encoding会引起网关日志响应结果乱码,因为设置了Accept-Encoding: gzip,deflate,所以服务器就会根据客户端支持的内容编码方式来选择合适的压缩算法来压缩响应,而网关层数据没对数据进行解压缩,因此就乱码

因此解决乱码的思路理论上会有2种,一种是上述博文介绍的,去掉Accept-Encoding: gzip,deflate这个头信息。去掉这个头信息就是告诉服务器,客户端不支持压缩,要求不压缩直接返回数据

另外一种思路是如果服务器选择了一种内容编码方式,它会在响应头部的 Content-Encoding 字段中指定所使用的编码方式。因此我们就可以根据Content-Encoding来判断是否要对数据进行解压缩

网关日志记录过滤器核心改造的示例如下

代码语言:javascript代码运行次数:0运行复制
/**
     * 记录响应日志
     * 通过 DataBufferFactory 解决响应体分段传输问题。
     */
  private ServerHttpRespeDecorator recordRespeLog(ServerWebExchange exchange, AccessLog accessLog) {
        ServerHttpRespe respe = exchange.getRespe();
        DataBufferFactory bufferFactory = respe.bufferFactory();
        return new ServerHttpRespeDecorator(respe) {
            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                if (body instanceof Flux) {
                    LogUtils.setRepe(accessLog,exchange);
                    Flux<? extends DataBuffer> fluxBody = Flux.from(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);


                    content = isGzip(respe) ? gzipMessageBodyResolver.decode(content) : content;

                    // 释放掉内存
                    DataBufferUtils.release(join);
                    String respeResult = new String(content, StandardCharsets.UTF_8);

                    accessLog.setRespeData(respeResult);

                        return bufferFactory.wrap(content);
                    }));
                    }
                // if body is not a flux. never got there.
                return super.writeWith(body);
            }
        };
    }



    public boolean isGzip(ServerHttpRespe serverHttpRespe) {
        HttpHeaders headers = serverHttpRespe.getHeaders();
        if ((HttpHeaders.COTET_ECODIG)) {
            List<String> encodingList = headers.get(HttpHeaders.COTET_ECODIG);
            return CollectionUtil.isotEmpty(encodingList) && (GZIP);
        }
        return false;
    }

注: 特别提醒,因为要获取服务端header响应Content-Encoding,用的是ServerHttpRespe,而不是ServerHttpRequest

04、总结

综上解决因Accept-Encoding引起的乱码方式有2种,一种是直接移除Accept-Encoding,告诉服务端不要对响应数据进行压缩,直接返回未压缩数据。另外一种如果不移除Accept-Encoding,就得根据Content-Encoding来对服务端响应的数据进行解压缩

本文参与 腾讯云自媒体同步曝光计划,分享自。原始发表:2025-01-18,如有侵权请联系 cloudcommunity@tencent 删除gateway乱码日志数据压缩

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1166886.html

相关标签:无
上传时间: 2025-07-21 04:18:28
留言与评论(共有 18 条评论)
本站网友 酒仙桥租房
26分钟前 发表
值为"gzip
本站网友 蝶双飞
4分钟前 发表
因此就乱码因此解决乱码的思路理论上会有2种
本站网友 胡继晔
24分钟前 发表
网关日志记录响应结果乱码原因介绍完Accept-Encoding
本站网友 vob格式转换
0秒前 发表
列出它支持的内容编码方式
本站网友 哈尔滨妇产医院
12分钟前 发表
在在这篇文章到的思路以及解决答案
本站网友 固始租房
18分钟前 发表
所以服务器就会根据客户端支持的内容编码方式来选择合适的压缩算法来压缩响应
本站网友 腾讯中奖
16分钟前 发表
服务器在收到请求后
本站网友 53iii
9分钟前 发表
分享自
本站网友 复方利血平片
28分钟前 发表
直接返回未压缩数据
本站网友 头肩底图形
13分钟前 发表
例如:Accept-Encoding
本站网友 大脑结构图
20分钟前 发表
一种是直接移除Accept-Encoding
本站网友 财迷王爷败金妃
26分钟前 发表
deflate: 使用 zlib 库和 deflate 压缩算法进行压缩
本站网友 casio计算器
2分钟前 发表
如果服务器选择了一种内容编码方式
本站网友 果蝇幼虫
11分钟前 发表
客户端不支持压缩
本站网友 媒体峰会
13分钟前 发表
deflate
本站网友 伊利最新事件
21分钟前 发表
例如:Accept-Encoding
本站网友 双系统安装
20分钟前 发表
deflate