Reputation: 5416
I need to consume and parse incoming json from a CRM system in my code. I used RestTemplate to do it. So the response from the CRM system looks like below.
{ "GvyArEFkg6JX6wI": {
"entityId": "GvyArEFkg6JX6wI",
"mergePolicy": {
"id": "9245a39d-fe1a-4b33-acab-9bc5cbabf37c"
}
}
}
Now the problem is the property name ("GvyArEFkg6JX6wI" in this case) in dynamic and in the next response it would be another string. In this case, how can I parse this json as this is not fixed? I tried using jsonGetter
but it only wraps it around another block and still does not resolve the problem of parsing the response.
AdobeResponseDto.class
@Builder
@ToString
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@NoArgsConstructor
public class AdobeResponseDto {
public Map<String, AdobeResponseFinal> adobeResponseWrapper = new HashMap<>();
@JsonAnySetter
public void setAdobeResponseWrapper(String name, AdobeResponseFinal value) {
adobeResponseWrapper.put(name, value);
}
@JsonAnyGetter
public Map<String, AdobeResponseFinal> getAdobeResponseWrapper() {
return adobeResponseWrapper;
}
}
AdobeResponseFinal.class
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AdobeResponseFinal {
public String entityId;
public MergePolicy mergePolicy;
}
I am calling the service like this:
final ResponseEntity<AdobeResponseDto> finalResponse;
finalResponse = aepClient.exchange(uri,HttpMethod.GET,entity,AdobeResponseDto.class);
final AdobeResponseDto body = finalResponse.getBody();
if(ObjectUtils.isNotEmpty(body)){
return body;
}
But in this way, the response I am getting is
{
"adobeResponseWrapper": {
"GvyArEFkg6JX6wI": {
"entityId": "GvyArEFkg6JX6wI",
"mergePolicy": {
"id": "9245a39d-fe1a-4b33-acab-9bc5cbabf37c"
}
}
Upvotes: 0
Views: 1829
Reputation: 4009
If you just want to get the value of dynamic field name (e.g., "GvyArEFkg6JX6wI" in your case), you can just deserialize the response body to a Map
and then traverse its value as follows:
ResponseEntity<String> finalResponse = aepClient.exchange(uri, HttpMethod.GET, entity, String.class);
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> result = objectMapper.readValue(finalResponse.getBody(), Map.class);
result.values().forEach(System.out::println);
Console output:
{entityId=GvyArEFkg6JX6wI, mergePolicy={id=9245a39d-fe1a-4b33-acab-9bc5cbabf37c}}
And if you want to deserialize the response body to your DTO (I assume that there is only ONE root-level property), you can modify the DTO like:
public class AdobeResponseDto {
private AdobeResponseFinal adobeResponseFinal;
@JsonAnySetter
public void setAdobeResponseFinal(String name, AdobeResponseFinal value) {
adobeResponseFinal = value;
}
@JsonAnyGetter
public AdobeResponseFinal getAdobeResponseFinal() {
return adobeResponseFinal;
}
}
Then you can get similar result as follows:
ResponseEntity<String> finalResponse = aepClient.exchange(uri, HttpMethod.GET, entity, String.class);
AdobeResponseDto adobeResponseDto = objectMapper.readValue(finalResponse.getBody(), AdobeResponseDto.class);
System.out.println(adobeResponseDto.getAdobeResponseFinal().toString());
Console output:
AdobeResponseFinal{entityId='GvyArEFkg6JX6wI', mergePolicy=MergePolicy{id='9245a39d-fe1a-4b33-acab-9bc5cbabf37c'}}
Upvotes: 2