【问题标题】:Having null response for a list of objects in REST API call with RestTemplate使用 RestTemplate 对 REST API 调用中的对象列表有空响应
【发布时间】:2019-07-29 07:41:30
【问题描述】:

所以我正在开发一个 REST 客户端,该客户端使用 REST API 来使用 Spring RestTemplate 获取 JSON 对象。所以我得到一个 HTTP 200 OK 响应,但类对象内的列表(设备)为空。但是会获取其他字段。当我使用 Postman 执行相同的请求时,它运行良好。这可能是什么原因?

RestTemplate 代码 sn-p :

 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

来自 REST API 的预期响应 JSON:

{
  "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"
       }
    ]
  }
}

【问题讨论】:

  • 是列表设备还是设备?您的问题与您的代码不符
  • 你在用杰克逊吗?如果是,哪个版本 1.x 或 2.x ?
  • @VibrantVivek 抱歉,因为我后来更新了问题,我更正了。我使用 jackson 2.4.1 进行数据绑定
  • 如果调用restTemplate.exchange(getMerchantDetailsUrl, HttpMethod.GET, entity, String.class),json字符串是否包含所有预期的设备?
  • 不等于:stackoverflow.com/questions/55043467/… 你没有回复我的评论...你有什么理由再次提出同样的问题吗?

标签: java spring resttemplate jsonschema2pojo


【解决方案1】:

您的模型不代表 JSON 响应。您试图在 JSON 的根级别找到键为 "elements" 的 JSONObject,但实际上它位于 "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"
        }

【讨论】:

  • @JohnDoe921 你可以尝试将@JsonGetter("elements") 注释放在列表的getter 上吗?
  • 是的,也试过了。 @JsonGetter("elements") public List getElements() { 返回元素; }
  • 应该可以的。我不知道这里还缺少什么。
【解决方案2】:

你需要如下改造你的班级并检查

删除 getter 方法
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 字符串中反序列化它。
我正在使用杰克逊 2.9.8

【讨论】:

  • 设备字段仍然为空
  • @JohnDoe921,更新答案,看一下,添加的客户端代码表示上述POJO的工作状态。
  • 我不明白你要我尝试什么
猜你喜欢
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 2019-02-23
  • 1970-01-01
  • 2022-07-24
  • 1970-01-01
  • 2017-02-20
相关资源
最近更新 更多