当前位置: 首页 > 知识库问答 >
问题:

Avro映射序列化/反序列化问题

孔俊友
2023-03-14

目前,我正在使用Avro1.8.0序列化/反序列化对象,但面临一些问题,特别是java.util.Map对象。不面临其他类型对象的问题。

这里的示例代码-

class AvroUtils {

    public byte[] serialize(Object payload) {
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        Schema schema = new ReflectDatumWriter().getData().induce(payload); //---> getting proper map schema as {"type":"map","values":"string"}
        JsonEncoder jsonEncoder = EncoderFactory.get().jsonEncoder(schema, out);
        final GenericDatumWriter<Object> writer = new GenericDatumWriter(schema);
        writer.write(payload, jsonEncoder);
        jsonEncoder.flush();
        return out.toByteArray();
    }

    public <R> R deserialize(Object o, Class<R> aClass) {
        Schema schema = new ReflectDatumWriter().getData().induce(o); //------> getting error - unable to get schema
        final ByteArrayInputStream bin = new ByteArrayInputStream((byte[]) o);
        JsonDecoder jsonDecoder = DecoderFactory.get().jsonDecoder(schema, bin);
        final GenericDatumReader<R> reader = new GenericDatumReader<>(schema);
        return reader.read(null, jsonDecoder);
    }

    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("Key1", "Value1");
        map.put("Key2", "Value2");

        // Serialization
        byte[] result = this.serialize(map);
        System.out.println("Serialized Data : " + new String(mapDes, "UTF-8"));

        // Deserialization
        Map<String, Object> mapDes = (Map<String, Object>) this.deserialize(result, Map.class);
        System.out.println("Deserialized Data : " + mapDes);
    }
}

在deserialize方法中,我试图根据输入数据获取模式,但avro抛出错误-

`Exception in thread "main" java.lang.ClassCastException: [B cannot be cast to java.util.Collection
at org.apache.avro.reflect.ReflectData.getArrayAsCollection(ReflectData.java:196)
at org.apache.avro.generic.GenericData.induce(GenericData.java:612)`

多谢了。

共有1个答案

秋和雅
2023-03-14

您得到了java.lang.ClassCastException:[B不能被强制转换为java.util.Collection,因为您尝试使用字节数组但不是映射的对象调用Induction()方法

如果要在一个地方序列化映射,在另一个地方反序列化,可以使用更好的方法:

Schema schema = Schema.createMap(Schema.create(Schema.Type.STRING));

如果这样做,在desirialize方法中将不需要任何附加参数。

此外,GenericDatumWriter只能用于泛型记录,因此需要一个ReflectDatumWriter

下面是一个包含更改的代码示例:

public class AvroUtils {

    public static byte[] serialize(Object payload) throws IOException {
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        Schema schema = Schema.createMap(Schema.create(Schema.Type.STRING)); //---> getting proper map schema as {"type":"map","values":"string"}
        JsonEncoder jsonEncoder = EncoderFactory.get().jsonEncoder(schema, out);
        final DatumWriter<Object> writer = new ReflectDatumWriter<>(schema);
        writer.write(payload, jsonEncoder);
        jsonEncoder.flush();
        return out.toByteArray();
    }

    public static <R> R deserialize(Object o) throws IOException {
        Schema schema = Schema.createMap(Schema.create(Schema.Type.STRING));
        JsonDecoder jsonDecoder = DecoderFactory.get().jsonDecoder(schema, new ByteArrayInputStream((byte[]) o));
        final DatumReader<R> reader = new ReflectDatumReader<>(schema);
        return reader.read(null, jsonDecoder);
    }

    public static void main(String[] args) throws IOException {
        Map<String, Object> map = new HashMap<>();
        map.put("Key1", "Value1");
        map.put("Key2", "Value2");

        // Serialization
        byte[] result = serialize(map);

        // Deserialization
        Map<String, Object> mapDes = deserialize(result);
        System.out.println("Deserialized Data : " + mapDes);
    }
}

因此,您将得到如下内容:

Deserialized Data : {Key2=Value2, Key1=Value1}
 类似资料:
  • 可以序列化/反序列化< code >映射吗 在这种特殊情况下,我知道总是,和 - 第三方类(我有序列化器和反序列化器),其他值是盒装原语。 有可能和杰克逊做这样的事吗?使用MapSerializer/MapDeserializer可以做到这一点吗?(我找不到任何例子)

  • 我对Jackson有一个错误的理解,就是将json文件反序列化为poco。这是我的代码: 我的POCO命名为AnimalBean: }还有我的JSON文件: } 当我执行我的代码时,我有以下错误:未识别的字段“动物园”(类动画豆),未标记为可忽略的。我知道问题是我的json文件开始不直接由动物,但我不能改变它,因为它不是我的。我已经尝试把对象apper.configure(Deseriazatio

  • 我是Avro和Kafka的新手,我花了几天时间来发送关于Kafka主题的序列化数据...不成功。 让我来解释一下我想要达到的目标: 在生产者方面,我通过SOAP接收数据并发送关于Kafka主题的内容。我正在使用CXF从WSDL生成POJO,并且编写了相应的模式。我正在尝试做的是序列化由CXF解封的对象,并在我的Kafka主题上发送它们。 在web上找到的大多数示例中,Avro记录都是使用已知的模式

  • 问题内容: 每当我尝试序列化文件时,都会收到错误消息:FileNotFound。不知道为什么。这是我的FileHelper代码: 问题答案: