I am working on a project in which I am making a call to one of my servers using RestTemplate
which is running a RESTful service and getting the response back from them.
The response that I will be getting from my server can be either of these error responses (that's all I have for error response) if something has gone wrong:
{"warning": "user_id not found", "user_id": some_user_id}
{"error": "user_id for wrong partition", "user_id": some_user_id, "partition": some_partition}
{"error": "missing client id", "client_id":2000}
or below successful response if there is no failures (it can be any random json string, key can be different as well) -
{"@data": {"oo":"1205000384","p":"2047935"}}
- If I am getting any error response as mentioned above, then I am deserializing it so that I can log them as an error with a specific
error
orwarning
I got front the server which can be for example -user_id not found
ormissing client id
. - If it is a successful response, then I am also deserializing it, which I don't need for my use case as we don't have any POJO. I just need to return the response as is which I receive from the server.
In my use case, I don't need to deserialize my response string if it is a successful response as we don't have any POJO for that and we are returning the response string as it is which we have got from the server. But just for logging specific error messages (if I am getting error response from the server) I am deserializing it which I am thinking is unnecessary. There might be better solution for my use case.
Here is my Java client which is calling a Callable
task using future.get
:
public class TestingClient implements IClient {
private ExecutorService service = Executors.newFixedThreadPool(10);
private RestTemplate restTemplate = new RestTemplate();
@Override
public String executeSync(ClientKey keys) {
String response = null;
try {
ClientTask ClientTask = new ClientTask(keys, restTemplate);
Future<String> future = service.submit(ClientTask);
response = handle.get(keys.getTimeout(), TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
} catch (Exception e) {
}
return response;
}
}
And here is my ClientTask
class, which implements the Callable
interface. In the call method, I am generating a URL and then hit the server using RestTemplate
and get the response back:
class ClientTask implements Callable<String> {
private ClientKey cKeys;
private RestTemplate restTemplate;
public ClientTask(ClientKey cKeys, RestTemplate restTemplate) {
this.restTemplate = restTemplate;
this.cKeys = cKeys;
}
@Override
public String call() throws Exception {
// .. some code here
String url = "some_url";
String response = restTemplate.getForObject(url, String.class);
String test = checkJSONResponse(response);
return test;
}
private String checkJSONResponse(final String response) throws Exception {
// may be there are some better way of doing it for my scenario instead of using GSON
Gson gson = new Gson();
String str = null;
JsonObject jsonObject = gson.fromJson(response, JsonObject.class); // parse it, may be performance issues here/
if (jsonObject.has("error") || jsonObject.has("warning")) {
final String error = jsonObject.get("error") != null ? jsonObject.get("error").getAsString() : jsonObject
.get("warning").getAsString();
// log specific `error` here using log4j
str = response;
} else {
str = response;
}
return str;
}
}
As you can see, we are deserializing the JSON string only to log specific error messages if we are getting any error response back. But for successful response we don't need any deserialization but still we are doing it.
Is there any better way of solving this problem? I am currently seeing some performance issues with the GSON deserialization. The only way I can identify successful response is error response will have error
or warning
in the response. I guess there might be some better way of solving this problem without paying the cost for deserialization.