One possible response is a JSON Object
and other is a JSON Array
. In that case it is not possible to create one POJO
class to handle it. Also, these two payloads means to different things: one is SUCCESS
and other is ERROR
payloads. In that case I would use Facade design pattern to create extra layer and hide this complex logic there. It could look like below:
class ResponseDeserialiserFacade {
private final ObjectMapper mapper = new ObjectMapper();
public List<NameValuePair> deserialisePairs(String json) {
try {
return mapper.readValue(json, new TypeReference<List<NameValuePair>>() {
});
} catch (IOException e) {
try {
Error error = mapper.readValue(json, Error.class);
throw new RequestApiException(error, e);
} catch (IOException e1) {
throw new RequestApiException(Error.from("Can not parse: " + json), e1);
}
}
}
}
As you noticed I introduced new exception:
class RequestApiException extends RuntimeException {
private final Error error;
RequestApiException(Error error, Exception base) {
super(base);
this.error = error;
}
public Error getError() {
return error;
}
}
with Error
class:
class Error {
private String error;
private String code;
public static Error from(String message) {
Error e = new Error();
e.error = message;
return e;
}
// getters, setters, toString
}
Now we can test it for SUCCESS
and ERROR
payloads:
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.List;
public class JsonApp {
public static void main(String[] args) {
String success = "[\n" +
" {\n" +
" \"name\" : \"name\",\n" +
" \"value\" : \"value\"\n" +
" },\n" +
" {\n" +
" \"name\" : \"name\",\n" +
" \"value\" : \"value\"\n" +
" }\n" +
"]\n";
tryToParse(success);
String error = "{\n" +
" \"error\" : \"some error\",\n" +
" \"code\": 123\n" +
"}";
tryToParse(error);
}
private static void tryToParse(String json) {
ResponseDeserialiserFacade deserialiser = new ResponseDeserialiserFacade();
try {
List<NameValuePair> pairs = deserialiser.deserialisePairs(json);
System.out.println("SUCCESS: " + pairs);
} catch (RequestApiException e) {
System.out.println("ERROR: " + e.getError());
}
}
}
class NameValuePair {
private String name;
private String value;
// getters, setters, toString
}
Above code prints:
SUCCESS: [NameValuePair{name='name', value='value'}, NameValuePair{name='name', value='value'}]
ERROR: Error{error='some error', code='123'}
As you can see, we treated error message like as exception.