Отображение Json во вложенный POJO - PullRequest
0 голосов
/ 08 мая 2018

У меня следующий 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.

Проблема в том, что json, который мы получаем из апстрима, не может быть изменен. Итак, есть ли способ отобразить поля во вложенный объект Пользователь , не меняя структуру json, полученную из апстрима.

Одним из решений является : сопоставить поля отдельно в объекте User и затем установить его в объекте Employee. Но это неэффективное решение, потому что для нулевых проверок нам нужно было бы выполнять проверки отдельно для объектов User и Employee. Если вложение является сложным, то проверка будет адским тиражом кода.

Ответы [ 3 ]

0 голосов
/ 08 мая 2018

Ваш JSON не соответствует вашему Employee классу.

Поскольку name и age находятся на том же уровне, что и id, но вы хотите заключить их в класс User.

Так что либо:

  1. Измените JSON структуру на

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

Или

  1. Разверните класс User, класс Employee будет:

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

Редактировать

Если вы не можете выбрать ни один из вариантов 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 {
0 голосов
/ 08 мая 2018

Структура json не соответствует структуре ваших классов. если бы json был как;

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

Тогда ваш код для десериализации объекта Employee будет работать.

0 голосов
/ 08 мая 2018

Кажется, вы неправильно вложили свой JSON. Или ваша структура объекта неверна.

JSON должно быть:

{
    "Id": "",
    "user" : {
                "Name": "",
                "Age": ""
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...