Rest 模板返回乱码某种中文的响应

问题描述 投票:0回答:1

我使用rest模板调用API,当我使用rest模板调用API时,它返回一些乱码,例如中文。

ResponseEntity<String> response = restTemplate.exchange(url, method, entity, String.class);

当我使用 Unirest 或 Postman 使用相同的 API 时,它会返回 JSON 格式的响应。我搜索并试图找出答案,但有一个限制,即我无法在代码中进行更改,或者我在 application.yml 或 pom.xml 中进行更改,但无法在代码级别进行更改。

<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]}>

当我将返回值更改为“Object.class”时,我收到了上述预期响应,但正如我之前所说,我无法进行该更改。我还在我的 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>

但对我来说没有任何作用。请建议我是否有任何可能的解决方案可以在不更改代码的情况下获取 JSON 格式的响应。

TIA。

json utf-8 spring-resttemplate invalid-characters response-entity
1个回答
0
投票

您的服务器正在生成 UTF-16 字符集的文本,如标题

Content-Type: application/json; charset=utf-16
所示。不幸的是,UTF-16 本身就是一个不明确的字符集:有两种变体,UTF-16-BE(“大端”)和 UTF-16-LE(“小端”)。

通常,如果仅指定“UTF-16”,则响应的前两个字节应为字节顺序标记,即 FF FE 或 FE FF,表示用于对消息进行编码的字节序。但是,您的服务器没有发送字节顺序标记。因此,Spring 最终不得不猜测正在使用哪种字节序——而 Spring 猜错了。

我可以通过一个简短的 Python 脚本来证明接收到的文本的字节顺序错误,该脚本可以“消除”您收到的消息:

r = r'笀∀爀攀焀甀攀猀琀䐀愀琀攀吀椀洀攀∀㨀∀㈀ ㈀㐀ⴀ 㜀ⴀ㈀㌀吀㄀ 㨀㈀㄀㨀㄀㠀⸀㜀 㜀㘀㐀㄀㐀⬀ 㔀㨀  ∀Ⰰ∀氀漀最䤀搀∀㨀∀㈀㜀  ㄀㜀昀戀ⴀ 攀㤀戀ⴀ㐀㐀戀搀ⴀ㤀搀 㠀ⴀ㔀㔀㄀㄀㌀㔀搀㜀搀 戀昀∀Ⰰ∀挀漀搀攀∀㨀∀䴀匀䜀ⴀ      ∀Ⰰ∀猀攀瘀攀爀椀琀礀∀㨀∀匀甀挀挀攀猀猀∀Ⰰ∀挀漀渀琀攀渀琀∀㨀∀攀礀䨀栀戀䜀挀椀伀椀䨀䤀唀稀䤀㄀一椀䤀猀䤀渀刀㔀挀䌀䤀㘀䤀欀瀀堀嘀䌀䨀㤀⸀攀礀䨀㄀戀洀氀砀搀圀嘀昀戀洀䘀琀娀匀䤀㘀䤀洀䤀㐀娀䐀䔀㈀䴀圀䔀礀䰀圀夀㈀夀樀挀琀一䐀䴀砀一礀㄀栀夀樀䔀 䰀吀欀㌀䴀䐀最稀伀吀䴀㐀娀圀䔀㐀䴀椀䤀猀䤀洀㔀椀娀椀䤀㘀䴀吀挀礀䴀吀挀砀䴀樀䄀㌀伀䌀眀椀娀堀栀眀䤀樀漀砀一稀䤀砀一稀䔀㄀一樀挀㐀䰀䌀䨀瀀夀堀儀椀伀樀䔀㌀䴀樀䔀㌀䴀吀䤀眀一稀栀㤀⸀挀䤀䄀攀䈀砀ⴀ瘀爀吀娀匀㠀㤀㠀甀㈀䄀㔀娀䰀㔀䴀倀䔀愀 爀欀伀儀瘀堀漀ⴀ樀ⴀ洀䤀礀唀  ∀Ⰰ∀攀爀爀漀爀∀㨀渀甀氀氀紀'
print(r.encode("utf-16-le").decode("utf-16-be"))

这将打印

{"requestDateTime":"2024-07-23T10:21:18.7076414+05:00","logId":"270017fb-0e9b-44bd-9d08-551135d7d0bf","code":"MSG-000000","severity":"Success","content":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImI4ZDE2MWEyLWY2YjctNDMxNy1hYjE0LTk3MDgzOTM4ZWE4MiIsIm5iZiI6MTcyMTcxMjA3OCwiZXhwIjoxNzIxNzE1Njc4LCJpYXQiOjE3MjE3MTIwNzh9.cIAeBx-vrTZS898u2A5ZL5MPEa0rkOQvXo-j-mIyU00","error":null}
,这是一个完全合理的 JSON 响应。

不幸的是,在这种情况下,是您的服务器没有发送正确的响应,应该修复(如果可能)。服务器应该:

  • 发送带有正确字节顺序标记的 UTF-16 响应,以指示所使用的字节序
  • 将字符集设置为 UTF-16-LE 或 UTF-16-BE 以明确指示使用的字节序
  • 只需使用 UTF-8 即可完全避免这种混乱(推荐)

不幸的是,我不确定修复 Spring 以使用“正确”编码是否容易,因为是您的服务器违反了相关规范。

© www.soinside.com 2019 - 2024. All rights reserved.