【问题标题】:Polymorphism in jackson annotations: @JsonTypeInfo usage杰克逊注解中的多态性:@JsonTypeInfo 用法
【发布时间】:2012-08-01 15:50:17
【问题描述】:

我想知道@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:需要 JSON 字符串 包含类型 id

【问题讨论】:

  • 你看到了吗? jackson-users.ning.com/forum/topics/…你有没有像其他线程中讨论的那样没有提到类型的列表?
  • 我认为您需要显示更多代码(如何完成序列化、反序列化),以及生成/使用的 JSON。

标签: java polymorphism jackson deserialization


【解决方案1】:

@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 的属性中设置。

【讨论】:

  • 有谁知道 JsonTypeInfo 是否可以应用于接口?
  • 更新了答案,在@JSONTypeInfo 中添加属性,看看它是否有效,抱歉我之前没有注意到。
  • 是的,@JsonTypeInfo 可以用于接口,如果有帮助的话(Jackson 的注解处理确实支持继承)
  • 但是如果其他人试图实现你的接口怎么办?如果不在接口文件中添加注释,则无法将名为“sub3”的新具体类型解组到 MyInt。
  • 这里有很好的解释和更新的例子:davismol.net/2015/03/05/…
【解决方案2】:

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

考虑以下代码示例

假设我们有一个枚举、接口和类

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-30
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 2020-01-29
    • 2023-04-03
    • 2018-01-08
    • 2020-03-31
    相关资源
    最近更新 更多