RestTemplate调用API返回乱码,求无代码修改的解决办法
RestTemplate调用API返回乱码问题(无法修改业务代码,仅可配置application.yml/pom.xml)
问题核心
调用代码:
ResponseEntity<String> response = restTemplate.exchange(url, method, entity, String.class);
返回乱码的原因是:RestTemplate默认的StringHttpMessageConverter未正确识别响应头Content-Type: application/json; charset=utf-16指定的编码,而是使用默认的ISO-8859-1解析utf-16格式的响应内容,导致乱码。而Unirest/Postman会自动根据响应头编码解析,所以正常。
乱码响应示例
<200,笀∀爀攀焀甀攀猀琀䐀愀琀攀吀椀洀攀∀㨀∀㈀ ㈀㐀ⴀ 㜀ⴀ㈀㌀吀 㨀㈀㨀㠀⸀㜀 㜀㘀㐀㐀⬀ 㔀㨀 ∀Ⰰ∀氀漀最䤀搀∀㨀∀㈀㜀 㜀昀戀ⴀ 攀㤀戀ⴀ㐀㐀戀搀ⴀ㤀搀 㠀ⴀ㔀㔀㌀㔀搀㜀搀 戀昀∀Ⰰ∀挀漀搀攀∀㨀∀䴀匀䜀ⴀ ∀Ⰰ∀猀攀瘀攀爀椀琀礀∀㨀∀匀甀挀挀攀猀猀∀Ⰰ∀挀漀渀琀攀渀琀∀㨀∀攀礀䨀栀戀䜀挀椀伀椀䨀䤀唀稀䤀一椀䤀猀䤀渀刀㔀挀䌀䤀㘀䤀欀瀀堀嘀䌀䨀㤀⸀攀礀䨀戀洀氀砀搀圀嘀昀戀洀䘀琀娀匀䤀㘀䤀洀䤀㐀娀䐀䔀㈀䴀圀䔀礀䰀圀夀㈀夀樀挀琀一䐀䴀砀一礀栀夀樀䔀 䰀吀欀㌀䴀䐀最稀伀吀䴀㐀娀圀䔀㐀䴀椀䤀猀䤀洀㔀椀娀椀䤀㘀䴀吀挀礀䴀吀挀砀䴀樀䄀㌀伀䌀眀椀娀堀栀眀䤀樀漀砀一稀䤀砀一稀䔀一樀挀㐀䰀䌀䨀瀀夀堀儀椀伀樀䔀㌀䴀樀䔀㌀䴀吀䤀眀一稀栀㤀⸀挀䤀䄀攀䈀砀ⴀ瘀爀吀娀匀㠀㤀㠀甀㈀䄀㔀娀䰀㔀䴀倀䔀愀 爀欀伀儀瘀堀漀ⴀ樀ⴀ洀䤀礀唀 ∀Ⰰ∀攀爀爀漀爀∀㨀渀甀氀氀紀,{Content-Length=[780], Content-Type=[application/json; charset=utf-16], Server=[Microsoft-IIS/10.0], Date=[Tue, 23 Jul 2024 05:21:18 GMT]}>
期望正常响应示例
<200,{requestDateTime=2024-07-23T10:23:45.9429614+05:00, logId=e7dc9988-2a2a780b54c6, code=200, severity=Success, content=eyJNiIsInR5cCI6IkpXVCJhbGciOiJIUzI19.eyJ1bSI6ImI4ZDE2MWEyMTIyMjV9LWY2mlxdWVfbmFtZYjctNDMcyMTcxMjIyNSwiZXhwIjoxNzIxNzE1ODI1LCJpYXQiOjE3MjxNy1hYjE0LTk3MDgzOTM4ZWE4MiIsIm5iZiI6MTE3.yGUCZ83YVYw7XOuXrIl79ONCYVuxKS5MbtB_XxG9wyE, error=null},{Content-Length=[780], Content-Type=[application/json; charset=utf-16], Server=[Microsoft-IIS/10.0], Date=[Tue, 23 Jul 2024 05:23:45 GMT]}>
已尝试的无效配置
application.yml
spring.mandatoryFileEncoding=UTF-8 spring.http.encoding.charset=UTF-8 spring.http.encoding.enabled=true spring.http.encoding.force=true
pom.xml
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties>
可行解决方案
方案1:全局调整JVM编码(影响整个应用)
在应用启动参数中添加:
-Dfile.encoding=UTF-16
该参数会强制JVM使用UTF-16编码处理字符串,让StringHttpMessageConverter默认使用UTF-16解析响应,解决乱码问题。注意此配置会影响整个应用的编码处理,若其他接口使用UTF-8编码可能出现问题。
方案2:Spring Boot Bean覆盖配置(需2.7+版本)
在application.yml中添加以下配置,替换默认的StringHttpMessageConverter,指定默认编码为UTF-16:
spring: beans: overrides: stringHttpMessageConverter: class: org.springframework.http.converter.StringHttpMessageConverter constructor-args: - UTF-16
此配置会替换Spring容器中默认的StringHttpMessageConverter实例,使其默认使用UTF-16编码,同时仍会优先遵循响应头指定的编码。
方案3:添加配置类(若允许新增非业务代码)
若仅限制修改业务代码,可添加以下配置类(放置在项目配置包下):
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.StringHttpMessageConverter; import java.nio.charset.StandardCharsets; @Configuration public class RestTemplateEncodingConfig { @Bean public StringHttpMessageConverter stringHttpMessageConverter() { return new StringHttpMessageConverter(StandardCharsets.UTF_16); } }
Spring会自动将此转换器加入RestTemplate的消息转换器列表,优先使用它处理字符串类型的响应。
内容的提问来源于stack exchange,提问作者MM Ary
相关产品推荐
相关产品推荐

