【问题标题】:Jackson deserialization with unknown dynamic properties具有未知动态属性的杰克逊反序列化
【发布时间】:2013-07-15 03:54:59
【问题描述】:

我有一个 JSON 字符串,例如:

"shipping_profiles": {
  "563": {
    "name": "name",
    "value": "value"            
  },
  "564": {
    "name": "name",
    "value": "value"            
  },
  "565": {
    "name": "name",
    "value": "value"            
  },
  "566": {
    "name": "name",
    "value": "value"            
  }
}

现在我用 Jackson 2.0 解析它。 我正在尝试从 JSON 字符串中获取 List<shipping_profiles>

有可能吗?

【问题讨论】:

  • 您能向我们展示一下您的 POJO 类的样子吗?
  • 您确定不希望 shipping_profiles 成为一个数组吗?例如。 “shipping_profiles”:[“563”:{ ... },...]。
  • @Michał Ziober : 到目前为止我还没有设计 POJO。等待您的帮助来设计 POJO
  • @Chris Kessel:不幸的是,是的。这是我得到的最后一个 JSON 字符串。
  • 你能告诉我这些数字是什么意思吗?这是实体 ID 还是您要解析的其他内容?或者你只需​​要“name”和“value”属性?

标签: java json jackson


【解决方案1】:

您的 shipping_profiles 属性看起来不像数组。它表示具有动态属性的对象,因此我们应该将其视为对象。如果我们对属性一无所知,我们可以使用@JsonAnySetter 注释。算法可能如下所示:

  1. 将 JSON 反序列化为 JSON 模型类。
  2. 使用 ObjectMapper 将动态对象(地图)转换为应用的 POJO 类
  3. 随时使用应用的 POJO。

请查看我的示例实现。我希望它可以帮助您解决问题。输入 JSON:

{
   "shipping_profiles":{
      "563":{
         "name":"name563",
         "value":"value563"
      },
      "564":{
         "name":"name564",
         "value":"value564"
      },
      "565":{
         "name":"name565",
         "value":"value565"
      },
      "566":{
         "name":"name566",
         "value":"value566"
      }
   }
}

示例程序:

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonProgram {

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();

        File source = new File("X:/test.json");
        Entity entity = mapper.readValue(source, Entity.class);
        ShippingProfiles shippingProfiles = entity.getShippingProfiles();
        List<Map<String, String>> profileMaps = shippingProfiles.getProfiles();

        List<Profile> profiles = new ArrayList<Profile>(profileMaps.size());
        for (Map<String, String> item : profileMaps) {
            profiles.add(mapper.convertValue(item, Profile.class));
        }
        System.out.println(profiles);
    }
}

class Entity {

    @JsonProperty("shipping_profiles")
    private ShippingProfiles shippingProfiles;

    public ShippingProfiles getShippingProfiles() {
        return shippingProfiles;
    }

    public void setShippingProfiles(ShippingProfiles shippingProfiles) {
        this.shippingProfiles = shippingProfiles;
    }
}

class ShippingProfiles {

    private List<Map<String, String>> profiles = new ArrayList<Map<String, String>>();

    @JsonAnySetter
    public void setDynamicProperty(String name, Map<String, String> map) {
        profiles.add(map);
    }

    public List<Map<String, String>> getProfiles() {
        return profiles;
    }

    public void setProfiles(List<Map<String, String>> profiles) {
        this.profiles = profiles;
    }
}

class Profile {

    private String name;
    private String value;

    public String getName() {
        return name;
    }

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

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Profile [name=" + name + ", value=" + value + "]";
    }
}

应用打印上方:

[Profile [name=name563, value=value563], Profile [name=name564, value=value564], Profile [name=name565, value=value565], Profile [name=name566, value=value566]]

【讨论】:

    【解决方案2】:

    我得到了带有动态属性的 json,使用 @michalziober 提供的方式解析。

    "commandClasses": {
            "32": {
              "name": "Basic",
              "data": {
              "name": "devices.1.instances.1.commandClasses.32.data",
              "value": null,
              "type": "NoneType"
             },
             "38": {
              "name": "SwitchMultilevel",
              "data": {
              "name": "devices.1.instances.1.commandClasses.38.data",
              "value": null,
              "type": "NoneType"
             },
             "43": {
              "name": "SceneActivation",
              "data": {
              "name": "devices.1.instances.1.commandClasses.43.data",
              "value": null,
              "type": "NoneType"
             }
    

    有了这个 json,我还需要保存那个动态属性,所以我添加了另一个 List 来存储它。

    public class CommandClasses {
    
        private List<String> nameList = new ArrayList<String>();
        private List<CommandClass> commmandClasses = new ArrayList<CommandClass>();
        private Logger logger = Logger.getInstance(CommandClasses.class);
    
        @JsonAnySetter
        public void setDynamicCommandClass(String name, CommandClass cc) {
           logger.d("@ adding new CC : " + name);
           nameList.add(name);
           commmandClasses.add(cc);
        }
    
        public List<CommandClass> getCommmandClasses() {
            return commmandClasses;
        }
    
        public void setCommmandClasses(List<CommandClass> commmandClasses) {
            this.commmandClasses = commmandClasses;
        }
    }
    

    现在我也可以访问该字段作为 id 稍后发送请求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-09
      • 1970-01-01
      • 2018-07-01
      相关资源
      最近更新 更多