You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring RestTemplate带Header调用接口返回乱码,求解决方案

解决RestTemplate exchange方法返回乱码(getForObject正常)的问题

我碰到过几乎一模一样的情况,你的问题大概率不是单纯的UTF-8编码问题,而是服务端返回了压缩后的响应,但你的RestTemplate没配置解压处理!

为什么会出现这种差异?

你用getForObject能拿到正常结果,是因为RestTemplate的默认请求逻辑会自动添加Accept-Encoding请求头,服务端收到后返回未压缩的明文;而你自定义请求头时漏掉了这个字段,服务端直接返回了gzip/deflate格式的二进制压缩数据,StringHttpMessageConverter把二进制字节当成普通字符串解析,自然就变成一堆乱码了。

先做个简单验证

调用接口后,打印或查看响应的Content-Encoding头字段,如果值是gzip或者deflate,那就100%确认是压缩的问题。

两种可行解决方案

方式一:用HttpClient请求工厂(推荐)

HttpClient会自动处理压缩响应,不需要手动写解压逻辑,步骤很简单:

  1. 先引入HttpClient依赖(Maven示例):
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.14</version> <!-- 替换成最新稳定版即可 -->
</dependency>
  1. 配置RestTemplate并修改请求头:
// 创建HttpClient请求工厂
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
RestTemplate restTemplate = new RestTemplate(requestFactory);

// 更新你的请求头方法,添加支持压缩的字段
private MultiValueMap<String, String> getHeadersInfo(HttpServletRequest request) {
    MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
    map.put("Accept", Arrays.asList("text/plain, application/json, application/*+json, */*"));
    map.put("Content-Type", Arrays.asList("application/json; charset=UTF-8"));
    // 关键:告诉服务端你支持压缩响应
    map.put("Accept-Encoding", Arrays.asList("gzip, deflate"));
    return map;
}

// 正常调用exchange方法即可
HttpEntity<String> entity = new HttpEntity<>(body, getHeadersInfo(request));
ResponseEntity<String> responseEntity = restTemplate.exchange(uri, request.getMethod(), entity, String.class);

方式二:手动添加Gzip消息转换器

如果不想引入额外依赖,可以给RestTemplate添加GzipHttpMessageConverter来处理解压:

RestTemplate restTemplate1 = new RestTemplate();
// 先添加Gzip转换器,确保它优先处理解压操作
restTemplate1.getMessageConverters().add(0, new GzipHttpMessageConverter());
// 再添加UTF-8的字符串转换器
restTemplate1.getMessageConverters().add(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));

// 同样要在请求头里加上Accept-Encoding
MultiValueMap<String, String> headers = getHeadersInfo(request);
headers.put("Accept-Encoding", Arrays.asList("gzip, deflate"));

HttpEntity<String> entity = new HttpEntity<>(body, headers);
ResponseEntity<String> responseEntity = restTemplate1.exchange(uri, request.getMethod(), entity, String.class);

额外提醒

  • 别重复添加相同类型的消息转换器,容易导致逻辑冲突;
  • 如果服务端强制返回压缩内容(不管你有没有加Accept-Encoding),那必须配置解压逻辑;
  • 可以通过responseEntity.getHeaders()打印响应头,辅助排查问题。

内容的提问来源于stack exchange,提问作者Popeye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:13:23