将Json映射到嵌套的POJO

时间:2018-05-08 07:34:25

标签: java json jackson

我从一些上游api

获得了以下JSON
{
    "Id": "",
    "Name": "",
    "Age": ""
}

我需要将上面的json映射到下游请求paylaod(POJO)。

public class Employee
{
     @JsonProperty("Id")
     private Integer Id;
     private User user;
}

public class User {

     @JsonProperty("Name")
     private String name;

     @JsonProperty("Age")
     private String age;

}

现在我正在做类似

的事情
Employee employee = new ObjectMapper().treeToValue(JsonNode node,Employee.class);

但是这在User Object中给出了null。

这里的挑战是,我们从上游获得的json无法改变。那么,有没有办法将字段映射到嵌套的用户对象,而不更改从上游接收的json的结构。

一个解决方案:将字段分别映射到User对象,然后将其设置为Employee对象。但这不是一个有效的解决方案,因为对于null验证,我们需要分别对User和Employee对象进行验证。如果嵌套很复杂,那么验证将是复制代码的地狱。

3 个答案:

答案 0 :(得分:3)

您的JSON不符合您的Employee课程。

由于nameageid处于同一级别,但您希望将其包含在课程User中。

所以:

  1. 将结构的json更改为

     {
      "id": "", 
      "user": {
        "name": "", 
        "age": ""
       }
     }
    
  2. 或者

    1. 打开User类,Employee类将是:

       public class Employee
       {
           @JsonProperty("Id")
           private Integer Id;
      
           @JsonProperty("Name")
           private String name;
      
           @JsonProperty("Age")
           private String age;
       }
      
    2. 修改

      如果您不能选择选项1或2,则只剩下一个选项是创建自定义反序列化器:

      编写反序列化器:

      public class EmployeeDeserializer extends StdDeserializer<Item> { 
      
          public EmployeeDeserializer() { 
              this(null); 
          } 
      
          public EmployeeDeserializer(Class<?> vc) { 
              super(vc); 
          }
      
          @Override
          public Employee deserialize(JsonParser jp, DeserializationContext ctxt) 
            throws IOException, JsonProcessingException {
              JsonNode node = jp.getCodec().readTree(jp);
              int id = (Integer) ((IntNode) node.get("Id")).numberValue();
              String name = node.get("Name").asText();
              String age = node.get("Age")).asText();
              User user = new User(name, age);
              return new Employee(id, user);
          }
      }
      

      然后注册这个解串器:

      ObjectMapper mapper = new ObjectMapper();
      SimpleModule module = new SimpleModule();
      module.addDeserializer(Employee.class, new EmployeeDeserializer());
      mapper.registerModule(module);
      
      Employee readValue = mapper.readValue(json, Employee.class);
      

      注册反序列化器的另一种方法是:

      @JsonDeserialize(using = EmployeeDeserializer.class)
      public class Employee {
      

答案 1 :(得分:1)

您似乎没有正确嵌套JSON。或者您的对象结构错误。

JSON应该是:

{
    "Id": "",
    "user" : {
                "Name": "",
                "Age": ""
    }
}

答案 2 :(得分:0)

json结构与类的结构不匹配。 如果json就像;

{
  "Id": "an-id,
  "user": {
    "Name": "Joe",
    "Age": "21"
  }
}

然后,您的代码将反序列化为Employee对象。