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

时间:2013-07-16 19:38:10

标签: java json jackson

我有一个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>

有可能吗?

2 个答案:

答案 0 :(得分:20)

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

  1. 将JSON反序列化为JSON模型类。
  2. 使用ObjectMapper
  3. 将动态对象(地图)转换为应用程序的POJO类
  4. 随时使用应用程序的POJO。
  5. 请参阅我的示例实现。我希望,它可以帮助您解决问题。输入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]]
    

答案 1 :(得分:0)

我使用@michalziober提供的方式解析了我的json动态属性。

"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以便稍后发送请求。