记一次springcloud gateway记录日志响应结果乱码问题
记一次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组装电脑配置单推荐报价格
推荐阅读
留言与评论(共有 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 |