I have this response:
{
"id":"decaa828741611e58bcffeff819cdc9f",
"statement":"question statement",
"exercise_type":"QUESTION"
}
Then, based on exercise_type attribute, I want to instantiate different objects instances (subclasses of ExerciseResponseDTO
), so I create this mix in:
@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 {}
So I create my ObjectMapper
as follows
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(ExerciseResponseDTO.class, ExerciseMixIn.class);
My test:
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
The problem is that, for some reason, the exercise_type attribute being used as property on @JsonTypeInfo
is being mapped as null . Any idea how i can solve this?
Finally, I've found the solution in the 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.
So the solution was simply adding the ' visible ' attribute as follows
@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
{}
Hope this helps someone else.
As per @jscherman answer by setting, 'visible' true in JsonTypeInfo will help in accessing exercise_type as a field.
If you use the same class to serialize also then resulting JSON will have exercise_type appear twice. So it's better to also update include to JsonTypeInfo.As.EXISTING_PROPERTY
And it's also worth looking at all other options for include.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.