okhttp之自定義Interceptor:請求失敗切換IP重試攔截器
阿新 • • 發佈:2019-01-23
經過一段時間的掙扎,終於把新公司專案的網路框架換成了retrofit,由於專案是有失敗重試和重定向需求的,所以需要在新的網路框架上增加這個功能,大家都知道retrofit的網路請求部分是基於okhttp的。這個時候可愛的Interceptor設計就提現出他的好處了,不需要修改其他的程式碼,直接增加一個攔截器就OK了
實現一個攔截器繼承Interceptor(2.0到3.0之前的版本)
public class RetryAndChangeIpInterceptor implements Interceptor {
String FirstIP;
String SecondIP;
int RetryCount;
public RetryAndChangeIpInterceptor(String firsrIP, String secondIP, int tryCount) {
FirstIP = firsrIP;
SecondIP = secondIP;
RetryCount = tryCount;
}
public RetryAndChangeIpInterceptor(String firsrIP, String secondIP) {
FirstIP = firsrIP;
SecondIP = secondIP;
RetryCount = 3 ;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// try the request
Response response = chain.proceed(request);
int tryCount = 0;
while (!response.isSuccessful() && tryCount <= RetryCount) {
String url = request.url().toString();
if (!Util.checkNULL(FirstIP) && !Util.checkNULL(SecondIP)) {//重定向
if (url.contains(FirstIP)) {
url = url.replace(FirstIP, SecondIP);
} else if (url.contains(SecondIP)) {
url = url.replace(SecondIP, FirstIP);
}
Request newRequest = response.request().newBuilder().url(url).build();
Log.d("intercept", "Request is not successful - " + tryCount);
tryCount++;
// retry the request
response = chain.proceed(newRequest);
} else {
response = chain.proceed(request);
}
}
return response;
}
}
3.0及以上版本(取消了httpEngine,採用了純攔截器遞迴呼叫機制)
package com.sunshine.retrofit.interceptor;
import android.util.Log;
import java.io.IOException;
import java.util.List;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
/**
* Created by 耿 on 2016/8/12.
*/
public class RetryAndChangeIpInterceptor implements Interceptor {
int RetryCount = 3;
String FirstIP;
List<String> SERVERS;
public RetryAndChangeIpInterceptor(String firsrIP, List<String> sERVERS) {
FirstIP = firsrIP;
SERVERS = sERVERS;
RetryCount = 3;
}
public RetryAndChangeIpInterceptor(String firsrIP, List<String> sERVERS, int tryCount) {
FirstIP = firsrIP;
SERVERS = sERVERS;
RetryCount = tryCount;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// try the request
Response response = doRequest(chain, request);
int tryCount = 0;
String url = request.url().toString();
while (response == null && tryCount <= RetryCount) {
url = switchServer(url);
Request newRequest = request.newBuilder().url(url).build();
Log.d("intercept", "Request is not successful - " + tryCount);
tryCount++;
// retry the request
response = doRequest(chain, newRequest);
}
if (response == null) {
throw new IOException();
}
return response;
}
private Response doRequest(Chain chain, Request request) {
Response response = null;
try {
response = chain.proceed(request);
} catch (Exception e) {
}
return response;
}
private String switchServer(String url) {
String newUrlString = url;
if (url.contains(FirstIP)) {
for (String server : SERVERS) {
if (!FirstIP.equals(server)) {
newUrlString = url.replace(FirstIP, server);
break;
}
}
} else {
for (String server : SERVERS) {
if (url.contains(server)) {
newUrlString = url.replace(server, FirstIP);
break;
}
}
}
return newUrlString;
}
}
配置OkHttpClient
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new RetryAndChangeIpInterceptor(BASE_URL, SecondIP))//新增失敗重試及重定向攔截器
.retryOnConnectionFailure(true)//允許失敗重試
.connectTimeout(8, TimeUnit.SECONDS)
.readTimeout(5, TimeUnit.SECONDS)
.writeTimeout(5, TimeUnit.SECONDS)
.build();
我建了一個QQ群(群號:121606151),用於大家討論交流Android技術問題,有興趣的可以加下,大家一起進步。