Polymorphism in jackson annotations: @JsonTypeInfo usage

后端 未结 2 1826
醉话见心
醉话见心 2020-11-27 14:32

I would like to know if @JsonTypeInfo annotation can be used for interfaces. I have set of classes which should be serialized and deserialized.

Here is

相关标签:
2条回答
  • 2020-11-27 14:35

    Yes it can be used both for abstract classes and interfaces.

    Consider following code example

    Suppose we have an enum , interface and classes

    enum VehicleType {
        CAR,
        PLANE
    }
    
    interface Vehicle {
        VehicleType getVehicleType();
        String getName();
    }
    
    
    @NoArgsConstructor
    @Getter
    @Setter
    class Car implements Vehicle {
        private boolean sunRoof;
        private String name;
    
        @Override
        public VehicleType getVehicleType() {
            return VehicleType.Car;
        }
    }
    
    @NoArgsConstructor
    @Getter
    @Setter
    class Plane implements Vehicle {
        private double wingspan;
        private String name;
    
        @Override
        public VehicleType getVehicleType() {
            return VehicleType.Plane;
        }
    }
    

    If we try to deserialize this json into List<Vehicle>

    [
      {"sunRoof":false,"name":"Ferrari","vehicleType":"CAR"}, 
      {"wingspan":19.25,"name":"Boeing 750","vehicleType":"PLANE"}
    ]
    

    then we will get error

    abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
    

    To solve this just add following JsonSubTypes and JsonTypeInfo annotations to the interface, as shown below

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
            property = "vehicleType")
    @JsonSubTypes({
            @JsonSubTypes.Type(value = Car.class, name = "CAR"),
            @JsonSubTypes.Type(value = Plane.class, name = "PLANE")
    })
    interface Vehicle {
        VehicleType getVehicleType();
        String getName();
    }
    

    With this the deserialization will work with interface and you will get a List<Vehicle> back

    You can check out the code here - https://github.com/chatterjeesunit/java-playground/blob/master/src/main/java/com/play/util/jackson/PolymorphicDeserialization.java

    0 讨论(0)
  • 2020-11-27 14:46

    @JsonSubTypes.Type must have a value and a name like this,

    @JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=As.WRAPPER_OBJECT, property="type")
    @JsonSubTypes({       
        @JsonSubTypes.Type(value=Dog.class, name="dog"),
        @JsonSubTypes.Type(value=Cat.class, name="cat")       
    }) 
    

    In the subclass, use @JsonTypeName("dog") to say the name.
    The values dog and cat will be set in the property named type.

    0 讨论(0)
提交回复
热议问题