JsonParseException:无效的 UTF-8 中间字节 0x2d

JsonParseException: Invalid UTF-8 middle byte 0x2d

我有一个 JSON 字符串,我正在从中制作一个 InputStream object ,如下所示,然后我正在制作一个 GenericRecord 对象,因为我正在尝试序列化我的 JSON 反对 Avro 模式。

InputStream input = new ByteArrayInputStream(jsonString.getBytes());
DataInputStream din = new DataInputStream(input);

Decoder decoder = DecoderFactory.get().jsonDecoder(schema, din);

DatumReader<GenericRecord> reader = new GenericDatumReader<GenericRecord>(schema);
// below line is throwing exception
GenericRecord datum = reader.read(null, decoder);   

下面是我得到的异常:

org.codehaus.jackson.JsonParseException: Invalid UTF-8 middle byte 0x2d at [Source: java.io.DataInputStream@562aee31; line: 1, column: 74]

这是发生此异常的实际 JSON 字符串:

{"name":"car_test","attr_value":"2006|Renault|Megane II Coupé-Cabriolet|null|null|null|null|0|Wed Feb 03 10:00:59 GMT-07:00 2016|1|77|null|null|null|null","data_id":900}

我做了一些研究,发现我需要使用 ByteArrayInputStream 和 UTF-8 编码,如下所示:

InputStream input = new ByteArrayInputStream(jsonString.getBytes(StandardCharsets.UTF_8.displayName()));

但是我的问题是这个异常的原因是什么?为什么它会发生在我上面的 JSON 字符串上?我只是想了解为什么在我上面的 JSON 字符串上会发生此异常。使用 UTF-8 是正确的解决方法吗?

这个错误是什么意思Invalid UTF-8 middle byte 0x2d

您从 Java Unicode 字符串 jsonString 开始。

然后使用 String.getBytes() 将其转换为字节流。由于您没有指定字节编码,因此使用的平台默认值很可能是 ISO 8859-1。

现在您从 (Data)InputStream 解析 JSON。现在 Avro 似乎使用 UTF-8 来解码字节。当它遇到 é (0x2d) 时失败,因为它不是有效的 UTF 字节序列。

所以最后是实际编码(ISO 8859-1)和预期编码(UTF-8)不匹配。

你可以像以前一样解决这个问题,或者只是避免从字符串到字节:

Decoder decoder = DecoderFactory.get().jsonDecoder(schema, jsonString);

您可能对使用 Jackson Avro 模块的更方便的方法感兴趣,而不是使用低级 Avro 解码器功能:

https://github.com/FasterXML/jackson-dataformat-avro/issues

您可以在其中提供 Avro Schema,但仍可使用 POJO。 您还可以对 JSON 部分使用常规 JSON Jackson 数据绑定(不同的 ObjectMapper),并将 JSON 读入 POJO,将 POJO 写入 Avro(或其他组合)。