简体   繁体   English

将Json映射到嵌套POJO

[英]Mapping Json into nested POJO

I've the following JSON from some upstream api 我从一些上游api获得以下JSON

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

And I need to map this above json to a downstream request paylaod (POJO) . 我需要将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;

}

Right now I'm doing something like 现在我正在做类似的事情

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

But this is giving null in User Object. 但这在User Object中提供了null。

The challenge here is , that the json we are getting from upstream can't be changed . 这里的挑战是,我们无法更改从上游获取的json。 So , is there is any way to map the fields into the nested User object , without changing the structure of json received from upstream. 因此,有什么方法可以将字段映射到嵌套的User对象中,而无需更改从上游接收的json的结构。

One Solution is : map the fields separately into User object and then set it into the Employee object . 一种解决方案是 :将字段分别映射到User对象,然后将其设置为Employee对象。 But that's not an efficient solution , because for null validations we would need to do validations separately for User and Employee objects. 但这不是一个有效的解决方案,因为对于null验证,我们需要分别对User和Employee对象进行验证。 If the nesting is complex then , validation will be hell of replicated code . 如果嵌套很复杂,那么验证将是复制代码的难题。

Your JSON does not comply with your Employee class. 您的JSON不符合Employee类。

Because name and age is at the same level as id , but you want to wrapped in a class User . 因为nameageid处于同一级别,但是您希望将其包装在User类中。

So either: 所以:

  1. Change the json the structure to 将json的结构更改为

      { "id": "", "user": { "name": "", "age": "" } } 

Or 要么

  1. Unwrap the User class, the Employee class will be: 解开User类,Employee类将是:

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

Edit 编辑

If you can't choose either option 1 or 2, you have only one option left is to create custom deserializer: 如果您无法选择选项1或2,则只剩下一个选项来创建自定义解串器:

Write a deserializer: 写一个反序列化器:

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);
    }
}

Then register this deserializer: 然后注册此反序列化器:

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

Employee readValue = mapper.readValue(json, Employee.class);

Another way to register deserializer is: 注册反序列化器的另一种方法是:

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

It seems you are not nesting your JSON correctly. 看来您没有正确嵌套JSON。 Or your Object Structure is wrong. 否则您的对象结构错误。

JSON should be: JSON应该是:

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

The json structure does not match the structure of your classes. json结构与您的类的结构不匹配。 if the json was like; 如果json就像;

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

Then your code to deserialise to an Employee object would work. 然后,将要反序列化为Employee对象的代码将起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM