【问题标题】:Create a type aware Jackson deserializer创建一个类型感知杰克逊反序列化器
【发布时间】:2012-10-19 15:07:35
【问题描述】:

我想配置一个 Jackson 反序列化器,根据带注释字段的目标类型,它的行为会有所不同。

public class Car {
    @JsonSerialize(using=IdSerializer.class)
    @JsonDeserialize(using=IdDeserializer.class)
    String id
}

public class Bus {
    @JsonSerialize(using=IdSerializer.class)
    @JsonDeserialize(using=IdDeserializer.class)
    Id id
}

Jackson 序列化器知道它转换数据的类型,所以这是有效的:

public class IdSerializer extends JsonSerializer<Object> {
    @Override
    public void serialize(Object value, JsonGenerator jsonGen, SerializerProvider provider) throws IOException {

        // value is the annotated field class
        if(value instanceof String)
            jsonGen.writeObject(...);
        else if (value instanceof Id)
            jsonGen.writeObject(...);
        else 
            throw new IllegalArgumentException();
    }
}

Jackson 反序列化器似乎不知道它将数据转换成的目标类型:

public class IdDeserializer extends JsonDeserializer<Object> {
    @Override
    public Object deserialize(JsonParser jp, DeserializationContext context) throws IOException {

        // what is the annotated field class?
    }
}

【问题讨论】:

  • 您可以在序列化中添加一些类型信息。
  • @KyleRenfro 你能提供一个代码示例吗?谢谢。

标签: java annotations jackson


【解决方案1】:

在序列化程序中,您可以添加有关类型的额外信息,以便在反序列化期间为您提供帮助。

从您发布的 IdSerializer 构建...

public class IdSerializer extends JsonSerializer<Object> {

    @Override
    public void serialize(Object value, JsonGenerator jsonGen, SerializerProvider provider) throws IOException {

        // value is the annotated field class
        if(value instanceof String){
            jsonGen.writeStartObject();
            jsonGen.writeFieldName("id");
            jsonGen.writeObject(value);
            jsonGen.writeFieldName("type");
            jsonGen.writeString("String");
            jsonGen.writeEndObject();
        }
        else if (value instanceof Id){
            Id id = (Id) value;
            jsonGen.writeStartObject();
            jsonGen.writeFieldName("id");
            jsonGen.writeString(id.getStuff());
            jsonGen.writeFieldName("type");
            jsonGen.writeString("Id");
            jsonGen.writeEndObject();
        }
        else{
            throw new IllegalArgumentException();
        }
    }
}

在您的反序列化器中,您可以解析此“类型”字段并返回正确的对象 输入。

【讨论】:

  • 序列化的对象被持久化到数据库中。因此,似乎禁止使用 jsonGen(它会将无用的数据保留在 DB 中)。
  • 明确一点,您是在将 json 保存到数据库中吗?此方法需要更多字节,但类型信息似乎没有用,因为您需要它来反序列化。
  • 无论持久化的 Java 对象如何,数据库 Document 都是相同的。这个想法是按原样保存 Id,并将其他对象转换为 Id。每个人都使用相同的注释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-11
  • 2016-10-23
  • 1970-01-01
  • 1970-01-01
  • 2012-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多