问题描述
使用 FastJsonHttpMessageConverter 解析gizp压缩的http响应,抛出RestClientException: Error while extracting response for type [***] and content type [application/json;charset=utf-8]。
根本原因:响应使用了 gzip 压缩,但 HTTP 客户端直接使用 Content-Length (364字节,gzip压缩后的大小), 2.0.60版本的fastjson,在FastJsonHttpMessageConverter的fastRead方法中,由于前端传了364个byte,因此它只读取了364位,实际body大小为压缩之前的(600字节),导致body内容残缺。
FastJsonHttpMessageConverter 85行
protected static byte[] fastRead(InputStream in, long contentLength) throws IOException {
int expectSize = calcInitialCapacity(contentLength); //由于压缩的原因,contentLength长度小于body真实长度
byte[] body = new byte[expectSize];
int offset = in.read(body, 0, body.length);
环境信息
- OS信息: windows11
- JDK信息: Openjdk 21
- 版本信息:Fastjson2 2.0.60
重现步骤
1、使用 FastJsonHttpMessageConverter 解析gizp压缩的http响应
2、远程服务返回的响应头包含 Content-Length: 压缩长度 和 content-encoding: gzip
3、JSON 解析器无法解析 gzip 压缩数据,抛出反序列化异常
期待的正确结果
HTTP 客户端应根据 content-encoding: gzip 判断响应被压缩,先解压再将原始 JSON 数据交给解析器。
相关日志输出
org.springframework.web.client.RestClientException: Error while extracting response for type [***] and content type [application/json;charset=utf-8]
附加信息
需要检查调用的 HTTP 客户端是否配置了 gzip 解压拦截器,以及解压时机是否在 JSON 解析之前。
2.0.58版本是初始化了一个大的buffer对象,然后去读取请求中的内容,因此没有该问题;
问题描述
使用 FastJsonHttpMessageConverter 解析gizp压缩的http响应,抛出RestClientException: Error while extracting response for type [***] and content type [application/json;charset=utf-8]。
根本原因:响应使用了 gzip 压缩,但 HTTP 客户端直接使用 Content-Length (364字节,gzip压缩后的大小), 2.0.60版本的fastjson,在FastJsonHttpMessageConverter的fastRead方法中,由于前端传了364个byte,因此它只读取了364位,实际body大小为压缩之前的(600字节),导致body内容残缺。
FastJsonHttpMessageConverter 85行
protected static byte[] fastRead(InputStream in, long contentLength) throws IOException {
int expectSize = calcInitialCapacity(contentLength); //由于压缩的原因,contentLength长度小于body真实长度
byte[] body = new byte[expectSize];
int offset = in.read(body, 0, body.length);
环境信息
重现步骤
1、使用 FastJsonHttpMessageConverter 解析gizp压缩的http响应
2、远程服务返回的响应头包含 Content-Length: 压缩长度 和 content-encoding: gzip
3、JSON 解析器无法解析 gzip 压缩数据,抛出反序列化异常
期待的正确结果
HTTP 客户端应根据 content-encoding: gzip 判断响应被压缩,先解压再将原始 JSON 数据交给解析器。
相关日志输出
org.springframework.web.client.RestClientException: Error while extracting response for type [***] and content type [application/json;charset=utf-8]
附加信息
需要检查调用的 HTTP 客户端是否配置了 gzip 解压拦截器,以及解压时机是否在 JSON 解析之前。
2.0.58版本是初始化了一个大的buffer对象,然后去读取请求中的内容,因此没有该问题;