Java对象Avro的Json字符串
我正在尝试将Json字符串转换为具有Avro模式的通用Java对象 下面是我的代码Java对象Avro的Json字符串,java,json,avro,Java,Json,Avro,我正在尝试将Json字符串转换为具有Avro模式的通用Java对象 下面是我的代码 String json = "{\"foo\": 30.1, \"bar\": 60.2}"; String schemaLines = "{\"type\":\"record\",\"name\":\"FooBar\",\"namespace\":\"com.foo.bar\",\"fields\":[{\"name\":\"foo\",\"type\":[\"null\",\"double\"],\"defa
String json = "{\"foo\": 30.1, \"bar\": 60.2}";
String schemaLines = "{\"type\":\"record\",\"name\":\"FooBar\",\"namespace\":\"com.foo.bar\",\"fields\":[{\"name\":\"foo\",\"type\":[\"null\",\"double\"],\"default\":null},{\"name\":\"bar\",\"type\":[\"null\",\"double\"],\"default\":null}]}";
InputStream input = new ByteArrayInputStream(json.getBytes());
DataInputStream din = new DataInputStream(input);
Schema schema = Schema.parse(schemaLines);
Decoder decoder = DecoderFactory.get().jsonDecoder(schema, din);
DatumReader<Object> reader = new GenericDatumReader<Object>(schema);
Object datum = reader.read(null, decoder);
String json=“{\'foo\':30.1,\'bar\':60.2}”;
字符串模式=“{\'type\':\'record\',\'name\':\'FooBar\',\'namespace\':\'com.foo.bar\',\'fields\':[{\'name\':\'foo\',\'type\':[\'null\',\'double\'],\'default\':null},{\'name\':'bar\',\'type\'type\':[\'null\','double\','default;
InputStream input=new ByteArrayInputStream(json.getBytes());
DataInputStream din=新的DataInputStream(输入);
Schema=Schema.parse(schemaLines);
Decoder Decoder=DecoderFactory.get().jsonDecoder(模式,din);
DatumReader=新的GenericDatumReader(模式);
对象数据=reader.read(空,解码器);
我得到了“org.apache.avro.AvroTypeException:Expected start union.get VALUE\u NUMBER\u FLOAT”异常
如果模式中没有联合,那么同样的代码也可以工作。
有人能解释一下并给我一个解决方案吗。您的模式与json字符串的模式不匹配。您需要有一个不同的模式,该模式在错误处没有并集,而是有一个十进制数。这样的模式应该被用作writer模式,而您可以自由地使用另一个作为reader模式。多亏了Reza。我找到了这个网页。 它介绍了如何将Json字符串转换为avro对象 他的代码的关键是:
static byte[] fromJsonToAvro(String json, String schemastr) throws Exception {
InputStream input = new ByteArrayInputStream(json.getBytes());
DataInputStream din = new DataInputStream(input);
Schema schema = Schema.parse(schemastr);
Decoder decoder = DecoderFactory.get().jsonDecoder(schema, din);
DatumReader<Object> reader = new GenericDatumReader<Object>(schema);
Object datum = reader.read(null, decoder);
GenericDatumWriter<Object> w = new GenericDatumWriter<Object>(schema);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Encoder e = EncoderFactory.get().binaryEncoder(outputStream, null);
w.write(datum, e);
e.flush();
return outputStream.toByteArray();
}
String json = "{\"username\":\"miguno\",\"tweet\":\"Rock: Nerf paper, scissors is fine.\",\"timestamp\": 1366150681 }";
String schemastr ="{ \"type\" : \"record\", \"name\" : \"twitter_schema\", \"namespace\" : \"com.miguno.avro\", \"fields\" : [ { \"name\" : \"username\", \"type\" : \"string\", \"doc\" : \"Name of the user account on Twitter.com\" }, { \"name\" : \"tweet\", \"type\" : \"string\", \"doc\" : \"The content of the user's Twitter message\" }, { \"name\" : \"timestamp\", \"type\" : \"long\", \"doc\" : \"Unix epoch time in seconds\" } ], \"doc:\" : \"A basic schema for storing Twitter messages\" }";
byte[] avroByteArray = fromJsonToAvro(json,schemastr);
Schema schema = Schema.parse(schemastr);
DatumReader<Genericrecord> reader1 = new GenericDatumReader<Genericrecord>(schema);
Decoder decoder1 = DecoderFactory.get().binaryDecoder(avroByteArray, null);
GenericRecord result = reader1.read(null, decoder1);
JSONTAVRO(字符串json,字符串Schematr)的静态字节[]引发异常{
InputStream input=new ByteArrayInputStream(json.getBytes());
DataInputStream din=新的DataInputStream(输入);
Schema=Schema.parse(schemastr);
Decoder Decoder=DecoderFactory.get().jsonDecoder(模式,din);
DatumReader=新的GenericDatumReader(模式);
对象数据=reader.read(空,解码器);
GenericDatumWriter w=新的GenericDatumWriter(模式);
ByteArrayOutputStream outputStream=新建ByteArrayOutputStream();
编码器e=EncoderFactory.get().binaryEncoder(outputStream,null);
w、 写入(数据,e);
e、 冲洗();
返回outputStream.toByteArray();
}
字符串json=“{\'username\':\'miguno\',\'tweet\':\'Rock:Nerf纸,剪刀很好。\',\'timestamp\':1366150681}”;
String schemastr=“{\'type\”:\“record\”,\“name\”:“twitter\u schema\”,\“namespace\”:“com.miguno.avro\”,\“fields\”:[{\'name\”:“username\”,“type\”:“String\”,“doc\”:“twitter.com上的用户帐户名\”,{\'name\:“tweet\”,“type\”:“type\:“String\”,“doc\”:“用户twitter消息的内容”,{名称\“:\“timestamp\”,\“type\”:“long\”,\“doc\”:“Unix纪元时间(秒)”,\“doc:\”:“存储Twitter消息的基本模式\“}”;
字节[]avroByteArray=fromJSONTAVRO(json,schematr);
Schema=Schema.parse(schemastr);
DatumReader reader1=新的GenericDatumReader(模式);
Decoder decoder1=DecoderFactory.get().binaryDecoder(avroByteArray,null);
GenericRecord结果=reader1.read(null,decoder1);
使用Avro 1.4.1,它可以:
private static GenericData.Record parseJson(String json, String schema)
throws IOException {
Schema parsedSchema = Schema.parse(schema);
Decoder decoder = new JsonDecoder(parsedSchema, json);
DatumReader<GenericData.Record> reader =
new GenericDatumReader<>(parsedSchema);
return reader.read(null, decoder);
}
private static GenericData.Record parseJson(字符串json,字符串模式)
抛出IOException{
Schema parsedSchema=Schema.parse(Schema);
解码器=新的JsonDecoder(parsedSchema,json);
数据读取器=
新的GenericDatumReader(parsedSchema);
返回reader.read(null,解码器);
}
可能需要对以后的Avro版本进行一些调整。对于任何使用Avro-1.8.2的人来说,
JsonDecoder
现在不能直接在包org.apache.Avro.io
之外实例化。您可以对其使用DecoderFactory
,如下代码所示:
String schemaStr = "<some json schema>";
String genericRecordStr = "<some json record>";
Schema.Parser schemaParser = new Schema.Parser();
Schema schema = schemaParser.parse(schemaStr);
DecoderFactory decoderFactory = new DecoderFactory();
Decoder decoder = decoderFactory.jsonDecoder(schema, genericRecordStr);
DatumReader<GenericData.Record> reader =
new GenericDatumReader<>(schema);
GenericRecord genericRecord = reader.read(null, decoder);
String schematr=“”;
字符串genericRecordStr=“”;
Schema.Parser schemaParser=新Schema.Parser();
Schema=schemaParser.parse(schemaStr);
DecoderFactory DecoderFactory=新的DecoderFactory();
Decoder-Decoder=decoderFactory.jsonDecoder(模式,genericRecordStr);
数据读取器=
新的GenericDatumReader(模式);
GenericRecord GenericRecord=reader.read(空,解码器);
问题不在于代码,而在于json的错误格式
字符串json=“{”foo:{”double:30.1}”,bar:{“double:60.2}” 正如评论中已经提到的,AVRO libs理解的JSON与普通JSON对象有点不同。具体来说,UNION
type被包装到一个嵌套的对象结构中:“UNION\u字段”:{“type”:“value”}
所以,如果您想将“普通”JSON转换为AVRO,您必须使用第三方库。至少现在是这样
- -
Java
声称支持联合的项目,不确定默认值
- -这是我的项目,虽然是用
Scala
编写的,但仍然可以从Java
使用。支持联合、默认值、base64二进制数据
From,我理解联合的Json编码是不同的,但我正在尝试找出是否有任何方法可以将Json字符串转换为object.FYI,jsonDecoder()的重载接受Json字符串;无需将其转换为流。或者,告诉Avro您正在使用哪一个流,如下所示:String json=“{\'foo\':{\'double\':30.1},\'bar\':{\'double\':60.2}”代码>这将是avro使用给定模式序列化记录的方式。谢谢Miljanm和Keegan。是的,我知道工会的json编码不同于avro.apache.org/docs/1.7.6/spec.html#json_编码。但我正在寻找一个开源库,它可以在内部将我的json字符串更改为avro特定的模式,然后解析它。有这样的工具吗?我不知道有这样的工具。为什么不想创建一个不同的模式?这个问题的解决方案似乎简单得多,模式与当前模式兼容。这段代码无法解决问题。当架构包含联合时,这不起作用。当我的架构包含联合时,有什么解决方案吗?我得到了Exce