简体   繁体   English

为多态类型层次结构 Jackson 编写自定义反序列化器

[英]Writing custom deserializer for polymorphic type hierarchy Jackson

I'm experimenting with Jackson deserialization for inheritance in Java.我正在尝试对 Java 中的 inheritance 进行 Jackson 反序列化。 I've a base class:我有一个基础 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 is also abstract 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;
   }
}

My subClassA:我的子类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;
   }

}

If I pass in a JSON of in the following form:如果我以以下形式传入 JSON :

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

I get an error Cannot construct instance of ClassA (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information I came across this https://github.com/FasterXML/jackson-databind/issues/374 which says this is a known issue with Jackson.我收到一个错误无法构造 ClassA 的实例(没有创建者,如默认构造,存在):抽象类型要么需要映射到具体类型,要么具有自定义反序列化器,要么包含我遇到的此https://github 的其他类型信息。 com/FasterXML/jackson-databind/issues/374表示这是 Jackson 的已知问题。 How do I go about writing a customDeserializer for this.我该如何为此编写自定义解串器。

In classA I tried doing this:在 A 类中,我尝试这样做:

@JsonDeserialize(using = ClassADeserializer.class)

and ClassADeserializer is:和 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);
    }

which obviously doesn't work.这显然是行不通的。 How do I go about writing a custom deserializer for this?如何为此编写自定义解串器?

Problem:问题:

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. 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. then jackson call default constructor to create instance.然后 jackson 调用默认构造函数来创建实例。 but default constructor also missing.. thats why u get this error: Cannot construct instance of ClassA (no Creators, like default construct, exist) ..但是默认构造函数也丢失了..这就是为什么你会收到这个错误: Cannot construct instance of ClassA (no Creators, like default construct, exist) ..

Solution:解决方案:

As you want to deserialize to SubClassA ... You need to use @JsonCreator in SubClassA...Then you need to use @JsonIgnoreProperties to ignore properties type so that jackson create instance of SubClassA instead of ClassA ....当您想反序列化为SubClassA ...您需要在 SubClassA 中使用@JsonCreator ...然后您需要使用 @JsonIgnoreProperties 来忽略属性type ,以便 jackson 创建SubClassA的实例而不是ClassA ....

Try with below SubClassA :尝试以下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