I am introducing Retrofit 2 to one of our new projects. I am having a particular issue when I consume a web service response using Retrofit.
I am using retrofit 2.3.0, and the retrofit gson converter 2.3.0.
My problem is as follows. The web service API that I am consuming will respond with 2 possible Response Models when a request is 200-OK.
Believe me, I know the problem here... The web service should not be responding on success if a web service exception was thrown... it should be responding with a 500-5xx. All of this would become much easier. Anyways, I need to conform to this logic.
This is what I have and it is working however, I think there is a better approach to this and I don't want to write the same code over and over which performs the casts operations every time I consume a response. However, I am not sure which is the correct approach here.
call.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
//cast operation
Gson gson = new Gson();
ServiceException exception = gson.fromJson(response.body(), ServiceException.class);
if(response.isSuccessful()){
if(null != exception.getCode()){
//handleException(exception);
}else{
//User authenticated successfully.
//cast operation
LoginResponseModel loginResponseModel = gson.fromJson(response.body(), LoginResponseModel.class);
//Perform actions with login response model.
//Launch dashboard if everything is ok.
Intent startDashboard = new Intent(LoginActivity.this, DashboardActivity.class);
startActivity(startDashboard);
}
}
}
@Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.e(TAG, t.getMessage());
}
});
This is my desired goal:
call.enqueue(new Callback<LoginResponseModel, ServiceException>() {
@Override
public void onResponse(Call<LoginResponseModel, ServiceException> call, Response<LoginResponseModel, ServiceException> response) {
if(response instanceof ServiceException){
handleException(response);
}else if(response instanceof LoginResponseModel){
//User authenticated successfully.
LoginResponseModel loginResponseModel = gson.fromJson(response.body(), LoginResponseModel.class);
//Perform actions with login response model.
//Launch dashboard if everything is ok.
Intent startDashboard = new Intent(LoginActivity.this, DashboardActivity.class);
startActivity(startDashboard);
}
}
}
@Override
public void onFailure(Call<LoginResponseModel, ServiceException> call, Throwable t) {
Log.e(TAG, t.getMessage());
}
});
Do I need a custom Callback implementation to achieve my goal? Do I need a custom response interceptor? Do I need a custom response converter? Any ideas of a better approach?
I am a little new to Retrofit and I haven't found much information about a scenario like this.
Hm what about use try catch
and handle gson JsonSyntaxException
? Something like this:
call.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
Gson gson = new Gson();
try {
ServiceException exception = gson.fromJson(response.body(), ServiceException.class);
//handleException(exception);
} catch (JsonSyntaxException e) {
// Incorrect class, deserialize using LoginResponseModel
LoginResponseModel loginResponseModel = gson.fromJson(response.body(), LoginResponseModel.class);
//User authenticated successfully.
//Launch dashboard if everything is ok.
Intent startDashboard = new Intent(LoginActivity.this, DashboardActivity.class);
startActivity(startDashboard);
}
}
@Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.e(TAG, t.getMessage());
}
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.