Java 无法构造-Jackson的实例
我正在使用Jackson,但遇到问题,当我尝试反序列化对象时,出现以下错误:Java 无法构造-Jackson的实例,java,jackson,Java,Jackson,我正在使用Jackson,但遇到问题,当我尝试反序列化对象时,出现以下错误: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of net.MyAbstractClass, problem: abstract types either need to be mapped to concrete types, have custom deserial
com.fasterxml.jackson.databind.JsonMappingException:
Can not construct instance of net.MyAbstractClass,
problem: abstract types either need to be mapped to concrete types,
have custom deserializer, or be instantiated with additional type information
我在属性中遇到问题:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT, property = "@id")
@JsonSubTypes({ @JsonSubTypes.Type(value = MyAbstractClass.class, name = "MyAbstractClass") })
@ManyToOne
private MyAbstractClass object;
有人能帮我吗?您也不能实例化抽象类。 您应该向Jackson提供关于如何用具体类型实例化MyAbstractClass的信息 请参阅有关stackoverflow的回答:
也许还会看到你的
@JsonSubTypes
声明没有意义:它需要列出实现(子)类,而不是类本身(这将是毫无意义的)。因此,您需要修改该条目以列出存在的子类;或者使用其他机制来注册子类(SimpleModule
具有类似于addAbstractTypeMapping
)的功能。对于我来说,没有为我尝试使用的POJO定义默认构造函数。创建默认构造函数修复了它
public class TeamCode {
@Expose
private String value;
public String getValue() {
return value;
}
**public TeamCode() {
}**
public TeamCode(String value) {
this.value = value;
}
@Override
public String toString() {
return "TeamCode{" +
"value='" + value + '\'' +
'}';
}
public void setValue(String value) {
this.value = value;
}
}
反序列化时需要使用具体类,而不是抽象类。 如果抽象类有几个实现,那么在这种情况下,您可以按如下方式使用它-
@JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@Type(value = Bike.class, name = "bike"),
@Type(value = Auto.class, name = "auto"),
@Type(value = Car.class, name = "car")
})
public abstract class Vehicle {
// fields, constructors, getters, setters
}
在您的具体示例中,问题在于您没有正确使用此结构:
@JsonSubTypes({ @JsonSubTypes.Type(value = MyAbstractClass.class, name = "MyAbstractClass") })
@JsonSubTypes.Type
应包含抽象类的实际非抽象子类型
因此,如果您有:
抽象类父类
和具体子类
Ch1扩展父级
和
Ch2扩展父级
那么您的注释应该如下所示:
@JsonSubTypes({
@JsonSubTypes.Type(value = Ch1.class, name = "ch1"),
@JsonSubTypes.Type(value = Ch2.class, name = "ch2")
})
此处的name
应与“鉴别器”的值匹配:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.WRAPPER_OBJECT,
property = "type")
在属性
字段中,它等于类型
。因此,type
将是键,您在name
中设置的值将是值
因此,当json字符串出现时,如果它具有以下形式:
{
"type": "ch1",
"other":"fields"
}
Jackson将自动将其转换为Ch1
类
如果您发送此邮件:
{
"type": "ch2",
"other":"fields"
}
您将获得一个
Ch2
实例。感谢您的帮助,我通过以下方式解决:JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“class”)
我的JSON中出现了PROPERTY=“class”
,通知将使用哪个子类。当心,允许用户指定在反序列化过程中使用哪个类可能会导致以下漏洞。感谢您的引用:@JsonTypeInfo(use=JsonTypeInfo.Id.class,include=JsonTypeInfo.as.PROPERTY,PROPERTY=“@class”)可以解决此问题。类似于JPA表描述符值。谢谢。关于类似案例的另一个讨论在。特别有趣的是,注释中指出要使用@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“type”)
。这样一来,JSON就大了一点,但它是显式的,应该使用哪种类型。也许可以添加一个例子来帮助将来为我工作的人。值得一提的是,Vehicle
有一个字段type
,它将根据定义的名称创建正确的对象。解释得很好。必须将include=JsonTypeInfo.As.EXTERNAL\u属性设置为才能让它为我工作。