简体   繁体   English

Jackson - @JsonTypeInfo 属性被映射为 null?

[英]Jackson - @JsonTypeInfo property is being mapped as null?

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:然后,基于运动类型属性,我想实例化不同的对象实例( 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 {}

So I create my ObjectMapper as follows所以我创建我的ObjectMapper如下

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 .问题是,出于某种原因,在@JsonTypeInfo上用作属性的运动类型属性被映射为null Any idea how i can solve this?知道我该如何解决这个问题吗?

Finally, I've found the solution in the API Doc最后,我在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.关于类型标识符可见性的注意事项:默认情况下,类型标识符的反序列化(在读取 JSON 期间使用)完全由 Jackson 处理,不会传递给反序列化器。 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 = true 在这种情况下,属性将在反序列化时按原样传递给反序列化器(并通过 setter 或字段设置)。

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.根据@jscherman通过设置回答JsonTypeInfo 中的'visible' true 将有助于将运动类型作为字段访问。

If you use the same class to serialize also then resulting JSON will have exercise_type appear twice.如果您也使用相同的类进行序列化,那么生成的 JSON 将出现两次运动类型。 So it's better to also update include to JsonTypeInfo.As.EXISTING_PROPERTY所以最好也更新包含到JsonTypeInfo.As.EXISTING_PROPERTY

And it's also worth looking at all other options for include.并且还值得查看包含的所有其他选项

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM