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

时间:2016-02-03 18:57:06

标签: java json utf-8 jackson avro

我有一个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

2 个答案:

答案 0 :(得分:1)

您从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);

答案 1 :(得分:0)

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

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

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