Имея нулевой ответ для списка объектов в вызове REST API с RestTemplate

Итак, я работаю над клиентом REST, который использует REST API для получения объекта JSON с помощью Spring RestTemplate. Итак, я получаю ответ HTTP 200 OK, но список (оборудование) внутри объекта класса равен нулю. Но выбираются другие поля. Когда я делаю тот же запрос с помощью Почтальона, он работает хорошо. В чем может быть причина этого?

Фрагмент кода RestTemplate:

 RestTemplate restTemplate = new RestTemplate();
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("Content-Type", "application/json");
requestHeaders.add("Authorization", "Bearer " + apiToken);
HttpEntity entity = new HttpEntity(requestHeaders);
ResponseEntity<CloverMerchant> response = restTemplate.exchange(getMerchantDetailsUrl, HttpMethod.GET, entity, CloverMerchant.class);
return response.getBody();

Класс модели CloverMerchant:

private String id;
private String name;
private String website;
private boolean isBillable;
private CloverBusinessEquipments equipment;

// other relevant getters and setters

Класс модели CloverBusinessEquipments:

private List<CloverBusinessEquipment> elements;

    public CloverBusinessEquipments() {
}

@JsonGetter("elements")
public List<CloverBusinessEquipment> getElements() {
    return elements;
}

Класс модели CloverBusinessEquipment:

private String merchantId;
private String serialNumber;
private String equipmentCode;
private String equipmentCodeDesc;
private String provisionedDeviceType;
private boolean boarded;
private boolean provisioned;

// relevant getters and setters

Ожидаемый ответ JSON от REST API:

{
  "id": "5ZTFCGXQKVZNA",
  "name": "xxxx",
  "website": "https://xxxx.io",
  "isBillable": false,
  "equipment": {
  "elements": [
    {
        "merchantId": "5ZTFCGXQKVZNA",
        "boarded": false,
        "provisioned": true,
        "serialNumber": "C030UQ71040182",
        "equipmentCode": "105J",
        "equipmentCodeDesc": "Clover Mini",
        "provisionedDeviceType": "MAPLECUTTER"
    },
    {
        "merchantId": "5ZTFCGXQKVZNA",
        "boarded": false,
        "provisioned": true,
        "serialNumber": "C050UQ75150054",
        "equipmentCode": "1297",
        "equipmentCodeDesc": "Clover Station 2018",
        "provisionedDeviceType": "GOLDENOAK"
       }
    ]
  }
}

person GeekySelene    schedule 13.03.2019    source источник
comment
есть в списке оборудование или оборудование? Ваш вопрос не соответствует вашему коду   -  person Jacob Botuck    schedule 08.03.2019
comment
ты используешь Джексона? если да, то какая версия 1.x или 2.x?   -  person Vivek    schedule 08.03.2019
comment
@VibrantVivek извините, потому что я обновил вопрос позже, я исправил его. Я использую jackson 2.4.1 для привязки данных   -  person GeekySelene    schedule 08.03.2019
comment
@ JohnDoe921, пожалуйста, попробуйте следующее: jsonschema2pojo.org ... вставьте ожидаемый JSON и выберите JSON в качестве источника и исправьте Jackson версия. И сгенерируйте POJO ... вставьте точный код в свой код ... да, вы можете переименовать обратно в Clover .... и т.д. и т.д .... он должен работать, если не дайте нам знать здесь   -  person Vivek    schedule 08.03.2019
comment
Если вы вызываете restTemplate.exchange(getMerchantDetailsUrl, HttpMethod.GET, entity, String.class), содержит ли строка json все ожидаемое оборудование?   -  person noiaverbale    schedule 13.03.2019
comment
Есть ли у вас какие-либо другие аннотации в вашем классе, кроме этого в вопросе?   -  person Kamil W    schedule 13.03.2019
comment
@noiaverbale да, он содержит ожидаемое оборудование   -  person GeekySelene    schedule 13.03.2019
comment
@KamilW да, я использовал @JsonIgnoreProperties (ignoreUnknown = true), чтобы игнорировать проблемы десериализации для любого свойства   -  person GeekySelene    schedule 13.03.2019
comment
Попробуйте поиграть с @JsonProperty, @JsonSetter может поможет.   -  person Kamil W    schedule 13.03.2019
comment
разве это не то же самое, что: stackoverflow.com/questions/55043467/ Вы не ответили на мой комментарий там ... есть причина, по которой вы снова задаете тот же вопрос?   -  person Vivek    schedule 13.03.2019
comment
Не публикуйте повторяющиеся вопросы. Отредактируйте исходный вопрос, включив в него все подробности.   -  person    schedule 16.03.2019


Ответы (2)


Ваша модель не представляет ответ JSON. Вы пытаетесь найти JSONObject с ключом "elements" на корневом уровне JSON, но на самом деле он находится на втором уровне после "equipment" ключа.

Переменная - private CloverBusinessEquipments equipments; должна представлять это:

"equipment": {
    "elements": [
        {
            "merchantId": "5ZTFCGXQKVZNA",
            "boarded": false,
            "provisioned": true,
            "serialNumber": "C030UQ71040182",
            "equipmentCode": "105J",
            "equipmentCodeDesc": "Clover Mini",
            "provisionedDeviceType": "MAPLECUTTER"
        },
        {
            "merchantId": "5ZTFCGXQKVZNA",
            "boarded": false,
            "provisioned": true,
            "serialNumber": "C050UQ75150054",
            "equipmentCode": "1297",
            "equipmentCodeDesc": "Clover Station 2018",
            "provisionedDeviceType": "GOLDENOAK"
        }
    ]
}

Но вы смоделировали свой POJO, который считает, что переменная equipments будет выглядеть, как показано ниже:

"elements": 
        {
            "merchantId": "5ZTFCGXQKVZNA",
            "boarded": false,
            "provisioned": true,
            "serialNumber": "C030UQ71040182",
            "equipmentCode": "105J",
            "equipmentCodeDesc": "Clover Mini",
            "provisionedDeviceType": "MAPLECUTTER"
        }
person uneq95    schedule 07.03.2019
comment
@ JohnDoe921 не могли бы вы попробовать поместить аннотацию @JsonGetter (elements) в получатель списка? - person uneq95; 08.03.2019
comment
да, тоже пробовал. @JsonGetter (elements) public List ‹CloverBusinessEquipment› getElements () {return elements; } - person GeekySelene; 08.03.2019
comment
это должно было сработать. Я не знаю, чего здесь еще не хватает. - person uneq95; 08.03.2019

Вам нужно переделать свой класс, как показано ниже, и проверить

удалить метод получения
CloverMerchant.java

private String id;
private String name;
private String website;
@JsonProperty("isBillable")
private boolean isBillable;
private CloverBusinessEquipments equipment;

Обновите CloverBusinessEquipments с помощью следующего кода.
CloverBusinessEquipments.java

private List<CloverBusinessEquipment> elements;

Создайте новый класс PoJo
CloverBusinessEquipment.java

private String merchantId;
private String serialNumber;
private String equipmentCode;
private String equipmentCodeDesc;
private String provisionedDeviceType;
private boolean boarded;
private boolean provisioned;

Main.java

ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
String str = "{\"id\":\"5ZTFCGXQKVZNA\",\"name\":\"xxxx\",\"website\":\"https://xxxx.io\",\"isBillable\":true,\"equipment\":{\"elements\":[{\"merchantId\":\"5ZTFCGXQKVZNA\",\"boarded\":false,\"provisioned\":true,\"serialNumber\":\"C030UQ71040182\",\"equipmentCode\":\"105J\",\"equipmentCodeDesc\":\"Clover Mini\",\"provisionedDeviceType\":\"MAPLECUTTER\"},{\"merchantId\":\"5ZTFCGXQKVZNA\",\"boarded\":false,\"provisioned\":true,\"serialNumber\":\"C050UQ75150054\",\"equipmentCode\":\"1297\",\"equipmentCodeDesc\":\"Clover Station 2018\",\"provisionedDeviceType\":\"GOLDENOAK\"}]}}";
CloverMerchant cv = mapper.readValue(str, CloverMerchant.class);
System.out.println(cv.getId()); //5ZTFCGXQKVZNA
System.out.println(cv.getEquipment().getElements().size()); //2

Если вы можете проверить вышеупомянутый основной метод, я могу десериализовать его из строки Json, указанной в вопросе.
Я использую Jackson 2.9.8

person dkb    schedule 07.03.2019
comment
по-прежнему поле оборудования равно нулю - person GeekySelene; 08.03.2019
comment
@ JohnDoe921, обновленный ответ, взгляните на него один раз, добавленный клиентский код указывает на рабочий статус вышеуказанных POJO. - person dkb; 08.03.2019
comment
я не понял, что ты просил меня попробовать - person GeekySelene; 13.03.2019