杰克逊反序列化具有未知的动态属性

时间:2022-11-20 18:01:27

I have a JSON string like:

我有一个JSON字符串,如:

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

Now I am parsing it with Jackson 2.0. I am trying to get a List<shipping_profiles> from the JSON string.

现在我用Jackson 2.0解析它。我想从JSON字符串中获取List

Is it possible?

可能吗?

2 个解决方案

#1


20  

Your shipping_profiles property doesn't look like array. It represent object with dynamic properties, so we should treat it like an object. If we do not know anything about properties we can use @JsonAnySetter annotation. Algorithm could looks like below:

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

  1. Deserialize JSON into JSON-model classes.
  2. 将JSON反序列化为JSON模型类。
  3. Convert dynamic objects (maps) into app's POJO classes using ObjectMapper
  4. 使用ObjectMapper将动态对象(贴图)转换为app的POJO类
  5. Use app's POJO whenever you want.
  6. 随时使用应用程序的POJO。

Please see my example implementation. I hope, it help you solve your problem. Input JSON:

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

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

Example program:

示例程序:

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 + "]";
    }
}

Above app prints:

以上app打印:

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

#2


0  

I got my json with dynamic property parsed with the way @michalziober provide.

我用我的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"
         }

With this json I also need to save that dynamic property, so I add another List for storing it.

有了这个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;
    }
}

Now I can also access the field as id to send out request later.

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

#1


20  

Your shipping_profiles property doesn't look like array. It represent object with dynamic properties, so we should treat it like an object. If we do not know anything about properties we can use @JsonAnySetter annotation. Algorithm could looks like below:

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

  1. Deserialize JSON into JSON-model classes.
  2. 将JSON反序列化为JSON模型类。
  3. Convert dynamic objects (maps) into app's POJO classes using ObjectMapper
  4. 使用ObjectMapper将动态对象(贴图)转换为app的POJO类
  5. Use app's POJO whenever you want.
  6. 随时使用应用程序的POJO。

Please see my example implementation. I hope, it help you solve your problem. Input JSON:

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

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

Example program:

示例程序:

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 + "]";
    }
}

Above app prints:

以上app打印:

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

#2


0  

I got my json with dynamic property parsed with the way @michalziober provide.

我用我的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"
         }

With this json I also need to save that dynamic property, so I add another List for storing it.

有了这个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;
    }
}

Now I can also access the field as id to send out request later.

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