创建一个知道类型的杰克逊解串器

时间:2012-10-19 15:07:36

标签: java annotations 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();
    }
}

杰克逊反序列化者似乎不知道它将转换数据的目标类型:

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

        // what is the annotated field class?
    }
}

1 个答案:

答案 0 :(得分: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();
        }
    }
}

在你的反序列化器中,你可以解析这个'type'字段并返回一个正确的Object 类型。