#Problem encountered:
App currently being developed has a problem:
When an interface is requested, it will fail because the token is no longer valid.
However, the product manager expects the app to refresh the token immediately and then repeat the request for the interface, which is insensitive to the user.
>
This means silent automatic login and then continue requesting:
>
Request Interface A -> Server returns token expiration -> Request token refresh interface -> Request interface A
>
How will people achieve these needs?
#Solution:
Ideas:
1. Get the returned data through the interceptor
2. Determine whether token expires
3. Refresh token if token expires
4. Re-request network data using the latest token
1 /** 2 * Interceptor for global automatic refresh of Token 3 */ 4 public class TokenInterceptor implements Interceptor { 5 6 @Override 7 public Response intercept(Chain chain) throws IOException { 8 Request request = chain.request(); 9 Response response = chain.proceed(request); 10 LogUtil.print("response.code=" + response.code()); 11 12 if (isTokenExpired(response)) {//Judging by agreement with the server token Be overdue 13 LogUtil.print("Silent automatic refresh Token,Then re-request the data"); 14 //Synchronize requests to get the latest Token 15 String newSession = getNewToken(); 16 //Use New Token,Create a new request 17 Request newRequest = chain.request() 18 .newBuilder() 19 .header("Cookie", "JSESSIONID=" + newSession) 20 .build(); 21 //Re-request 22 return chain.proceed(newRequest); 23 } 24 return response; 25 } 26 27 /** 28 * Determine whether Token is invalid based on Response 29 * 30 * @param response 31 * @return 32 */ 33 private boolean isTokenExpired(Response response) { 34 if (response.code() == 404) { 35 return true; 36 } 37 return false; 38 } 39 40 /** 41 * Synchronize requests to get the latest Token 42 * 43 * @return 44 */ 45 private String getNewToken() throws IOException { 46 // Get new through a specific interface token,Synchronized is used here retrofit request 47 Response_Login loginInfo = CacheManager.restoreLoginInfo(BaseApplication.getContext()); 48 String username = loginInfo.getUserName(); 49 String password = loginInfo.getPassword(); 50 51 LogUtil.print("loginInfo=" + loginInfo.toString()); 52 Call<Response_Login> call = WebHelper.getSyncInterface().synclogin(new Request_Login(username, password)); 53 loginInfo = call.execute().body(); 54 LogUtil.print("loginInfo=" + loginInfo.toString()); 55 56 loginInfo.setPassword(password); 57 CacheManager.saveLoginInfo(loginInfo); 58 return loginInfo.getSession(); 59 } 60 }
Then configure OkHttp
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(15, TimeUnit.SECONDS) .readTimeout(300, TimeUnit.SECONDS) .writeTimeout(300, TimeUnit.SECONDS) .cache(new Cache(FileConstants.HTTP_CACHE_DIR, FileConstants.CACHE_SIZE)) .addInterceptor(interceptor) // .addInterceptor(new MockInterceptor()) .addInterceptor(new TokenInterceptor()) // .addInterceptor(new RetryIntercepter(3)) .addInterceptor(logging) .build();