将嵌套的JSON映射到Java POJO

3

我正在使用Jackson将嵌套的JSON响应映射到POJO时遇到困难。目前,Users类中的值返回为null。

JSON:

{
"users": [
    {
        "username": "johnSmith123",
        "email": "johnSmith123@gmail.com",
        "birthday": "1989-10-23"
    }
]
}

POJO:

public class Users {

  @JsonProperty("username")
  public String username;
  @JsonProperty("email")
  public String email;
  @JsonProperty("birthday")
  public String birthday;

}

控制器方法:

private ObjectMapper mapper = new ObjectMapper();

ResponseEntity<String> response = restTemplate.exchange(
        accountUrl, HttpMethod.GET, entity, String.class);

Users user = mapper.readValue(response.getBody(), Users.class);

我该如何解决这个问题?谢谢。

看起来你已经正确地设置了你的POJO。但是你试图消费的JSON是一个对象集合。所以你需要使用:List<Users> user = mapper.readValue(response.getBody(), new TypeReference<List<Users>>(){}); - KyleAure
嗨,我刚试了一下,但不幸的是出现了以下错误:com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.util.ArrayList<com.package> out of START_OBJECT token. - user2047296
哦,我看到你正在使用Jackson进行JSON绑定。我建议更新到更现代的Jakarta EE兼容的JSON绑定库,例如Yasson。使用这个库,您可以使用以下语法来消耗列表:https://github.com/eclipse-ee4j/jsonb-api/blob/master/docs/src/docs/user-guide.adoc#mapping-a-generic-collection - KyleAure
谢谢您的跟进,但我最终创建了一个包装类作为实现。 - user2047296
1个回答

4

UsersJSON Object 被包裹在 JSON Array 中,该数组又被包裹在根 JSON Object 中。你需要使用集合类型:

TypeReference<Map<String, List<Users>>> usersType = new TypeReference<Map<String, List<Users>>>() {};
Map<String, List<Users>> wrappedUsers = mapper.readValue(body, usersType);
List<Users> users = wrappedUsers.values().stream().flatMap(Collection::stream).collect(Collectors.toList());

或者创建包装类:
class UsersHolder {
    public List<Users> users;

    //getters, setters
}

你可以使用以下方式:

UsersHolder wrappedUsers = mapper.readValue(body, UsersHolder.class);
System.out.println(wrappedUsers.users);

参见:


我添加了包装类,它运行良好。还有一个问题,如果您不介意...是否仍然有意义使用User类,以便我可以像这样访问它:wrappedUsers.users.get(0).getUsername(),或者这被视为不必要的?谢谢 - user2047296
1
@user2047296,实际上这取决于您和您的个人喜好。我可能会选择获取用户:Users user = wrappedUsers.getUsers().get(0);包装类仅用于反序列化,因此不应传递给您应用程序的其他层。 - Michał Ziober
1
那确实有道理,谢谢你的解释 :) - user2047296
我的问题听起来与这个非常相似。我不确定我需要为我的情况做出什么样的改变。你能否帮助我回答这个问题Nested JSON response from SQL View?我时间不多了 :( @MichałZiober - Omega

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