我有一个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
?
答案 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(或其他组合)。