【问题标题】:Jackson - @JsonTypeInfo property is being mapped as null?Jackson - @JsonTypeInfo 属性被映射为空?
【发布时间】:2016-02-10 05:18:43
【问题描述】:

我有这样的回应:

{  
    "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。 知道如何解决这个问题吗?

【问题讨论】:

    标签: java jackson json-deserialization


    【解决方案1】:

    终于在API Doc找到了解决办法

    关于类型标识符可见性的注意事项:默认情况下,反序列化 (在读取 JSON 时使用)类型标识符被完全处理 由杰克逊,并没有传递给反序列化器。但是,如果是这样 需要,可以定义属性 visible = true 其中 case 属性将按原样传递给反序列化器(并通过 setter 或字段)关于反序列化。

    所以解决方案只是简单地添加 '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  
    {}  
    

    希望这对其他人有所帮助。

    【讨论】:

    • 你是救生员!
    【解决方案2】:

    根据@jscherman answer,通过设置,JsonTypeInfo 中的 'visible' true 将有助于将 exercise_type 作为字段进行访问。

    如果您也使用相同的类进行序列化,则生成的 JSON 将让 exercise_type 出现两次。所以最好也更新包含到JsonTypeInfo.As.EXISTING_PROPERTY

    还值得关注all other options 的包含。

    【讨论】:

      猜你喜欢
      • 2015-12-21
      • 2016-08-29
      • 2018-09-15
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 2019-11-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多