Подтвердить что ты не робот

Свойство Jackson - @JsonTypeInfo отображается как 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 

Проблема заключается в том, что по какой-либо причине атрибут exercise_type, используемый как свойство на @JsonTypeInfo, отображается как null. Любая идея, как я могу это решить?

4b9b3361

Ответ 1

Наконец, я нашел решение в API Doc

Примечание о видимости идентификатора типа: по умолчанию десериализация (использование во время чтения JSON) идентификатора типа полностью обрабатывается Джексоном и не передается десериализаторам. Однако, если это необходимо, можно определить свойство visible = true, в этом случае свойство будет передано десериализаторам как есть (и установлено через установщик или поле) при десериализации.

Таким образом, решение было просто добавить атрибут "видимый" следующим образом

@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  
{}  

Надеюсь, это поможет кому-то еще.

Ответ 2

Согласно ответу @jscherman путем установки, "visible" true в JsonTypeInfo поможет получить доступ к упражнению в качестве поля.

Если вы используете тот же класс для сериализации, то в результате JSON будет иметь типerc_type дважды. Поэтому лучше также обновить include до JsonTypeInfo.As.EXISTING_PROPERTY

И также стоит посмотреть на все остальные варианты включения.