簡體   English   中英

傑克遜為一個具有多態類型的字段定制解串器

[英]Jackson custom deserializer for one field with polymorphic types

更新:

我嘗試在jackson源代碼中調試並在方法中找出它

deserialize(JsonParser jp, DeserializationContext ctxt)

SettableBeanProperty.java

_valueTypeDeserializer不為null時,它將永遠不會使用_valueDeserializer

這是一個正確的假設,TypeDeserializer應該比ValueDeserializer更合適嗎?


我正在嘗試使用@JsonDeserialize為一個具有多態類型的字段定義自定義反序列化器。 我可以單獨使用@JsonDeserialize@JsonTypeInfo 但是當我一起使用它們時,似乎忽略了@JsonDeserialize注釋。

這是我的類層次結構:

1. Definition.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. DefinitionDeserializer.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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM