I am using Retrofit 2.0 with Jackson Converter to communicate with the Rest API. Some requests require tokens during authorization. If the tokens that I have are out of date, I need to update them with another request and repeat the last request, which failed because of it.
My question is: do I need to do this manually each time or is there a way to automate it?
Here's how I am implementing it at the moment:
Tracker service
public interface TrackerService { @POST("auth/sendPassword") Call<ResponseMessage> sendPassword(@Header("app-type") String appType, @Body User userMobile); @FormUrlEncoded @POST("oauth/token") Call<TokenResponse> oathToken(@Field("client_id") String clientId, @Field("client_secret") String clientSecret, @Field("grant_type") String grantType, @Field("username") String username, @Field("password") String password); @FormUrlEncoded @POST("oauth/token") Call<TokenResponse> refreshToken(@Field("client_id") String clientId, @Field("client_secret") String clientSecret, @Field("grant_type") String grantType, @Field("refresh_token") String username); @PUT("me/profile") Call<Profile> updateProfile(@Header("app-type") String appType, @Header("Authorization") String token, @Body Profile profile); }
ServiceGateway
public class ServiceGateway { private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); private static Retrofit retrofit; public static <S> S createService(Class<S> serviceClass) { HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(20 * 1000, TimeUnit.MILLISECONDS) .writeTimeout(20 * 1000, TimeUnit.MILLISECONDS) .readTimeout(20 * 1000, TimeUnit.MILLISECONDS) .addInterceptor(interceptor).build(); Retrofit.Builder builder = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(JacksonConverterFactory.create()); retrofit = builder.client(httpClient.build()) .client(client) .build(); return retrofit.create(serviceClass); } public static Retrofit getRetrofit() { return retrofit; } }
How do I call a function and treat it when the tokens are out of date
trackerService = ServiceGateway.createService(TrackerService.class); Call<Profile> call = trackerService.updateProfile(getString(R.string.app_type), "Bearer " + userPrefs.accessToken().get(), new Profile(trimedInvitationMessage, title, String.valueOf(selectedCountry.getCountryCode()), mobilePhone, countryISO, fullName)); call.enqueue(new Callback<Profile>() { @Override public void onResponse(Call<Profile> call, Response<Profile> response) { if (response.body() != null) { } else { if (response.raw().code() == 401) { Call<TokenResponse> refreshTokenCall = trackerService.refreshToken(userPrefs.clientId().get(), userPrefs.clientSecret().get(), "refresh_token", userPrefs.refreshToken().get()); refreshTokenCall.enqueue(new Callback<TokenResponse>() { @Override public void onResponse(Call<TokenResponse> call, Response<TokenResponse> response) { if (response.body() != null) { updateAdviserProfile(trimedInvitationMessage, title, mobilePhone, countryISO, fullName); } else { userPrefs.clear(); Intent intent = new Intent(WelcomeActivity_.launcher(EditProfileActivity.this)); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); startActivity(WelcomeActivity_.launcher(EditProfileActivity.this)); } } @Override public void onFailure(Call<TokenResponse> call, Throwable t) { } }); } else if (response.raw().code() == 422) } } @Override public void onFailure(Call<Profile> call, Throwable t) { } });