jackson 注释中的多态性:@JsonTypeInfo 用法

新手上路,请多包涵

我想知道 @JsonTypeInfo 注释是否可以用于接口。我有一组应该被序列化和反序列化的类。

这是我正在尝试做的。我有两个实现类 Sub1Sub2 实现 MyInt 。一些模型类具有实现类型的接口引用。我想反序列化基于多态性的对象

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=As.WRAPPER_OBJECT)
@JsonSubTypes({
    @Type(name="sub1", value=Sub1.class),
    @Type(name="sub2", value=Sub2.class)})
public interface MyInt{
}

@JsonTypeName("sub1")
public Sub1 implements MyInt{
}

@JsonTypeName("sub2")
public Sub2 implements MyInt{
}

我得到以下 JsonMappingException

意外的标记 (END_OBJECT),预期的 FIELD_NAME:需要包含类型 ID 的 JSON 字符串

原文由 Chris 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

@JsonSubTypes.Type 必须有这样的值和名称,

 @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")
})

在子类中,用 @JsonTypeName("dog") 说名字。

dogcat 将在名为 type 的属性中设置。

原文由 Senthil Kumar 发布,翻译遵循 CC BY-SA 4.0 许可协议

是的,它可以用于抽象类和接口。

考虑以下代码示例

假设我们有一个 enum , interface 和 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;
    }
}

如果我们尝试将此 json 反序列化为 List<Vehicle>

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

然后我们会得到错误

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

要解决此问题,只需在界面中添加以下 JsonSubTypesJsonTypeInfo 注释,如下所示

@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();
}

有了这个反序列化将与接口一起工作,你将得到一个 List<Vehicle> 返回

您可以在此处查看代码 - https://github.com/chatterjeesunit/java-playground/blob/master/src/main/java/com/play/util/jackson/PolymorphicDeserialization.java

原文由 Sunit Chatterjee 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题