簡體   English   中英

為多態類型層次結構 Jackson 編寫自定義反序列化器

[英]Writing custom deserializer for polymorphic type hierarchy Jackson

我正在嘗試對 Java 中的 inheritance 進行 Jackson 反序列化。 我有一個基礎 class:

@Getter //Lombok @Getter
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", include = JsonTypeInfo.As.PROPERTY)
@JsonSubTypes(value = {
        @JsonSubTypes.Type(value=ClassA.class, name = "classA")
})
public abstract class BaseClass {
   private List<String> fields;

   @JsonCreator
   public BaseClass(@JsonProperty("fields") final List<String> fields) {
     this.fields = fields;
   }
}

ClassA 也是抽象的

@Getter
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "typeA", include = JsonTypeInfo.As.PROPERTY)
@JsonSubTypes(value = {
        @JsonSubTypes.Type(value=SubClassA.class, name = "subclassA")
})
public abstract class ClassA extends BaseClass{
   private String mode;

   @JsonCreator
   public ClassA(@JsonProperty("fields") final List<String> fields, @JsonProperty("mode") String mode) {
       super(fields);
       this.mode = mode;
   }
}

我的子類A:

public class SubClassA extends ClassA {
   private String dummyField;

   public SubClassA(@JsonProperty("fields") final List<String> fields, @JsonProperty("mode") String mode,
     @JsonProperty("dummyField") String dummyField) {
       super(fields, mode);
       this.dummyField = dummyField;
   }

}

如果我以以下形式傳入 JSON :

{
  "type": "classA",
  "typeA": "subclassA",
  "mode": "testingMode",
  "fields": ["1", "2"],
  "dummyField": "dummy"
}

我收到一個錯誤無法構造 ClassA 的實例(沒有創建者,如默認構造,存在):抽象類型要么需要映射到具體類型,要么具有自定義反序列化器,要么包含我遇到的此https://github 的其他類型信息。 com/FasterXML/jackson-databind/issues/374表示這是 Jackson 的已知問題。 我該如何為此編寫自定義解串器。

在 A 類中,我嘗試這樣做:

@JsonDeserialize(using = ClassADeserializer.class)

和 ClassADeserializer 是:

public class ClassADeserializer extends StdDeserializer<ClassA> {
    private final JsonDeserializer<?> defaultDeserializer;
    public ClassADeserializer(JsonDeserializer<?> defaultDeserializer) {
        super(ClassA.class);
        this.defaultDeserializer = defaultDeserializer;
    }

    @Override public ClassA deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
       return (ClassA) defaultDeserializer.deserialize(jsonParser, deserializationContext);
    }

這顯然是行不通的。 如何為此編寫自定義解串器?

問題:

You pass in json "type": "classA", ... That means jackson first try to create instance of ClassA ..During deserialization jackson search @JsonCreator constructor first..If @JsonCreator missing or can not call @JsonCreator constructor then jackson create object with default constructor and call setter method... In your ClassA @JsonCreator constructor with 2 arguments but jackson call with 3 arguments.. So its fail. 然后 jackson 調用默認構造函數來創建實例。 但是默認構造函數也丟失了..這就是為什么你會收到這個錯誤: Cannot construct instance of ClassA (no Creators, like default construct, exist) ..

解決方案:

當您想反序列化為SubClassA ...您需要在 SubClassA 中使用@JsonCreator ...然后您需要使用 @JsonIgnoreProperties 來忽略屬性type ,以便 jackson 創建SubClassA的實例而不是ClassA ....

嘗試以下SubClassA

@Getter
@JsonIgnoreProperties(ignoreUnknown = true)
public class SubClassA extends ClassA {
    private String dummyField;

    @JsonCreator
    public SubClassA(@JsonProperty("fields") final List<String> fields, @JsonProperty("mode") String mode,
                     @JsonProperty("dummyField") String dummyField) {
        super(fields, mode);
        this.dummyField = dummyField;
    }

}

暫無
暫無

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

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