Java 创建类型识别的Jackson反序列化程序

Java 创建类型识别的Jackson反序列化程序,java,annotations,jackson,Java,Annotations,Jackson,我想配置一个Jackson反序列化程序,根据带注释字段的目标类型,它的行为会有所不同 public class Car { @JsonSerialize(using=IdSerializer.class) @JsonDeserialize(using=IdDeserializer.class) String id } public class Bus { @JsonSerialize(using=IdSerializer.class) @JsonDese

我想配置一个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();
    }
}
公共类IdSerializer扩展JsonSerializer{
@凌驾
public void serialize(对象值、JsonGenerator jsonGen、SerializerProvider提供程序)引发IOException{
//值是带注释的字段类
if(字符串的值实例)
jsonGen.writeObject(…);
else if(值instanceof Id)
jsonGen.writeObject(…);
其他的
抛出新的IllegalArgumentException();
}
}
Jackson反序列化程序似乎不知道将数据转换成的目标类型:

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

        // what is the annotated field class?
    }
}
公共类IdDeserializer扩展JsonDeserializer{
@凌驾
公共对象反序列化(JsonParser jp,反序列化上下文)引发IOException{
//什么是带注释的字段类?
}
}

在序列化程序中,您可以添加有关类型的额外信息,这些信息将在反序列化过程中帮助您

从发布的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();
        }
    }
}
公共类IdSerializer扩展JsonSerializer{
@凌驾
public void serialize(对象值、JsonGenerator jsonGen、SerializerProvider提供程序)引发IOException{
//值是带注释的字段类
if(字符串的值实例){
jsonGen.writeStartObject();
jsonGen.writeFieldName(“id”);
jsonGen.writeObject(值);
jsonGen.writeFieldName(“类型”);
jsonGen.writeString(“字符串”);
jsonGen.writeEndObject();
}
else if(值instanceof Id){
Id=(Id)值;
jsonGen.writeStartObject();
jsonGen.writeFieldName(“id”);
writeString(id.getStuff());
jsonGen.writeFieldName(“类型”);
jsonGen.WRITETSTRING(“Id”);
jsonGen.writeEndObject();
}
否则{
抛出新的IllegalArgumentException();
}
}
}
在反序列化程序中,您可以解析此“类型”字段并返回正确类型的对象
键入。

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

从发布的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();
        }
    }
}
公共类IdSerializer扩展JsonSerializer{
@凌驾
public void serialize(对象值、JsonGenerator jsonGen、SerializerProvider提供程序)引发IOException{
//值是带注释的字段类
if(字符串的值实例){
jsonGen.writeStartObject();
jsonGen.writeFieldName(“id”);
jsonGen.writeObject(值);
jsonGen.writeFieldName(“类型”);
jsonGen.writeString(“字符串”);
jsonGen.writeEndObject();
}
else if(值instanceof Id){
Id=(Id)值;
jsonGen.writeStartObject();
jsonGen.writeFieldName(“id”);
writeString(id.getStuff());
jsonGen.writeFieldName(“类型”);
jsonGen.WRITETSTRING(“Id”);
jsonGen.writeEndObject();
}
否则{
抛出新的IllegalArgumentException();
}
}
}
在反序列化程序中,您可以解析此“类型”字段并返回正确类型的对象
类型。

您可以向序列化添加一些类型信息。@KyleRenfro您可以提供一个代码示例吗?谢谢。您可以向序列化添加一些类型信息。@KyleRenfro您能提供一个代码示例吗?谢谢。序列化对象被持久化到数据库中。因此,使用jsonGen似乎是被禁止的(它会在数据库中保存无用的数据)?这个方法需要更多的字节,但是类型信息看起来并不是无用的,因为你需要它来反序列化。其思想是将Id保存为原样,并将其他对象转换为Id。对每个人使用相同的注释。序列化对象将持久化到数据库中。因此,使用jsonGen似乎是被禁止的(它会在数据库中保存无用的数据)?这个方法需要更多的字节,但是类型信息看起来并不是无用的,因为你需要它来反序列化。其思想是将Id保存为原样,并将其他对象转换为Id。对每个人使用相同的注释。