繁体   English   中英

HttpMessageNotReadableException:JSON 解析错误:无法识别的令牌“嬀崀”

[英]HttpMessageNotReadableException: JSON parse error: Unrecognized token '嬀崀'

我通过 RestTemplate 调用端点,如下所示:

   SSLContext sslContext = SSLContexts.createSystemDefault();
   SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
   HttpClient client = HttpClientBuilder.create().setSSLSocketFactory(socketFactory).build();
   ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(client);

   HttpEntity<String> entity = new HttpEntity<>(requestJson, headers());
   Object[] response = restTemplate.postForObject(uri, entity, Object[].class);

我已经验证了entity object 中的 JSON 字符串是有效的,方法是复制它并在 cURL 请求中使用它,并且没有任何错误。 此请求中也使用了相同的标头和授权令牌。

当我执行 POST 时,我得到以下错误:

Error while extracting response for type [class [Ljava.lang.Object;] and content type [application/json;charset=utf-16]
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized token '嬀崀': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token '嬀崀': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
     at [Source: (InputStreamReader); line: 1, column: 3]

我的acceptcontent-type标头都设置为application/json 通过检查 cURL 中的 output ,我发现响应正文中没有汉字。

响应头如下:

Connection →keep-alive
Content-Encoding →gzip
Content-Type →application/json; charset=utf-8
Date → xxx
Transfer-Encoding →chunked
Vary →Accept-Encoding

当我将responseType设置为String.classObject.class发出请求时,响应为中文字符:

restTemplate.postForObject(uri, entity, String.class);
嬀崀

我期待这个调用应该返回一个空数组[]

当我将requestJson字符串更改为应该返回一个非空数组的字符串时,我得到了数百个汉字,而不仅仅是两个。

如何解码响应以获取有效数据,例如使用 cURL 时?

编辑:

我不知道这有什么关系,但是空数组[]中的字符的字节码是 91 和 93,而这两个汉字的字节码是 0、91、0、93。

似乎来自restTemplate的响应是作为汉字字符串而不是数组返回的。 您发布的第一个错误似乎表明问题在于将响应提取到Object[]中。 如果来自 restTemplate 的响应实际上是一个字符串,那么这也可以解释第二个错误。 RestTemplate 期望解析一个数组,但却收到了字符串嬀崀 这就是为什么将响应类型更改为String.class似乎可行的原因。

如果您希望从您正在调用的 api 中返回 JSON 数组,那么我会仔细检查您正在调用的 api 的响应。 否则,我建议改用String.class

已编辑:restTemplate 可能正在使用utf-16字符集解析响应,而服务器正在使用utf-8字符集对响应进行编码。 就像您在描述中发布的那样,这些字符似乎具有相同的字节码。 也许将 restTemplate 中的预期字符集更改为utf-8将解决您的问题。

不要使用 UTF16。 HTTP 规范说 ASCII,许多使用 UTF8。 错误用charset=utf-16指出了这一点。 尝试在请求上设置编码 header。

正如您使用 char 代码所指出的那样,您所看到的正是使用 UTF16 时预期的结果,因为每个 char 都是 2 个字节。

The API is serving back UTF-8 content when I call it from cURL, but when I call the API programmatically it is serving back UTF-16LE despite my request headers asking for UTF-8 explicitly.

我需要做一些解码/编码游戏,但以下允许我观察有效的、预期的响应 JSON:

ResponseEntity<byte[]> responseEntity = restTemplate.postForEntity(uri, entity, byte[].class);
   
byte[] bytes = responseEntity.getBody();

String json = new String(bytes, StandardCharsets.UTF_16LE);

FooBar[] fooBar = objectMapper.readValue(json, FooBar[].class);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM