Jackson - @JsonTypeInfo 属性 被映射为 null?
Jackson - @JsonTypeInfo property is being mapped as null?
我有这样的回复:
{
"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 属性被映射为 空。
知道我该如何解决这个问题吗?
最后,我在 API Doc
中找到了解决方案
Note on visibility of type identifier: by default, deserialization
(use during reading of JSON) of type identifier is completely handled
by Jackson, and is not passed to deserializers. However, if so
desired, it is possible to define property visible = true in which
case property will be passed as-is to deserializers (and set via
setter or field) on deserialization.
所以解决方案只是简单地添加“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
{}
希望这对其他人有帮助。
根据 通过设置,JsonTypeInfo 中的 'visible' true 将有助于将 exercise_type 作为字段访问。
如果您使用相同的 class 进行序列化,那么结果 JSON 将有 exercise_type 出现两次。所以最好也更新 include 到 JsonTypeInfo.As.EXISTING_PROPERTY
并且还值得查看 all other options 以获取包含。
我有这样的回复:
{
"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 属性被映射为 空。
知道我该如何解决这个问题吗?
最后,我在 API Doc
中找到了解决方案Note on visibility of type identifier: by default, deserialization (use during reading of JSON) of type identifier is completely handled by Jackson, and is not passed to deserializers. However, if so desired, it is possible to define property visible = true in which case property will be passed as-is to deserializers (and set via setter or field) on deserialization.
所以解决方案只是简单地添加“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
{}
希望这对其他人有帮助。
根据
如果您使用相同的 class 进行序列化,那么结果 JSON 将有 exercise_type 出现两次。所以最好也更新 include 到 JsonTypeInfo.As.EXISTING_PROPERTY
并且还值得查看 all other options 以获取包含。