1. 程式人生 > >okhttp之自定義Interceptor:請求失敗切換IP重試攔截器

okhttp之自定義Interceptor:請求失敗切換IP重試攔截器

經過一段時間的掙扎,終於把新公司專案的網路框架換成了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技術問題,有興趣的可以加下,大家一起進步。