2015-11-09 20 views
21

Mi sto occupando di questo problema. Diciamo che ho questa risposta:Jackson - La proprietà @JsonTypeInfo viene mappata come null?

{ 
    "id":"decaa828741611e58bcffeff819cdc9f", 
    "statement":"question statement", 
    "exercise_type":"QUESTION" 
} 

Poi, sulla base di exercise_type attributo voglio creare un'istanza di istanze diverse oggetti (sottoclassi di ExerciseResponseDTO), così ho creare questo 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 {} 

Così creo il mio ObjectMapper come segue

ObjectMapper mapper = new ObjectMapper(); 
mapper.addMixIn(ExerciseResponseDTO.class, ExerciseMixIn.class); 

la mia prova:

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 

Il problema è che, per qualche motivo, il exercise_type attributo viene utilizzato come alloggio su @JsonTypeInfo viene mappato come nullo. Qualche idea su come posso risolvere questo?

risposta

40

Infine, ho trovato la soluzione nel API Doc

Nota sulla visibilità di tipo identificativo: per impostazione predefinita, la deserializzazione (uso durante la lettura di JSON) di tipo identificatore è completamente gestita da Jackson, e non è passato ai deserializzatori. Tuttavia, in tal caso desiderato, è possibile definire proprietà visible = true in cui la proprietà del case verrà passata così com'è ai deserializzatori (e impostata tramite setter o campo) in fase di deserializzazione.

Quindi la soluzione era semplicemente aggiungendo il 'visibile' attributo come segue

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

Spero che questo aiuti qualcun altro.

+0

Buona ricerca. :) – Rick

+0

[Wisdom of the Ancients] (https://xkcd.com/979/) –

Problemi correlati