问题
So I'm working on a REST client that consumes a REST API to get a JSON object using the Spring RestTemplate. So I get an HTTP 200 OK response but the list (equipment) inside the class object is null. But other fields are fetched. When I do the same request using the Postman it works well. What might be the reason for this?
The RestTemplate code snippet :
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();
The CloverMerchant model class :
private String id;
private String name;
private String website;
private boolean isBillable;
private CloverBusinessEquipments equipment;
// other relevant getters and setters
The CloverBusinessEquipments model class:
private List<CloverBusinessEquipment> elements;
public CloverBusinessEquipments() {
}
@JsonGetter("elements")
public List<CloverBusinessEquipment> getElements() {
return elements;
}
The CloverBusinessEquipment model class :
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
The expected response JSON from the 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"
}
]
}
}
回答1:
Your model does not represent the JSON response. You are trying to find the JSONObject with key "elements"
at the root level of the JSON, but in reality it is at the second level after "equipment"
key.
The variable - private CloverBusinessEquipments equipments;
should represent this:
"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"
}
]
}
But you have modelled your POJO which thinks that the equipments
variable will be like below:
"elements":
{
"merchantId": "5ZTFCGXQKVZNA",
"boarded": false,
"provisioned": true,
"serialNumber": "C030UQ71040182",
"equipmentCode": "105J",
"equipmentCodeDesc": "Clover Mini",
"provisionedDeviceType": "MAPLECUTTER"
}
回答2:
You need to remodel your class as below and check
remove getter method
CloverMerchant.java
private String id;
private String name;
private String website;
@JsonProperty("isBillable")
private boolean isBillable;
private CloverBusinessEquipments equipment;
Update CloverBusinessEquipments with the following code.
CloverBusinessEquipments.java
private List<CloverBusinessEquipment> elements;
Create new PoJo class
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
If you can check above the main method, I am able to deserialize it from Json String posted in the question.
I am using Jackson 2.9.8
来源:https://stackoverflow.com/questions/55136143/having-null-response-for-a-list-of-objects-in-rest-api-call-with-resttemplate