簡體   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