1. 程式人生 > >網路請求框架——OkGo解讀(三)——request

網路請求框架——OkGo解讀(三)——request

所有請求的基類,其中泛型R主要用於屬性設定方法後,返回對應的子型別,以便於實現鏈式呼叫

public abstract class BaseRequest<R extends BaseRequest> {

    protected String url;
    protected String baseUrl;
    protected Object tag;
    protected long readTimeOut;
    protected long writeTimeOut;
    protected long connectTimeout;
    protected int 
retryCount; protected CacheMode cacheMode; protected String cacheKey; protected long cacheTime = CacheEntity.CACHE_NEVER_EXPIRE; //預設快取的超時時間 private HttpsUtils.SSLParams sslParams; protected HostnameVerifier hostnameVerifier; protected HttpParams params = new HttpParams(); //新增的param
protected HttpHeaders headers = new HttpHeaders(); //新增的header protected List<Interceptor> interceptors = new ArrayList<>(); //額外的攔截器 protected List<Cookie> userCookies = new ArrayList<>(); //使用者手動新增的Cookie private AbsCallback mCallback; private Converter mConverter
; private HttpUrl httpUrl; private Request mRequest; public BaseRequest(String url) { this.url = url; baseUrl = url; httpUrl = HttpUrl.parse(url); OkGo go = OkGo.getInstance(); //預設新增 Accept-Language String acceptLanguage = HttpHeaders.getAcceptLanguage(); if (!TextUtils.isEmpty(acceptLanguage)) headers(HttpHeaders.HEAD_KEY_ACCEPT_LANGUAGE, acceptLanguage); //預設新增 User-Agent String userAgent = HttpHeaders.getUserAgent(); if (!TextUtils.isEmpty(userAgent)) headers(HttpHeaders.HEAD_KEY_USER_AGENT, userAgent); //新增公共請求引數 if (go.getCommonParams() != null) params.put(go.getCommonParams()); if (go.getCommonHeaders() != null) headers.put(go.getCommonHeaders()); //新增快取模式 if (go.getCacheMode() != null) cacheMode = go.getCacheMode(); cacheTime = go.getCacheTime(); //超時重試次數 retryCount = go.getRetryCount(); } @SuppressWarnings("unchecked") public R url(String url) { this.url = url; return (R) this; } @SuppressWarnings("unchecked") public R tag(Object tag) { this.tag = tag; return (R) this; } @SuppressWarnings("unchecked") public R readTimeOut(long readTimeOut) { this.readTimeOut = readTimeOut; return (R) this; } @SuppressWarnings("unchecked") public R writeTimeOut(long writeTimeOut) { this.writeTimeOut = writeTimeOut; return (R) this; } @SuppressWarnings("unchecked") public R connTimeOut(long connTimeOut) { this.connectTimeout = connTimeOut; return (R) this; } @SuppressWarnings("unchecked") public R cacheMode(CacheMode cacheMode) { this.cacheMode = cacheMode; return (R) this; } @SuppressWarnings("unchecked") public R cacheKey(String cacheKey) { this.cacheKey = cacheKey; return (R) this; } /** 傳入 -1 表示永久有效,預設值即為 -1 */ @SuppressWarnings("unchecked") public R cacheTime(long cacheTime) { if (cacheTime <= -1) cacheTime = CacheEntity.CACHE_NEVER_EXPIRE; this.cacheTime = cacheTime; return (R) this; } @SuppressWarnings("unchecked") public R setCertificates(InputStream... certificates) { sslParams = HttpsUtils.getSslSocketFactory(null, null, certificates); return (R) this; } @SuppressWarnings("unchecked") public R setCertificates(InputStream bksFile, String password, InputStream... certificates) { sslParams = HttpsUtils.getSslSocketFactory(bksFile, password, certificates); return (R) this; } @SuppressWarnings("unchecked") public R setHostnameVerifier(HostnameVerifier hostnameVerifier) { this.hostnameVerifier = hostnameVerifier; return (R) this; } @SuppressWarnings("unchecked") public R headers(HttpHeaders headers) { this.headers.put(headers); return (R) this; } @SuppressWarnings("unchecked") public R headers(String key, String value) { headers.put(key, value); return (R) this; } @SuppressWarnings("unchecked") public R removeHeader(String key) { headers.remove(key); return (R) this; } @SuppressWarnings("unchecked") public R removeAllHeaders() { headers.clear(); return (R) this; } @SuppressWarnings("unchecked") public R params(HttpParams params) { this.params.put(params); return (R) this; } @SuppressWarnings("unchecked") public R params(Map<String, String> params, boolean... isReplace) { this.params.put(params, isReplace); return (R) this; } @SuppressWarnings("unchecked") public R params(String key, String value, boolean... isReplace) { params.put(key, value, isReplace); return (R) this; } @SuppressWarnings("unchecked") public R params(String key, int value, boolean... isReplace) { params.put(key, value, isReplace); return (R) this; } @SuppressWarnings("unchecked") public R params(String key, float value, boolean... isReplace) { params.put(key, value, isReplace); return (R) this; } @SuppressWarnings("unchecked") public R params(String key, double value, boolean... isReplace) { params.put(key, value, isReplace); return (R) this; } @SuppressWarnings("unchecked") public R params(String key, long value, boolean... isReplace) { params.put(key, value, isReplace); return (R) this; } @SuppressWarnings("unchecked") public R params(String key, char value, boolean... isReplace) { params.put(key, value, isReplace); return (R) this; } @SuppressWarnings("unchecked") public R params(String key, boolean value, boolean... isReplace) { params.put(key, value, isReplace); return (R) this; } @SuppressWarnings("unchecked") public R addUrlParams(String key, List<String> values) { params.putUrlParams(key, values); return (R) this; } @SuppressWarnings("unchecked") public R removeParam(String key) { params.remove(key); return (R) this; } @SuppressWarnings("unchecked") public R removeAllParams() { params.clear(); return (R) this; } @SuppressWarnings("unchecked") public R addCookie(String name, String value) { Cookie.Builder builder = new Cookie.Builder(); Cookie cookie = builder.name(name).value(value).domain(httpUrl.host()).build(); userCookies.add(cookie); return (R) this; } @SuppressWarnings("unchecked") public R addCookie(Cookie cookie) { userCookies.add(cookie); return (R) this; } @SuppressWarnings("unchecked") public R addCookies(List<Cookie> cookies) { userCookies.addAll(cookies); return (R) this; } @SuppressWarnings("unchecked") public R setCallback(AbsCallback callback) { this.mCallback = callback; return (R) this; } @SuppressWarnings("unchecked") public R addInterceptor(Interceptor interceptor) { interceptors.add(interceptor); return (R) this; } /** 預設返回第一個引數 */ public String getUrlParam(String key) { List<String> values = params.urlParamsMap.get(key); if (values != null && values.size() > 0) return values.get(0); return null; } /** 預設返回第一個引數 */ public HttpParams.FileWrapper getFileParam(String key) { List<HttpParams.FileWrapper> values = params.fileParamsMap.get(key); if (values != null && values.size() > 0) return values.get(0); return null; } public HttpParams getParams() { return params; } public HttpHeaders getHeaders() { return headers; } public String getUrl() { return url; } public String getBaseUrl() { return baseUrl; } public Object getTag() { return tag; } public CacheMode getCacheMode() { return cacheMode; } public void setCacheMode(CacheMode cacheMode) { this.cacheMode = cacheMode; } public String getCacheKey() { return cacheKey; } public void setCacheKey(String cacheKey) { this.cacheKey = cacheKey; } public long getCacheTime() { return cacheTime; } public int getRetryCount() { return retryCount; } public Request getRequest() { return mRequest; } public AbsCallback getCallback() { return mCallback; } public Converter getConverter() { return mConverter; } /** * 返回當前的請求方法 * GET,POST,HEAD,PUT,DELETE,OPTIONS */ public String getMethod() { return mRequest.method(); } /** 根據不同的請求方式和引數,生成不同的RequestBody */ public abstract RequestBody generateRequestBody(); /** 對請求body進行包裝,用於回撥上傳進度 */ public RequestBody wrapRequestBody(RequestBody requestBody) { ProgressRequestBody progressRequestBody = new ProgressRequestBody(requestBody); progressRequestBody.setListener(new ProgressRequestBody.Listener() { @Override public void onRequestProgress(final long bytesWritten, final long contentLength, final long networkSpeed) { OkGo.getInstance().getDelivery().post(new Runnable() { @Override public void run() { if (mCallback != null) mCallback.upProgress(bytesWritten, contentLength, bytesWritten * 1.0f / contentLength, networkSpeed); } }); } }); return progressRequestBody; } /** 根據不同的請求方式,將RequestBody轉換成Request物件 */ public abstract Request generateRequest(RequestBody requestBody); /** 根據當前的請求引數,生成對應的 Call 任務 */ public okhttp3.Call generateCall(Request request) { mRequest = request; if (readTimeOut <= 0 && writeTimeOut <= 0 && connectTimeout <= 0 && sslParams == null && userCookies.size() == 0) { return OkGo.getInstance().getOkHttpClient().newCall(request); } else { OkHttpClient.Builder newClientBuilder = OkGo.getInstance().getOkHttpClient().newBuilder(); if (readTimeOut > 0) newClientBuilder.readTimeout(readTimeOut, TimeUnit.MILLISECONDS); if (writeTimeOut > 0) newClientBuilder.writeTimeout(writeTimeOut, TimeUnit.MILLISECONDS); if (connectTimeout > 0) newClientBuilder.connectTimeout(connectTimeout, TimeUnit.MILLISECONDS); if (hostnameVerifier != null) newClientBuilder.hostnameVerifier(hostnameVerifier); if (sslParams != null) newClientBuilder.sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager); if (userCookies.size() > 0) OkGo.getInstance().getCookieJar().addCookies(userCookies); if (interceptors.size() > 0) { for (Interceptor interceptor : interceptors) { newClientBuilder.addInterceptor(interceptor); } } return newClientBuilder.build().newCall(request); } } /** 獲取同步call物件 */ public okhttp3.Call getCall() { //構建請求體,返回call物件 RequestBody requestBody = generateRequestBody(); mRequest = generateRequest(wrapRequestBody(requestBody)); return generateCall(mRequest); } /** Rx支援,獲取同步call物件 */ public <T> Call<T> getCall(Converter<T> converter) { mConverter = converter; return DefaultCallAdapter.<T>create().adapt(new CacheCall<T>(this)); } /** Rx支援,獲取同步call物件 */ public <T, E> E getCall(Converter<T> converter, CallAdapter<E> adapter) { mConverter = converter; return adapter.adapt(getCall(converter)); } /** 普通呼叫,阻塞方法,同步請求執行 */ public Response execute() throws IOException { return getCall().execute(); } /** 非阻塞方法,非同步請求,但是回撥在子執行緒中執行 */ @SuppressWarnings("unchecked") public <T> void execute(AbsCallback<T> callback) { mCallback = callback; mConverter = callback; new CacheCall<T>(this).execute(callback); } }
HttpsUtils:   
public abstract class SSLSocketFactory extends SocketFactory {
    public SSLSocketFactory() {
        throw new RuntimeException("Stub!");
    }
// 第一次呼叫此方法時,將檢查安全屬性 "ssl.SocketFactory.provider"。
// 如果它不為 null,則載入並例項化使用該名稱的類。
// 如果成功並且該物件是 SSLSocketFactory 的例項,則它成為預設的 SSL 套接字工廠。
    public static synchronized SocketFactory getDefault() {
        throw new RuntimeException("Stub!");
    }
// 返回預設情況下啟用的密碼套件的列表。
// 除非啟用了不同的列表,否則 SSL 連線上的聯絡將使用這些密碼套件中的一個。
        // 這些預設值的最低服務質量是要求保護機密性和伺服器驗證(也就是說沒有匿名的密碼套件)。
    public abstract String[] getDefaultCipherSuites();
// 返回可以在 SSL 連線上啟用的密碼套件的名稱。
// 通常,因為此列表可能包含不能滿足這些預設值的服務質量要求的密碼套件,所以預設情況下只能實際啟用它們的子集。
//這種密碼套件在專門的應用程式中才能有用。
    public abstract String[] getSupportedCipherSuites();
// 返回在連線到指定主機的給定埠的現有套接字上分層的套接字。
// 通過代理使用 SSL 或者協商在已有的套接字上使用 SSL 時可以使用此構造方法。
// 主機和埠號指的是邏輯同位體目標。使用為此工廠建立的套接字選項來配置此套接字。
    public abstract Socket createSocket(Socket var1, String var2, int var3, boolean var4) throws IOException;
}
 此介面的例項管理使用哪一個 X509 證書來驗證遠端的安全套接字。決定是根據信任的證書授權、證書撤消列表、線上狀態檢查或其他方式做出的。
public interface X509TrustManager extends TrustManager {
 //  給出同位體提供的部分或完整的證書鏈,構建到可信任的根的證書路徑,並且返回是否可以確認和信任將其用於基於驗證型別的客戶端 SSL 驗證。
    void checkClientTrusted(X509Certificate[] var1, String var2) throws CertificateException;
  //  給出同位體提供的部分或完整的證書鏈,構建到可信任的根的證書路徑,並且返回是否可以確認和信任將其用於基於驗證型別的伺服器 SSL 驗證。
    void checkServerTrusted(X509Certificate[] var1, String var2) throws CertificateException;
  //  返回受驗證同位體信任的認證中心的陣列。
    X509Certificate[] getAcceptedIssuers();
}
/** Https相關的工具類 */
public class HttpsUtils {

    public static class SSLParams {
        public SSLSocketFactory sSLSocketFactory;
        public X509TrustManager trustManager;
    }

    public static SSLParams getSslSocketFactory(InputStream bksFile, String password, InputStream[] certificates) {
        SSLParams sslParams = new SSLParams();
        try {
            KeyManager[] keyManagers = prepareKeyManager(bksFile, password);
            TrustManager[] trustManagers = prepareTrustManager(certificates);
            SSLContext sslContext = SSLContext.getInstance("TLS");
            X509TrustManager trustManager;
            if (trustManagers != null) {
                trustManager = new MyTrustManager(chooseTrustManager(trustManagers));
            } else {
                trustManager = new UnSafeTrustManager();
            }
            sslContext.init(keyManagers, new TrustManager[]{trustManager}, null);
            sslParams.sSLSocketFactory = sslContext.getSocketFactory();
            sslParams.trustManager = trustManager;
            return sslParams;
        } catch (NoSuchAlgorithmException e) {
            throw new AssertionError(e);
        } catch (KeyManagementException e) {
            throw new AssertionError(e);
        } catch (KeyStoreException e) {
            throw new AssertionError(e);
        }
    }

    private static TrustManager[] prepareTrustManager(InputStream... certificates) {
        if (certificates == null || certificates.length <= 0) return null;
        try {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            int index = 0;
            for (InputStream certificate : certificates) {
                String certificateAlias = Integer.toString(index++);
                keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
                try {
                    if (certificate != null) certificate.close();
                } catch (IOException e) {
                    OkLogger.e(e);
                }
            }
            TrustManagerFactory trustManagerFactory;
            trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            return trustManagerFactory.getTrustManagers();
        } catch (NoSuchAlgorithmException e) {
            OkLogger.e(e);
        } catch (CertificateException e) {
            OkLogger.e(e);
        } catch (KeyStoreException e) {
            OkLogger.e(e);
        } catch (Exception e) {
            OkLogger.e(e);
        }
        return null;
    }

    private static KeyManager[] prepareKeyManager(InputStream bksFile, String password) {
        try {
            if (bksFile == null || password == null) return null;
            KeyStore clientKeyStore = KeyStore.getInstance("BKS");
            clientKeyStore.load(bksFile, password.toCharArray());
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(clientKeyStore, password.toCharArray());
            return keyManagerFactory.getKeyManagers();
        } catch (KeyStoreException e) {
            OkLogger.e(e);
        } catch (NoSuchAlgorithmException e) {
            OkLogger.e(e);
        } catch (UnrecoverableKeyException e) {
            OkLogger.e(e);
        } catch (CertificateException e) {
            OkLogger.e(e);
        } catch (IOException e) {
            OkLogger.e(e);
        } catch (Exception e) {
            OkLogger.e(e);
        }
        return null;
    }

    private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers) {
        for (TrustManager trustManager : trustManagers) {
            if (trustManager instanceof X509TrustManager) {
                return (X509TrustManager) trustManager;
            }
        }
        return null;
    }

    private static class UnSafeTrustManager implements X509TrustManager {
        @Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
public X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[]{};
        }
    }

