Spring Cloud Gateway 响应出现中文乱码?
前言:记一次 Gateway 读取响应内容时导致中文乱码。问题还是比较严重的,因为这个问题导致系统全局中文出现偶发性乱码,经过 debug 追踪,最终确认了是在 gateway 获取响应内容重写时出现了问题。场景复现:先看代码,方法的功能是读取响应结果,并记录响应结果。/*** 记录响应日志** @param exchange* @return*/private ServerHttpRespons
·
前言:
记一次 Gateway 读取响应内容时导致中文乱码。
问题还是比较严重的,因为这个问题导致系统全局中文出现偶发性乱码,经过 debug 追踪,最终确认了是在 gateway 获取响应内容重写时出现了问题。
场景复现:
先看代码,方法的功能是读取响应结果,并记录响应结果。
/**
* 记录响应日志
*
* @param exchange
* @return
*/
private ServerHttpResponseDecorator logResponse(ServerWebExchange exchange, LogReq logReq) {
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
// 定义 response
ServerHttpResponseDecorator response = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
// 略...
// 注意:此处切分多次读取将导致问题的出现
dataBuffers.forEach(dataBuffer -> {
try {
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
responseContentList.add(new String(content, StandardCharsets.UTF_8));
} catch (Exception e) {
log.error("加载 Response 字节流异常,失败原因:{}", Throwables.getStackTraceAsString(e));
} finally {
DataBufferUtils.release(dataBuffer);
}
});
// 略...
}
@Override
public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
return writeWith(Flux.from(body).flatMapSequential(p -> p));
}
};
return response;
}
在 dataBuffers 中如果响应过大可能会将字符串分批读取,那么这就存在一个问题,当需要读取的字符串的某个字被切分了,将导致那个字乱码。如:伞兵一号卢本伟,由于是按字节分批读取,假如分成两批,伞兵一号
与 卢本伟
,如果号
字被拆开了,那么将导致号
乱码了。
{
"status": ,
"data": {
"title": "伞兵一��卢本伟"
},
"message": ""
}
解决方案:
做法很明显就是不要分批,通过 DefaultDataBufferFactory 将 dataBuffers 合并为一个再读取,实现如下:
DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
DataBuffer dataBuffer = dataBufferFactory.join(dataBuffers);
try {
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
responseContentList.add(new String(content, StandardCharsets.UTF_8));
} catch (Exception e) {
log.error("加载 Response 字节流异常,失败原因:{}", Throwables.getStackTraceAsString(e));
} finally {
DataBufferUtils.release(dataBuffer);
}
合并完成后再读取,中文乱码解决!!!
{
"status": ,
"data": {
"title": "伞兵一号卢本伟"
},
"message": ""
}
如果此博客有帮助到您,请不要忘记点赞喔~
更多推荐
已为社区贡献5条内容
所有评论(0)