Jackson serialization of abstract interface

眉间皱痕 提交于 2019-12-25 03:44:44

问题


I'm working with a framework that performs Java Jackson serialization of class Config with a field supplier that is an abstract interface Supplier<T>. The interfaces below are defined in the framework so I cannot change/add the annotations.

public interface Supplier<T> {
    T get();
}

public interface Calculator {
}

@Data
@NoArgsConstructor
public class Config extends Serializable {
  private Supplier<Calculator> supplier;
}

I have a concrete implementation of Supplier:

class MySupplier implements Supplier {
   @Override Calculator get() { return ...; }
}

When I serialize an instance of Config into JSON the supplier field is serialized without class information. From what I understand this is because the field declaration is abstract. As a result during deserialization Jackson doesn't know how to instantiate supplier field.

"config" : {
 ...
 "supplier" : { }
 ...
}

How can I force my implementation of the Supplier interface to add class name information into generated JSON to allow proper deserialization? I don't have access to the code that performs serialization and deserialization, I can only manipulate my implementation of Supplier.


回答1:


Jackson allows to configure third party classes using feature called MixIn. For more information read:

  1. Jackson Mixin to the Rescue
  2. Jackson Mix-In Annotations

You need to specify two new interface which will allow you to add annotations for other classes:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({@JsonSubTypes.Type(value = MySupplier.class, name = "MySupplier")})
interface SupplierAnnotations {
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({
        @JsonSubTypes.Type(value = MyCalculator.class, name = "MyCalculator"),
        @JsonSubTypes.Type(value = HisCalculator.class, name = "HisCalculator") }
)
interface CalculatorAnnotations {
}

Now, you have to inform ObjectMapper about your new classes. You can do that in this way:

ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Calculator.class, CalculatorAnnotations.class);
mapper.addMixIn(Supplier.class, SupplierAnnotations.class);

Everything you need to do is to list sub types for Suplier and Calculator interfaces.



来源:https://stackoverflow.com/questions/54224705/jackson-serialization-of-abstract-interface

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!