I am implementing a post with restTemplate
, with body an object representing a fields of a json
and I would like the answer with an object
representing the json
fields of the answer itself.
For example, the json
is this:
{
"content": {
"name": "support-callmebackmodals-view_web",
"data": {
"channel": "web",
"productName": "book"
}
}
}
The class that represents it is this:
@Getter
@Setter
@NoArgsConstructor
public class Request {
Con ContentObject;
}
ConClass
contains "content" of json
, content contains name and DataClass
ecc.
The response translated into object I created is:
@Getter
@Setter
@NoArgsConstructor
@ToString
public class AssistenzaResponse {
private boolean success;
private String error;
Results results;
}
@Getter
@Setter
@NoArgsConstructor
public class Results {
Content content;
}
@Getter
@Setter
@NoArgsConstructor
public class Content {
Meta meta;
private String name;
private String html;
private float duration;
private float statusCode;
private boolean success;
private String error;
}
@Getter
@Setter
@NoArgsConstructor
public class Meta {
private String src;
}
My service
is this:
@Service
public class AssistenzaService {
public AssistenzaResponse getUno() throws IOException {
String url = "https://support.aasdt/batch";
org.apache.http.client.HttpClient client = HttpClientBuilder.create().build();
Request request1 = new Request();
Con con = new Con();
con.setName("support-callmebackmodals-view_web");
Data data = new Data();
data.setChannel("web");
data.setProductName("LibrettoMinori");
con.setData(data);
RestTemplate restTemplate = new RestTemplate();
request1.setContentObject(con);
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
headers.set("Accept", "application/json");
HttpEntity<Request> entity = new HttpEntity<>(request1, headers);
try {
ResponseEntity<AssistenzaResponse> response = restTemplate.exchange(url, HttpMethod.POST, entity, AssistenzaResponse.class);
return response.getBody();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
}
But the answer is not what I expect, because it returns:
{
"success": true,
"error": null,
"results": {
"results": null
}
}
Instead if I use:
ResponseEntity<String> response = restTemplate.exchange(url,HttpMethod.POST, entity, String.class);
The response is correct and it is:
{
"success": true,
"error": null,
"results": {
"content": {
"name": "support-callmebackmodals-view_web",
"html": "",
"meta": {
"src": "/support/client.js"
},
"duration": 7.694401,
"statusCode": 200,
"success": true,
"error": null
}
}
}
Why don't I get the exact answer using the answer object I created?
But if I use the string it works?
I expect that the json
answer will not be returned as String
, but as my Response
object, I tried to use also postForObject
and postForEntity
.
The problem is that the structure of the JSON response you are receiving does not match the structure of the AssistenzaResponse class you are using for deserialization. Therefore, RestTemplate cannot correctly convert the JSON response into an AssistenzaResponse object.
You can fix this by changing the AssistenzaResponse class to match the structure of the JSON response you are receiving. In your case, you need to add one more level of nesting to the AssistenzaResponse class. This can be done, for example, as follows:
@Getter
@Setter
@NoArgsConstructor
public class AssistenzaResponse {
private boolean success;
private String error;
private Results results;
@Getter
@Setter
@NoArgsConstructor
public static class Results {
private Content content;
@Getter
@Setter
@NoArgsConstructor
public static class Content {
private String name;
private String html;
private Meta meta;
private float duration;
private float statusCode;
private boolean success;
private String error;
@Getter
@Setter
@NoArgsConstructor
public static class Meta {
private String src;
}
}
}
}
You can then use AssistenzaResponse instead of String when calling RestTemplate.exchange() like you did before:
ResponseEntity<AssistenzaResponse> response = restTemplate.exchange(url, HttpMethod.POST, entity, AssistenzaResponse.class);
return response.getBody();
The RestTemplate should now properly convert the JSON response into an AssistenzaResponse object. Try it!