我的Volley+OkHttp实现Https

在参考了Android 网络--我是怎么做的: Volley+OkHttp+Https 之后,我总结了下,实现了自己的网络请求框架

先上框架图:


我的Volley+OkHttp实现Https_第1张图片
网络请求框架模块

这里主要说下OkHttpStack.java这个类,因为我是通过修改它来实现的Https
话不多说,直接上代码:

/**
 * Created by caihan on 2016/9/14.
 */
public class OkHttpStack extends HurlStack {

    private static final String TAG = "OkHttpStack";
    private OkHttpClient okHttpClient;
    private boolean useClientAuth = false;

//    private static String mHttpsHost = "kyfw.12306.cn";
//    private static int mRes = R.raw.kyfw;
//    private static String mPassWord = "asdfqaz";

    public OkHttpStack() {
        this(new OkHttpClient());
    }

    public OkHttpStack(OkHttpClient okHttpClient) {
        this.okHttpClient = okHttpClient;
    }

    @Override
    protected HttpURLConnection createConnection(URL url) throws IOException {
        if ("https".equals(url.getProtocol())) {
            HttpsURLConnection connection = (HttpsURLConnection) new OkUrlFactory(okHttpClient).open(url);
            try {
                connection.setSSLSocketFactory(createSSLSocketFactory(AppData.getContext(), -1, null));
            } catch (CertificateException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyStoreException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }
            return connection;
        } else {
            return new OkUrlFactory(okHttpClient).open(url);
        }
    }


    private SSLSocketFactory createSSLSocketFactory(Context context, int res, String password)
            throws CertificateException,
            NoSuchAlgorithmException,
            IOException,
            KeyStoreException,
            KeyManagementException {
        KeyManager[] kms = null;
        TrustManagerFactory tmf = null;
        // 实例化SSL上下文
        SSLContext sslContext = SSLContext.getInstance("TLS");
        if (res > 0 && !TextUtils.isEmpty(password)) {
            InputStream inputStream = context.getResources().openRawResource(res);
            // 获得信任库
            KeyStore keyStore = KeyStore.getInstance("BKS");
            keyStore.load(inputStream, password.toCharArray());
            // 实例化信任库
            tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            // 初始化信任库
            tmf.init(keyStore);
            if (useClientAuth) {
                try {
                    String KEYSTORE_PASSWORD = "pass";
                    // 获得密钥库
                    KeyStore keyStoreM = KeyStore.getInstance("PKCS12");//JKS
                    keyStoreM.load(inputStream, KEYSTORE_PASSWORD.toCharArray());
                    // 实例化密钥库
                    KeyManagerFactory kmf = KeyManagerFactory
                            .getInstance(KeyManagerFactory.getDefaultAlgorithm());
                    // 初始化密钥工厂
                    kmf.init(keyStoreM, KEYSTORE_PASSWORD.toCharArray());
                    kms = kmf.getKeyManagers();
                } catch (UnrecoverableKeyException e) {
                    e.getMessage();
                }
            }
            // 初始化SSL上下文
            sslContext.init(kms, tmf.getTrustManagers(), new SecureRandom());
        } else {
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[]{};
                }

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

                public void checkServerTrusted(X509Certificate[] chain,
                                               String authType) throws CertificateException {
                }
            }};
            sslContext.init(null, trustAllCerts, new SecureRandom());
        }
        return sslContext.getSocketFactory();
    }


    /**
     * 在getInstance在Application中,若需要是用https,需要先调用此方法
     * 并且部分参数、方法、协议等可能需要改动
     *
     * @param httpsHost
     * @param res
     * @param password
     */
    public static void prepareHttps(String httpsHost, int res, String password) {
//        mHttpsHost = httpsHost;
//        mRes = res;
//        password = mPassWord;
    }

}

你可能感兴趣的:(我的Volley+OkHttp实现Https)