杰克逊解析包含对象数组和带动态键的地图数组的JSON

时间:2013-07-28 03:56:41

标签: java android json jackson

我有这样的json:

{

    "users":{
           "1234":{
                 "firstname":"Joe",
                 "lastname":"Smith"
           },
           "9876":{
                 "firstname":"Bob",
                 "lastname":"Anderson"
           }
    },
    "jobs":[
          {
              "id":"abc",
              "location":"store"
          },
          {
              "id":"def",
              "location":"factory"
          }
    ]
}

我正在使用Jackson进行解析,因此我使用以下方法解析响应:readvalue(json,MyCustomClass.class)

MyCustomClass的样子

public class MyCustomClass{
      @JsonProperty("jobs")
      ArrayList<Job> jobs;

      @JsonProperty("users")
      ArrayList<UserMap> usersMap;
}

现在,作业完全解析为Jobs对象,但我无法让用户解析,因为它们具有动态键。我阅读了JsonAnyGetter / Setter并尝试制作映射字符串的UserMap对象图 - &gt;用户喜欢:

public class UserMap {

private HashMap<String,User> usersMap;


@JsonAnySetter
public void add(String key, User user){
    usersMap.put(key, user);
}

@JsonAnyGetter
public Map<String, User> getUsersMap(){
    return usersMap;
}


}

但这不起作用。我想我可以使用TypeReference包装器做到这一点,但如果这些地图是我回来的唯一类型,我只能想到一种方法。由于我得到不同的类型(用户和工作)是否可以这样做?

2 个答案:

答案 0 :(得分:10)

解决方案:

public class MyCustomClass {
    @JsonProperty("users")
    public LinkedHashMap<String, User> users;

    @JsonProperty("jobs")
    public ArrayList<Job> jobs;
}    

答案 1 :(得分:0)

您可以通过编写自己的自定义反序列化器并将其注册到您正在使用的对象映射器来解决此问题。这应该有效,因为您可以完全控制每个对象如何反序列化为User对象。

有关如何滚动自己的反序列化程序,请参阅this jackson documentation

还想说,如果你能控制json结构 - 我会改变键值(我猜是用户的ID)是实际json对象的一部分,而不是键。这将有助于您一起避免这个问题。

例如:

"users":{
       {
             "id":"1234",
             "firstname":"Joe",
             "lastname":"Smith"
       },
       {
             "id":"9876",
             "firstname":"Bob",
             "lastname":"Anderson"
       }