杰克逊解析包含对象数组和映射数组的JSON,其中包含动态键

8

我有一个类似这样的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对象映射字符串->用户,例如:

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包装器来完成,但如果那些映射是我唯一得到的类型,我才能想出一种方法来做到这一点。由于我正在获取不同的类型返回(用户和工作),是否可能做到这一点呢?


你的 JSON 不合法。例如,在“Anderson”后面你有一个逗号。 - Bertrand Martel
抱歉,那是我的笔误,我已经修正了。现在应该是有效的 JSON 格式了。 - pat
2个回答

11

解决方案:

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

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

0

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

请参阅jackson文档,了解如何编写自己的反序列化器。

我还想说,如果您可以控制json结构-我建议更改键值(我猜是用户ID)以成为实际json对象的一部分,而不是键。这将帮助您完全避免此问题。

例如:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接