Reputation: 16043
Right now we are using retrofit like this:
service.executeSomeRequest(UserPreferenceRequest userPreferenceRequest, new Callback<UserPreferenceResponse>() {
@Override
public void success(UserPreferenceResponse responseCallback, Response response) {
if (responseCallback.getStatus() == ResponseStatus.OK) {
// Everything is OK, process response
} else {
ApiErrorProcessor.process(responseCallback.getError());
}
}
@Override
public void failure(RetrofitError retrofitError) {
ServerErrorProcessor.process(retrofitError);
}
});
But we have a lot of requests, and practically, every request we implement requires us to write the same error code handling (for API, and server errors) which duplicates the code.
What we want is to override only methods of interest, and if no implementation provided then a default implementation to be executed.
Something like this:
service.executeSomeRequest(UserPreferenceRequest userPreferenceRequest, new
CustomCallback<UserPreferenceResponse>() {
@Override
public void success(UserPreferenceResponse responseCallback, Response response) {
super.success(responseCallback, response);
// Everything is OK, process response
}
});
The CustomCallback
will take care of API and server errors, and if everything is OK, then only then pass the result to the calling activity.
When building the RestAdapter
there is setRequestInterceptor();
which allows me to catch the request before issuing it, I was thinking of something similar, like setResponseInterceptor()
, that will allow me to catch the response before passing it to the activity and treat there generic errors, but didn't find something similar.
Upvotes: 8
Views: 3604
Reputation: 2622
You can combine the retrofit requests with an event bus and have a clean and centralised point for handling your responses.
All you need to do is define a Composed object like this:
public class GetUsers {
// Retrofit Request
public static final class Request {}
// Retrofit Callback
public static final class Callback
implements retrofit.Callback<Response response> {
@Override
public void success(Response response,
Response retrofitResponse) {
// .... handle the code
BusManager.post(new Event());
}
@Override
public void failure(RetrofitError error) {}
BusManager.post(new RetrofitErrorEvent(error));
}
// Otto Event
public static final class Event {}
This object defines the Request, Callback and Event and this object is feed to the retrofit request.
public void getUsers(){
request.users(new GetUsers.Request(), new GetUsers.Callback());
}
After this, in your main class looks like this:
public void onResume(){
controller.getUsers();
}
@Subscribe
public void onGetPostsEvent(GetPosts.Event event){
textView.setText(event.getText());
}
For a more detailed explanation check this blog post: Otto + Retrofit – An elegant solution for Web Requests and you can find a working example here
Upvotes: 2
Reputation: 76105
Your custom callback can process the response in the base class first and then delegate to an abstract method.
public interface StatusResponse {
Status getStatus();
}
public abstract class CustomCallback<T extends StatusResponse> implements Callback<T> {
@Override public final void success(T data, Response response) {
if (data.getStatus() == Status.OK) {
success(data);
} else {
// Handle error..
}
}
public abstract void success(T data);
}
Upvotes: 10