    private static class MyTrustManager implements X509TrustManager {
        private X509TrustManager defaultTrustManager;
        private X509TrustManager localTrustManager;

        public MyTrustManager(X509TrustManager localTrustManager) throws NoSuchAlgorithmException, KeyStoreException {
            TrustManagerFactory var4 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            var4.init((KeyStore) null);
            defaultTrustManager = chooseTrustManager(var4.getTrustManagers());
            this.localTrustManager = localTrustManager;
        }

        @Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

        }

        @Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            try {
                defaultTrustManager.checkServerTrusted(chain, authType);
            } catch (CertificateException ce) {
                localTrustManager.checkServerTrusted(chain, authType);
            }
        }

        @Override
public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }
}

/**
 * ================================================
 * 作    者:jeasonlzy(廖子堯)Github地址:https://github.com/jeasonlzy0216
 * 版    本:1.0
 * 建立日期:16/8/9
 * 描    述:表示當前請求是否具有請求體
 * 修訂歷史:
 * ================================================
 */
public interface HasBody<R> {
    R requestBody(RequestBody requestBody);

    R params(String key, File file);

    R addFileParams(String key, List<File> files);

    R addFileWrapperParams(String key, List<HttpParams.FileWrapper> fileWrappers);

    R params(String key, File file, String fileName);

    R params(String key, File file, String fileName, MediaType contentType);

    R upString(String string);

    R upJson(String json);

    R upBytes(byte[] bs);
}