Jackson JsonTypeInfo.As.EXTERNAL_PROPERTY 没有按预期工作 [英] Jackson JsonTypeInfo.As.EXTERNAL_PROPERTY doesn't work as expected

查看:17
本文介绍了Jackson JsonTypeInfo.As.EXTERNAL_PROPERTY 没有按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Jackson 来解析我无法控制的 JSON.JSON 如下所示:

I am using Jackson to parse JSON that I have no control over. The JSON looks like this:

{
    "status":"0"
    "type":"type1"
    "info": {
       // additional fields
    }
}

我的班级是这样的

public class Response {
    private String status;
    private String type;
    private Info info
}

我使用的 Info 的子类取决于 type 属性,所以我的 info 映射是

The subclass of Info that I use depends on the type property, so my mapping for info is

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
@JsonSubTypes(value = {
        @JsonSubTypes.Type(value = Type1Info.class, name = "type1"),
        @JsonSubTypes.Type(value = Type2Info.class, name = "type2") })
public abstract class Info {
    // some fields
}

据我所知,当区别元素与必须转换的元素处于同一级别时,这是使用类型信息的正确方法.但这不起作用,我总是收到相同的错误:

As far as I can tell this is the correct way to use type info when the distinguishing element is at the same level as the element that has to be casted. But this doesn't work, I always get the same error:

com.fasterxml.jackson.databind.JsonMappingException:意外的令牌(END_OBJECT),预期的 FIELD_NAME:缺少属性类型"包含类型 ID

com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'type' that is to contain type id

如果我将 EXTERNAL_PROPERTY 更改为 PROPERTY,我仍然会遇到相同的错误.我对 EXTERNAL_PROPERTY 的理解有误吗?

If I change EXTERNAL_PROPERTY to PROPERTY I still get the same error. Is my understanding of EXTERNAL_PROPERTY wrong?

推荐答案

来自 Javadoc:

From Javadoc:

类似于PROPERTY的包含机制,除了property是在层次结构中包含更高一级,即作为兄弟属性在与要键入的 JSON 对象相同的级别.注意这个选择只能是用于属性,而不是用于类型(类).试图将其用于类将导致基本属性的包含策略.

Inclusion mechanism similar to PROPERTY, except that property is included one-level higher in hierarchy, i.e. as sibling property at same level as JSON Object to type. Note that this choice can only be used for properties, not for types (classes). Trying to use it for classes will result in inclusion strategy of basic PROPERTY instead.

注意到只能用于属性是粗体的.来源:JsonTypeInfo.As.EXTERNAL_PROPERTY.

Noticed that can only be used for properties is bolded. Source: JsonTypeInfo.As.EXTERNAL_PROPERTY.

因此,您必须将所有注释从 Info 类移动到 Response 中的属性 infosetInfo 方法班级.

So, you have to move all annotation from Info class to property info or setInfo method in Response class.

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
@JsonSubTypes(value = { @JsonSubTypes.Type(value = Type1Info.class, name = "type1"),
        @JsonSubTypes.Type(value = Type2Info.class, name = "type2") })
public void setInfo(Info info) {
    this.info = info;
}

对我来说,您还应该从 Response 类中删除 type 属性.它将在序列化过程中动态生成.在反序列化中你不需要它,因为杰克逊关心类型.您的课程可能如下所示:

For me, you should also remove type property from Response class. It will be generated dynamically during serialization process. In deserialization you do not need it because Jackson cares about types. Your class could look like this:

class Response {

    private String status;
    private Info info;

    //getters, setters
}

另见这个问题:JSON 嵌套类数据绑定.

这篇关于Jackson JsonTypeInfo.As.EXTERNAL_PROPERTY 没有按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