java - Jackson 自定义反序列化器,用于具有多态类型的一个字段

标签 java json polymorphism jackson deserialization

更新:

我尝试在jackson源代码中调试,在方法中发现

deserialize(JsonParser jp, DeserializationContext ctxt) of

SettableBeanProperty.java

_valueTypeDeserializer 不为 null 时,它永远不会使用 _valueDeserializer

TypeDeserializer 应该比 ValueDeserializer 更合适的假设是否正确?


我正在尝试使用 @JsonDeserialize 为具有多态类型的一个字段定义自定义反序列化器。我可以成功分别使用 @JsonDeserialize@JsonTypeInfo 。但是当我一起使用它们时,似乎 @JsonDeserialize 注释被忽略了。

这是我的类层次结构:

1. 定义.java

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", defaultImpl = Definition.class)
@JsonSubTypes({@Type(value = Definition.class, name = "normal"),
    @Type(value = FormDefinition.class, name = "form")})
public class Definition {

    private String name;
    private String description;

    // getter&setter for name&description
}

2. FormDefinition.java

public class FormDefinition extends Definition {

    private String formName;
    @JsonDeserialize(using = DefinitionDeserializer.class)
    private Definition definition;

    public String getFormName() {
        return formName;
    }

    public void setFormName(String formName) {
        this.formName = formName;
    }

    public void setDefinition(Definition definition) {
        this.definition = definition;
    }
}

3。定义Deserializer.java

public class DefinitionDeserializer extends JsonDeserializer<Definition> {

    @Override 
    public Definition deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
            throws IOException, JsonProcessingException {
        Definition definition = new Definition();
        String name = jsonParser.readValueAs(String.class);
        definition.setName(name);
        return definition;
    }
}

示例主要

public class App 
{
    public static void main( String[] args ) throws IOException {
        String sampleData = "{\"type\":\"form\",\"definition\":\"super\",\"formName\":\"FormName\"}";
        ObjectMapper mapper = new ObjectMapper();
        Definition definition = mapper.readValue(sampleData, Definition.class);
        System.out.println(definition);
    }
}

运行示例主应用程序将引发异常:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class jp.co.worksap.model.Definition] from String value ('super'); no single-String constructor/factory method (through reference chain: jp.co.worksap.model.FormDefinition["definition"])

这似乎使用 AsPropertyTypeDeserializer 来反序列化 FormDefinition 类的 definition 字段,而不是带注释的反序列化器 DefinitionDeserializer

我认为这里的棘手部分是我想使用自定义反序列化器的字段也是 Definition 类型,它使用 @JsonTypeInfo 来解决多态问题。

有什么方法可以一起使用吗?谢谢。

最佳答案

Jackson 在选择要使用的 Deserializer 之前处理 @JsonTypeInfo,可能是因为 Deserializer 的选择通常取决于类型。但是,您可以像指定自定义反序列化器一样轻松地在每个字段的基础上禁用此功能 - 通过直接注释字段:

@JsonDeserialize(using = DefinitionDeserializer.class)
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
private Definition definition;

关于java - Jackson 自定义反序列化器,用于具有多态类型的一个字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27351698/

相关文章:

创建目录时出现 java.security 错误 (Linux)

java - DialogFragments 中的空指针异常,android

ios - 发出过多 AFNetworking 请求时超时

java - Json KEY不断变化时Spring对Java对象的响应

javascript - AJAX 和 PHP 响应给出 "SyntaxError: Unexpected end of JSON input"

java - 关于对象创建的基本事情 :is it a good practice to create a new object of listener, 每次我们想为一个 View 设置一个监听器

java - 在Android中录制声音

Java父子函数调用机制关系

c++ - 在多态对象之外多态地调用函数

c++ - 如何用复数和多态重载运算符?