我想知道@JsonTypeInfo
注释是否可用于接口。我有一组应该序列化和反序列化的类。
这是我正在尝试做的事情。我有两个实现类Sub1
,Sub2
实现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
答案 0 :(得分:45)
@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")
来表示名称
值dog
和cat
的值将在名为type
的属性中设置。
答案 1 :(得分:1)
是的,它可以用于抽象类和接口。
考虑以下代码示例
假设我们有一个enum,接口和类
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
要解决此问题,只需在界面上添加以下JsonSubTypes
和JsonTypeInfo
批注,如下所示
@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>
的回馈