Джексон - Пользовательский десериализатор не читает все поля в JSON - PullRequest
1 голос
/ 13 января 2020

Я получаю от API это JSON:

    "link": [],
    "firstRecord": 1,
    "item": [
        {
            "Customer": {
                "id": "1058207",
                "firstName": "foo",
                "lastName": "foo2",
                "nestedObj1": {
                    "id": "40008"
                },
                "nestedObj2": {
                    "link": [],
                    "linkfoo": "lala",
                    "item": [
                             {
                              "id": "266614",
                              "label": "NESTED_OBJ_2"
                            }
                           ]
                  }
              ]
           }

Моя функция десериализатора

    @Override
    public CustomerView deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {

        //tried this too
        TreeNode treeNode = p.getCodec().readTree(p);

        // also this
        JsonNode node = p.getCodec().readTree(p);

        JsonNode simpleNode = new ObjectMapper().readTree(p);

        // use for each field that is not String
        ObjectMapper mapper = new ObjectMapper();

        Customer customer = new Customer();

        customer.setFirstName(simpleNode.get("Customer").get("firstName").textValue()); 

        NestedObj2[] arrayObj2 = mapper.readValue(
                        simpleNode.get("Customer").get("nestedObj2").get("item").toString(), 
                        NestedObj2[].class);

        customer.setArrayObj2(arrayObj2);
}

Класс NestedObj2 имеет все поля, как в JSON, массив "item" является отдельным объектом как поле.

Проблема в том, что ни JsonNode, ни TreeNode не видят поле "nestedObj2", а остальные поля находятся внутри них во время десериализации -> проверено во время отладки.

Я что-то пропускаю в конфигурации или мне нужно использовать другой объект для десериализации?

Спасибо!

РЕДАКТИРОВАТЬ

В конце концов, я использовал DTO, как советовал @Mehrdad HosseinNejad. Когда я получаю JSON по RestTemplate.exchange(), мне пришлось настроить RestTemplate с MappingJacksonHttpMessageConverter как здесь { ссылка }

1 Ответ

1 голос
/ 13 января 2020

Лучше использовать классы DTO, нет необходимости создавать собственный десериализатор

Я кодировал пример вложенного DTO следующим образом:

Создание класса DTO для клиента

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Customer {

private Long id;
private String firstName;
private String lastName;
private NestedObj1 nestedObj1;
private NestedObj2 nestedObj2;

//getter and setter

}

Создание класса DTO для NestedObj1

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class NestedObj1 {

private Long id;

//getter and setter

}

Создание класса DTO для NestedObj2

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class NestedObj2 {

private List<String> link;
private String linkFoo;
private List<Item> item;

//getter and setter     

}

Создание класса DTO для элемента

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Item {

private Long id;
private String label;

//getter and setter

}

После создания этих DTO вы можете просто с помощью класса ObjectMapper преобразовать ваш JSON в Java Object

Customer customer= new ObjectMapper().readValue(jsonFile, Customer.class);

Для других опций, таких как игнорирование некоторых свойств, ... вы можете использовать следующую ссылку:

Примеры аннотаций Джексона

Дополнительная информация в десериализации:

Начало работы с десериализацией в Джексоне

...