我正在处理这个问题。让我们说我有这样的回应:
{
"id":"decaa828741611e58bcffeff819cdc9f",
"statement":"question statement",
"exercise_type":"QUESTION"
}
然后,根据 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 {}
所以我创建我的ObjectMapper
如下
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(ExerciseResponseDTO.class, ExerciseMixIn.class);
我的测试:
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
问题在于,出于某种原因,在@JsonTypeInfo
上用作属性的 exercise_type 属性被映射为 null 。
知道如何解决这个问题吗?
答案 0 :(得分:74)
最后,我在API Doc
中找到了解决方案关于类型标识符可见性的注意事项:默认情况下,反序列化 (在读取JSON期间使用)类型标识符已完全处理 由杰克逊,并没有传递给反序列化者。但是,如果是这样 期望,可以在其中定义属性visible = true case属性将按原样传递给反序列化器(并通过设置 反序列化的setter或字段。
因此,解决方案只是添加' 可见'属性如下
@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
{}
希望这有助于其他人。
答案 1 :(得分:3)
根据@jscherman answer的设置,JsonTypeInfo中的“ visible”为true将有助于以字段的形式访问exercise_type。
如果您也使用同一类进行序列化,则生成的JSON将具有exercise_type出现两次。因此最好也将include更新为JsonTypeInfo.As.EXISTING_PROPERTY
值得一看的是all other options的包含内容。