javaparsingresponse-entity

Java get nested value from ResponseEntity without creating a pojo


I am trying to get a single nested value from a ResponseEntity but I am trying to do so without having to create a pojo for every possible item as this is a third party api response.

Example response.getBody() as it appears in Postman:

{
    "message": "2 records found",
    "records": [
        {
            "Account": {
                "Id": "1",
                "Name": "Foo Inc"
            },
            "CaseNumber": "200",
            "Contact": {
                "FirstName": "Foo",
                "LastName": "Bar"
            },
            "Status": "In Progress",
            "StatusMessage": "We are working on this."
        },
        {
            "Account": {
                 "Id": "1",
                 "Name": "Foo Inc"
            },
            "CaseNumber": "100",
            "Contact": {
                "FirstName": "Foo",
                "LastName": "Bar"
            },
            "Status": "Closed"
        }

    ]
}

Basically, if I were in JS, I am looking for:

for(let record of res.body.records){
   if(record && record.CaseNumber === "200"){
      console.log(record.Status)
}
res.body.records[0].Status

Currently, they are are doing this to check if the response is empty:

ResponseEntity<Object> response = restTemplate.exchange(sfdcURL, HttpMethod.POST, entity, Object.class);

LinkedHashMap<Object, Object> resMap = (LinkedHashMap<Object, Object>) response.getBody();
        
List<Object> recordsList = (List<Object>) resMap.get("records");

if (recordsList.size() <= 0) { return error }

But I need to get the value of of "Status" and I need to do so without creating a pojo.

I appreciate any guidance on how I can do this in Java

UPDATE

So the response.getBody() is returned and when it is displayed in Postman, it looks like the pretty JSON shown above. However, when I do:

System.out.println(response.getBody().toString())

it looks like:

{message=2 Records Found, records=[{Account={Id=1, Name=Foo Inc}, CaseNumber=200, Contact={FirstName=Foo, LastName=Bar}, //etc

To make it worse, one of the fields appears in the console as follows (including linebreaks):

[...], Status=In Progress, LastEmail=From: noreply@blah.com
Sent: 2022-08-08 10:14:54
To: foo@bar.com
Subject: apropos case #200


Hello Foo,
We are working on your case and stuff

Thank you,
us, StatusMessage=We are working on this., OtherFields=blah, [...]

text.replaceAll("=", ":") would help some, but won't add quotations marks nor would it help separate that email block.

How can I so that the responses here like ObjectMapper and JSONObject can work?


Solution

  • As Oliver suggested JsonNode seems to be the best approach. But, if I receive the ResponseEntity<Object>, I still cannot figure out a way to convert it to readable Json (and thus convert it to JsonNode), so I am still open to responses for that part.

    I was able to get it to work by changing the ResponseEntity<Object> to ResponseEntity<JsonNode> so this is what I will be submitting for now:

    ResponseEntity<JsonNode> response = restTemplate.exchange(sfdcURL,
          HttpMethod.POST, entity, JsonNode.class);
    
    JsonNode records = response.getBody().get("records");
    
    String status = null;
    String statusMessage = null;
    
    for (JsonNode rec : records) {
        if(rec.get("CaseNumber").asText().equals(caseNumber)) {
            status = rec.get("Status").asText();
            if(rec.has("StatusMessage")) {
                statusMessage = rec.get("StatusMessage").asText();
            }
        } else {
            statusMessage = "Invalid CaseNumber";
        }
    }
    

    Because the overall method returns a ResponseEntity<Object> I then converted my strings to a HashMap and returned that:

    HashMap<String, String> resMap = new HashMap<String, String>();
    resMap.put("Status", status);
    resMap.put("StatusMessage", statusMessage);
            
    return new ResponseEntity<>(resMap, HttpStatus.OK);
    

    This is not a perfect solution, but it works for now. Would still be better for exception handling if I could receive a ResponseEntity<Object> and then convert it to a JsonNode though. Thanks everyone for the responses!