1

I am calling a third-party API that returns two different values for the same parameter name as below,

    ActivationResponse activationResponse = new ActivationResponse();
ResponseEntity<ActivationResponse> response = null;
    response = restTemplate.exchange(Url, HttpMethod.POST, request, ActivationResponse.class);
    activationResponse = response.getBody();

Error response:

    {
   "executionCode":"2",
   "executionMessage":"NullPointerException Occured!",
   "response":"java.lang.NullPointerException"
}

Success response:

{
  "executionCode" : "0",
  "executionMessage" : "SUCCESS",
  "response" : {
    "orderID" : "79966036"
  }
}

As the sample response response parameter can come as a string or with a JSON object.

Currently the response model is as below,

public class ActivationResponse {

    private String executionCode;
    private String executionMessage;
    private ActivationResponseDetails response;
}

public class ActivationResponseDetails {
    private String orderID;
}

When the error comes, an exception is thrown indicating that it can't handle the response parameter. Please advice how to handle both success and failure scenarios without issues.

Please Note that approach in this answer is not possible, because I have to print the logs in following way, so using @JsonIgnore will not show that parameter on the log.

Logs are printed like this,

log.info("ActivationResponse json : {}", mapper.writerWithDefaultPrettyPrinter().writeValueAsString(response.getBody()));
cmb28
  • 421
  • 9
  • 24
  • Must it be deserialized to a single type? Is it impossble that success maps to OkResponse and errors to ErrorResponse? – morsor Dec 01 '21 at 10:47
  • Just for clarification: The problem occurs because there is no orderID? – SirHawrk Dec 01 '21 at 10:47
  • @morsor success response maps without error. But error response gives an exception. I think it is because in error scenario it is expecting a json object but receiving a string. – cmb28 Dec 01 '21 at 11:01
  • @SirHawrk in error scenario, "response" parameter comes as a string, not a json object. I want to know how i can handle both success and error scenarios without getting exceptions – cmb28 Dec 01 '21 at 11:02
  • @cmb28: Yes - I understand that is the problem. My questions is whether you MUST map ALL responses to the exact same structure? It is perfectly normal to have success and error map to different types – morsor Dec 01 '21 at 11:04
  • @morsor yes it is ok – cmb28 Dec 01 '21 at 12:49

1 Answers1

2

If you insist on having a one-size-fits-all Response object, setting the type of the response field to Object, may do the trick:

public class ActivationResponse {
    private String executionCode;
    private String executionMessage;
    private Object response;
}

The field 'response' should now resolve to a simple String (success) or a more involved Java object (error).

morsor
  • 1,263
  • 14
  • 29
  • Thnanks for the reply. Actually I want to do the opposite of this. keep response as "private ActivationResponseDetails response;" and ignore the string values coming – cmb28 Dec 02 '21 at 05:39
  • Can you just not have your caller map the success response to a String and the error response to ActivationResponseDetails? Could you please explain why both responses apparently MUST map to the same object? – morsor Dec 02 '21 at 07:14
  • This idea of using the Object field solved my problem. Often the Json attributes may come as JsonObject or JsonArray with the same name, and this was the right solution for me to avoid errors in both scenarios! I also created then a method to get the field as a List, just by using some conditions and casting operations: https://stackoverflow.com/a/73219012/5538923 – marcor92 Aug 03 '22 at 09:10