jsc*_*man 44 java jackson json-deserialization
我正在处理这个问题.假设我有这样的回答:
{
"id":"decaa828741611e58bcffeff819cdc9f",
"statement":"question statement",
"exercise_type":"QUESTION"
}
Run Code Online (Sandbox Code Playgroud)
然后,基于exercise_type属性,我想实例化不同的对象实例(子类ExerciseResponseDTO),所以我创建了这个混合:
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "exercise_type")
@JsonSubTypes({
@Type(value = ExerciseChoiceResponseDTO.class, name = "CHOICE"),
@Type(value = ExerciseQuestionResponseDTO.class, name = "QUESTION")})
public abstract class ExerciseMixIn
{}
public abstract class ExerciseResponseDTO {
private String id;
private String statement;
@JsonProperty(value = "exercise_type") private String exerciseType;
// Getters and setters
}
public class ExerciseQuestionResponseDTO
extends ExerciseResponseDTO {}
public class ExerciseChoiceResponseDTO
extends ExerciseResponseDTO {}
Run Code Online (Sandbox Code Playgroud)
所以我创建ObjectMapper如下
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(ExerciseResponseDTO.class, ExerciseMixIn.class);
Run Code Online (Sandbox Code Playgroud)
我的测试:
ExerciseResponseDTO exercise = mapper.readValue(serviceResponse, ExerciseResponseDTO.class)
Assert.assertTrue(exercise.getClass() == ExerciseQuestionResponseDTO.class); // OK
Assert.assertEquals("decaa828741611e58bcffeff819cdc9f" exercise.getId()); // OK
Assert.assertEquals("question statement", exercise.getStatement()); // OK
Assert.assertEquals("QUESTION", exercise.getExerciseType()); // FAIL. Expected: "QUESTION", actual: null
Run Code Online (Sandbox Code Playgroud)
问题在于,由于某种原因,用作属性on 的exercise_type属性@JsonTypeInfo被映射为null.知道如何解决这个问题吗?
jsc*_*man 84
最后,我在API Doc中找到了解决方案
关于类型标识符可见性的注意事项:默认情况下,类型标识符的反序列化(在读取JSON期间使用)完全由Jackson处理,并且不会传递给反序列化器.但是,如果需要,可以定义属性visible = true,在这种情况下,属性将在反序列化时按原样传递给反序列化器(并通过setter或field设置).
所以解决方案只是添加' visible '属性,如下所示
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "exercise_type",
visible = true)
@JsonSubTypes({
@Type(value = ExerciseChoiceResponseDTO.class, name = "CHOICE"),
@Type(value = ExerciseQuestionResponseDTO.class, name = "QUESTION")})
public abstract class ExerciseMixIn
{}
Run Code Online (Sandbox Code Playgroud)
希望这有助于其他人.
小智 5
根据@jscherman通过设置回答,JsonTypeInfo 中的'visible' true 将有助于将运动类型作为字段访问。
如果您也使用相同的类进行序列化,那么生成的 JSON 将出现两次运动类型。所以最好也更新包含到JsonTypeInfo.As.EXISTING_PROPERTY
并且还值得查看包含的所有其他选项。