Jackson objectMapper 无法读取 UTF-8

Jackson objectMapper cannot read UTF-8

如标题所示,Jackson 无法读取 utf-8。

第 37 行:

ArrayNode arrayNode1 = objectMapper.readValue(bansFile, ArrayNode.class);

21:48:55 [严重] com.fasterxml.jackson.core.JsonParseException:无效的 UTF-8 起始字节 0xb3 在[来源:(文件);行:18,列:38]

这是第 18 行,无法读取 UTF-8“ł”

"原因":"管理员 nie podał powodu banicji"

整个 StackTrace

21:48:55 [SEVERE]     at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1840)
21:48:55 [SEVERE]     at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:712)
21:48:55 [SEVERE]     at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._reportInvalidInitial(UTF8StreamJsonParser.java:3569)
21:48:55 [SEVERE]     at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._reportInvalidChar(UTF8StreamJsonParser.java:3565)
21:48:55 [SEVERE]     at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString2(UTF8StreamJsonParser.java:2511)
21:48:55 [SEVERE]     at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishAndReturnString(UTF8StreamJsonParser.java:2437)
21:48:55 [SEVERE]     at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.getText(UTF8StreamJsonParser.java:293)
21:48:55 [SEVERE]     at com.fasterxml.jackson.databind.deser.std.BaseNodeDeserializer.deserializeObject(JsonNodeDeserializer.java:267)
21:48:55 [SEVERE]     at com.fasterxml.jackson.databind.deser.std.BaseNodeDeserializer.deserializeArray(JsonNodeDeserializer.java:437)
21:48:55 [SEVERE]     at com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer$ArrayDeserializer.deserialize(JsonNodeDeserializer.java:141)
21:48:55 [SEVERE]     at com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer$ArrayDeserializer.deserialize(JsonNodeDeserializer.java:126)
21:48:55 [SEVERE]     at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4202)
21:48:55 [SEVERE]     at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3070)
21:48:55 [SEVERE]     at koral.proxyban.listeners.ServerConnect.isBanned(ServerConnect.java:37)
21:48:55 [SEVERE]     at koral.proxyban.listeners.ServerConnect.onProxyConnect(ServerConnect.java:25)

不,错误消息说数据是不是 UTF-8。

根据违规字符 ł 编码为字节 0xb3.

的事实,它看起来是 ISO-LATIN-2(或等效字符)

您的选择取决于很多因素。如果您的数据来自外部来源,您可能对编码没有发言权(或者您可以联系数据供应商并要求他们提供 UTF8 格式的数据)。然后你将不得不做类似

的事情
BufferedReader br = new BufferedReader(new InputStreamReader(
               new FileInputStream("yourfile"), "ISO-8859-2");    
objectMapper.readValue(br, ArrayNode.class);

在这种情况下,InputStreamReader 将正确地将字节转换为字符,而 Jackson 根本不需要处理字节(只是文本)。但它还要求您知道该文件是使用ISO-8859-2(即Latin-2)编码的。

有很多方法可以猜测文件的编码,但无法以编程方式安全地完成,因此您不能说“以正确的编码打开文件”。我知道如何调试此问题的方法是查找常见的抛光编码,然后查看 ł 在哪里用 0xb3 编码,如错误消息中所示。

不幸的是,API 中有许多方法使用“默认平台编码”,并不总是 UTF8。所以你可能会写一个你认为是 UTF8 的文件,因为你忘记明确指定你想要 UTF8,比如 new OutputStreamWriter(new FileOutputStream("yourfile"), StandardCharsets.UTF_8);.

这适用于所有将字节转换为字符的地方,反之亦然,例如文件访问、从网络套接字读取文本等等。

问题与 Jackson 无关,因为 JSON 接受的编码是 UTF8、UTF16 和 UTF32。

如果你写文件,你可以使用

保存它
OutputStreamWriter writer = new OutputStreamWriter(
                  new FileOutputStream("yourfile"), StandardCharsets.UTF_8);

如果文件是从其他来源创建的,您必须使用正确的编码来读取它

BufferedReader br = new BufferedReader(new InputStreamReader(
                   new FileInputStream("yourfile"), SOME_CHARSET));

然后将内容保存为UTF-8,否则Jackson不接受