为属性选择什么@ JsonTypeInfo.ID ="type.id";用于反序列化,JsonTypeInfo.Id.CUSTOM吗? [英] What @JsonTypeInfo.ID to choose for property = "type.id" for deserialization, JsonTypeInfo.Id.CUSTOM?

查看:1281
本文介绍了为属性选择什么@ JsonTypeInfo.ID ="type.id";用于反序列化,JsonTypeInfo.Id.CUSTOM吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个看起来像这样的JSON:

So I have JSON that looks like this:

{
    "ActivityDisplayModel" : {
        "name" : "lunch with friends",
        "startTime" : "12:00:00",
        "type" : {
            "id" : "MEAL",
            "description" : "Meal"
        },
        "complete" : false
    }
}

我正在尝试找到一种方法,以使@JsonTypeInfo不会因为在type对象中包含类型参数而对我发火.在字段type是String而不是对象本身之前,我已经完成了此工作,但是在以后的处理中,我需要将它作为对象.我知道以下内容不起作用,并且我猜想有一种方法可以使用

I'm trying to find the way to get @JsonTypeInfo to not be mad at me for having the type parameter inside the type object. I've got this working before when the field type was a String and not an object itself, but for later processing I need it as an object. I know the following doesn't work, and I'm guessing theres a way to use JsonTypeInfo.Id.CUSTOM, but after looking all over on the internet, no fully examples with JSON have come up. Also, if this is possible with an objectMapper setting, I'm all ears.

/** 
 * My ActivityDisplayModel Abstract Class
 */
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type.id")
@JsonSubTypes({
@JsonSubTypes.Type(value = MealDisplayModel.class, name = "MEAL"),
@JsonSubTypes.Type(value = EntertainmentDisplayModel.class, name = "ENTERTAINMENT")
})
public abstract class ActivityDisplayModel { 
    ...

以上本质上是我想要做的,但是我当然有一个例外:

The above is essentially what I want to do, but of course I get an exception of:

Could not read JSON: Could not resolve type id '{' into a subtype of  [simple type, class ... .ActivityDisplayModel]

对于这样一个简单的问题,即仅在JSON中更深入地研究一个层次,谁会认为这会带来很多麻烦?

For such a simple problem of just looking one level deeper in the JSON, who would have thought it would have been so much trouble?

推荐答案

我不确定是否可以通过指定内部属性type.id来做到这一点.我认为您应该将JSON更改为简单版本.如果您不能强制JSON供应商更改JSON模式,则必须手动执行.假设您的JSON如下所示:

I am not sure that you can do it with specifying inner property: type.id. In my opinion you should change your JSON to simpler version. If you can not force your JSON supplier to change JSON schema you have to do it manually. Assume that your JSON looks like below:

{
    "activityDisplayModel": {
        "name": "lunch with friends",
        "type": {
            "id": "MEAL",
            "description": "Meal"
        },
        "complete": false
    }
}

下面的POJO类适合上面的JSON:

Below POJO classes fit to above JSON:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = MealDisplayModel.class, name = "MEAL"),
    @JsonSubTypes.Type(value = EntertainmentDisplayModel.class, name = "ENTERTAINMENT")
})
abstract class ActivityDisplayModel {

    protected String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }
}

class MealDisplayModel extends ActivityDisplayModel {

    private boolean complete;

    public boolean isComplete() {
        return complete;
    }

    public void setComplete(boolean complete) {
        this.complete = complete;
    }

    @Override
    public String toString() {
        return "MealDisplayModel [complete=" + complete + ", toString()=" + super.toString() + "]";
    }
}

@JsonIgnoreProperties("complete")
class EntertainmentDisplayModel extends ActivityDisplayModel {

    @Override
    public String toString() {
        return "EntertainmentDisplayModel [toString()=" + super.toString() + "]";
    }
}

class Root {

    private ActivityDisplayModel activityDisplayModel;

    public ActivityDisplayModel getActivityDisplayModel() {
        return activityDisplayModel;
    }

    public void setActivityDisplayModel(ActivityDisplayModel activityDisplayModel) {
        this.activityDisplayModel = activityDisplayModel;
    }

    @Override
    public String toString() {
        return activityDisplayModel.toString();
    }
}

下面的脚本显示了如何在JSON上方进行解析:

Below script shows how you can parse above JSON:

ObjectMapper mapper = new ObjectMapper();
// Updated JSON in memory
ObjectNode rootNode = (ObjectNode)mapper.readTree(json);
ObjectNode activityDisplayModelNode = (ObjectNode)rootNode.path("activityDisplayModel");
JsonNode typeNode = activityDisplayModelNode.path("type");
activityDisplayModelNode.set("type", typeNode.path("id"));

System.out.println("Result: " + mapper.convertValue(rootNode, Root.class));

上面的脚本打印:

Result: MealDisplayModel [complete=false, toString()=lunch with friends]

另请参阅:

  1. 杰克逊树模型示例.
  2. 将Java对象转换为Jackson中的JsonNode.
  3. . >
  1. Jackson Tree Model Example.
  2. Convert Java Object to JsonNode in Jackson.

这篇关于为属性选择什么@ JsonTypeInfo.ID ="type.id";用于反序列化,JsonTypeInfo.Id.CUSTOM吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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