Spring REST GET请求返回乱码而非JSON,如何排查问题?
问题分析与解决办法
嘿,我之前也踩过类似的乱码坑,咱们一步步拆解下可能的原因和对应的解决办法:
最可能的原因:未处理响应的gzip/deflate压缩
很多API服务为了节省带宽,会对响应内容进行gzip或deflate压缩,但你的RestTemplate默认并没有配置自动解压缩的逻辑,直接读取二进制压缩数据就会出现你看到的那种乱码。这也是为什么其他站点正常——那些站点可能没开启压缩功能。
解决办法:配置RestTemplate支持自动解压缩
推荐用Apache HttpClient来实现,它自带压缩处理的拦截器,代码如下:
// 构建支持压缩的HttpClient CloseableHttpClient httpClient = HttpClientBuilder.create() .setDefaultRequestConfig(RequestConfig.custom() .setConnectTimeout(5000) .setSocketTimeout(5000) .build()) // 添加请求头告诉服务器我们支持压缩 .addInterceptorFirst((HttpRequest request, HttpContext context) -> { if (!request.containsHeader("Accept-Encoding")) { request.addHeader("Accept-Encoding", "gzip, deflate"); } }) // 自动解压缩响应内容 .addInterceptorFirst((HttpResponse response, HttpContext context) -> { HttpEntity entity = response.getEntity(); if (entity != null) { Header encoding = entity.getContentEncoding(); if (encoding != null) { String encodingValue = encoding.getValue(); if (encodingValue.equalsIgnoreCase("gzip")) { response.setEntity(new GzipDecompressingEntity(entity)); } else if (encodingValue.equalsIgnoreCase("deflate")) { response.setEntity(new DeflateDecompressingEntity(entity)); } } } }) .build(); // 把HttpClient绑定到RestTemplate RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient)); // 再调用接口试试 String jsonString = restTemplate.getForObject("http://us.turtlepool.space/api/stats", String.class);
次可能的原因:字符编码不匹配
RestTemplate默认的StringHttpMessageConverter用的是ISO-8859-1编码,如果目标API返回的是UTF-8编码的内容,直接转换就会出现乱码(不过这种乱码通常是中文变成问号或方块,和你现在的情况不太一样,但也可以排查)。
解决办法:修改默认字符编码为UTF-8
RestTemplate restTemplate = new RestTemplate(); // 遍历替换默认的StringHttpMessageConverter编码 for (HttpMessageConverter<?> converter : restTemplate.getMessageConverters()) { if (converter instanceof StringHttpMessageConverter) { ((StringHttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8); break; } } // 调用接口 String jsonString = restTemplate.getForObject("http://us.turtlepool.space/api/stats", String.class);
排查小技巧
你可以先用Postman或者curl调用这个API,查看响应头里的Content-Encoding和Content-Type字段:
- 如果
Content-Encoding是gzip或deflate,那肯定是压缩的问题; - 如果
Content-Type里包含charset=utf-8,那需要检查编码配置。
内容的提问来源于stack exchange,提问作者Maciaz
相关产品推荐
相关产品推荐

