Jackson 使用子类反序列化
Jackson Deserialize with Subclasses
好的,我知道有很多类似的问题,但似乎都没有用。
我为我的实体设置了以下结构。
public abstract class MyAbstractClass {
// bunch of properties, getters, and setters that subclasses share
public abstract String getType();
}
public class MySubclass1 extends MyAbstractClass {
// a few unique properties, getters, and setters
public String getType() {
return "Type_1"; //always the same for each instance of MySubclass1
}
}
public class MySubclass2 extends MyAbstractClass {
// a few unique properties, getters, and setters
public String getType() {
return "Type_2"; //always the same for each instance of MySubclass2
}
}
在我的控制器中,我尝试将请求映射到以下方法。
public @RequestBody MyAbstractClass saveObject(@RequestBody MyAbstractClass mac) {
// call model to save object
}
我想对 2 个实体使用 1 种控制器方法而不是单独的方法。但是使用上面的结果如下。
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of path.to.my.entity.MyAbstractClass, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
有道理。
尝试 1
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="implementingClass")
public abstract class MyAbstractClass
我认为它的作用 - 添加一个元数据 implementingClass
属性 来存储子 class class。
结果是什么。
Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'implementingClass' that is to contain type id (for class path.to.my.entity.MyAbstractClass)
在 property
中尝试使用 "class" 而不是 "implementingClass" 并得到了相似的结果。
尝试 2
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({
@Type(name="MySubclass1", value=MySubclass1.class),
@Type(name="MySubclass2", value=MySubclass2.class)
})
public abstract class MyAbstractClass
我认为它的作用 - 使用定义的 name
进行某种包装。
结果是什么。
Could not resolve type id 'myUuid' into a subtype of [simple type, class path.to.my.entity.MyAbstractClass]
即使将 @JsonTypeName("MySubclass1")
和 @JsonTypeName("MySubclass2")
添加到 2 个子 class 中,结果也相同。
其他尝试
我尝试了很多。什么都不管用。这里不会包括所有内容。
我觉得应该有一个简单的方法来做到这一点,但我一直在错误地配置东西。
我觉得 getType
可能会被利用,但我不想为类型添加实际的 属性(它只是一个辅助方法)。我也想用注释而不是其他选项来做到这一点。
谢谢。
我知道了,但我想我会回答,以防其他人遇到这个问题。
我向我的子类添加了 type
属性 而不仅仅是辅助方法(下面包含一个示例)。
public class MySubclass1 extends MyAbstractClass {
@Transient
private final String type = "TYPE_1";
public String getType() {
return type;
}
}
然后我为我的抽象超类做了以下操作。
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type")
@JsonSubTypes({
@Type(name="TYPE_1", value=MySubclass1.class),
@Type(name="TYPE_2", value=MySubclass2.class)
})
public abstract class MyAbstractClass
在提供 JSON 时,我确定要包含类型。我不会包括这个,因为它是一种奇怪的击倒精神错乱。
不太好。但它奏效了。
好的,我知道有很多类似的问题,但似乎都没有用。
我为我的实体设置了以下结构。
public abstract class MyAbstractClass {
// bunch of properties, getters, and setters that subclasses share
public abstract String getType();
}
public class MySubclass1 extends MyAbstractClass {
// a few unique properties, getters, and setters
public String getType() {
return "Type_1"; //always the same for each instance of MySubclass1
}
}
public class MySubclass2 extends MyAbstractClass {
// a few unique properties, getters, and setters
public String getType() {
return "Type_2"; //always the same for each instance of MySubclass2
}
}
在我的控制器中,我尝试将请求映射到以下方法。
public @RequestBody MyAbstractClass saveObject(@RequestBody MyAbstractClass mac) {
// call model to save object
}
我想对 2 个实体使用 1 种控制器方法而不是单独的方法。但是使用上面的结果如下。
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of path.to.my.entity.MyAbstractClass, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
有道理。
尝试 1
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="implementingClass")
public abstract class MyAbstractClass
我认为它的作用 - 添加一个元数据 implementingClass
属性 来存储子 class class。
结果是什么。
Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'implementingClass' that is to contain type id (for class path.to.my.entity.MyAbstractClass)
在 property
中尝试使用 "class" 而不是 "implementingClass" 并得到了相似的结果。
尝试 2
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({
@Type(name="MySubclass1", value=MySubclass1.class),
@Type(name="MySubclass2", value=MySubclass2.class)
})
public abstract class MyAbstractClass
我认为它的作用 - 使用定义的 name
进行某种包装。
结果是什么。
Could not resolve type id 'myUuid' into a subtype of [simple type, class path.to.my.entity.MyAbstractClass]
即使将 @JsonTypeName("MySubclass1")
和 @JsonTypeName("MySubclass2")
添加到 2 个子 class 中,结果也相同。
其他尝试
我尝试了很多。什么都不管用。这里不会包括所有内容。
我觉得应该有一个简单的方法来做到这一点,但我一直在错误地配置东西。
我觉得 getType
可能会被利用,但我不想为类型添加实际的 属性(它只是一个辅助方法)。我也想用注释而不是其他选项来做到这一点。
谢谢。
我知道了,但我想我会回答,以防其他人遇到这个问题。
我向我的子类添加了 type
属性 而不仅仅是辅助方法(下面包含一个示例)。
public class MySubclass1 extends MyAbstractClass {
@Transient
private final String type = "TYPE_1";
public String getType() {
return type;
}
}
然后我为我的抽象超类做了以下操作。
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type")
@JsonSubTypes({
@Type(name="TYPE_1", value=MySubclass1.class),
@Type(name="TYPE_2", value=MySubclass2.class)
})
public abstract class MyAbstractClass
在提供 JSON 时,我确定要包含类型。我不会包括这个,因为它是一种奇怪的击倒精神错乱。
不太好。但它奏效了。