經過前面的內容能夠使你們對Volley有所瞭解。下面就開始講支持HTTPS的實現。html
其實Volley能夠支持HTTPS,可是框架中默認沒有加上去咱們能夠修改一小部分源碼來實現這以功能。java
volley的網絡請求 先要經過toolbox包下的Volley.java生成一個requestQueue.在requestQueue去分發請求,處理請求是使用HttpStack接口來完成的。看下面的代碼Volley.java中的newRequestQueueInDiskandroid
public static RequestQueue newRequestQueueInDisk(Context context, String dir, HttpStack stack) { File cacheDir = new File(dir, DEFAULT_CACHE_DIR); String userAgent = "volley/0"; try { String packageName = context.getPackageName(); PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0); userAgent = packageName + "/" + info.versionCode; } catch (NameNotFoundException e) { } if (stack == null) { //2.3及以上版本使用HurlStack來處理請求 if (Build.VERSION.SDK_INT >= 9) { stack = new HurlStack(); } else { // Prior to Gingerbread, HttpUrlConnection was unreliable. // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); } } Network network = new BasicNetwork(stack); RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network); queue.start(); return queue; }
咱們來看下HurlStack這個類的構造你們就會發現其實volley能夠支持https了,一樣位於toolbox包下網絡
public HurlStack() { this(null); } /** * @param urlRewriter Rewriter to use for request URLs */ public HurlStack(UrlRewriter urlRewriter) { this(urlRewriter, null); } /** * @param urlRewriter Rewriter to use for request URLs * @param sslSocketFactory SSL factory to use for HTTPS connections */ public HurlStack(UrlRewriter urlRewriter, SSLSocketFactory sslSocketFactory) { mUrlRewriter = urlRewriter; mSslSocketFactory = sslSocketFactory; } private HttpURLConnection openConnection(URL url, Request<?> request) throws IOException { HttpURLConnection connection = createConnection(url); int timeoutMs = request.getTimeoutMs(); connection.setConnectTimeout(timeoutMs); connection.setReadTimeout(timeoutMs); connection.setUseCaches(false); connection.setDoInput(true); <span style="color:#ff6600;"> </span>// use caller-provided custom SslSocketFactory, if any, for HTTPS if ("https".equals(url.getProtocol()) && mSslSocketFactory != null) { ((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory); } return connection; }
由此能夠看出HurlStack 是支持HTTPS 只是在Volley.java生成對象時調用的是無參構造。因此 SSLSocketFactory並無實例對象。框架
那麼一種修改的方法是重寫Volley.java newRequestQueueInDisk方法 調用第三個構造。又由於這三個構造最後調用的都是參數最多的那個因此也能夠在第三個構造中直接默認生成SSLSocketFactory示例。可是我沒有用這種方法。dom
個人實現方法是在toolbox中添加HTTPSTrustManager類(代碼網上找的- -、),並對HurlStack的createConnetcion方法進行了小小的修改。ide
package com.android.volley.toolbox; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; public class HTTPSTrustManager implements X509TrustManager { private static TrustManager[] trustManagers; private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[] {}; @Override public void checkClientTrusted( java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException { // To change body of implemented methods use File | Settings | File // Templates. } @Override public void checkServerTrusted( java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException { // To change body of implemented methods use File | Settings | File // Templates. } public boolean isClientTrusted(X509Certificate[] chain) { return true; } public boolean isServerTrusted(X509Certificate[] chain) { return true; } @Override public X509Certificate[] getAcceptedIssuers() { return _AcceptedIssuers; } public static void allowAllSSL() { HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String arg0, SSLSession arg1) { // TODO Auto-generated method stub return true; } }); SSLContext context = null; if (trustManagers == null) { trustManagers = new TrustManager[] { new HTTPSTrustManager() }; } try { context = SSLContext.getInstance("TLS"); context.init(null, trustManagers, new SecureRandom()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } HttpsURLConnection.setDefaultSSLSocketFactory(context .getSocketFactory()); } }
createConnction方法的修改ui
protected HttpURLConnection createConnection(URL url) throws IOException { //若是請求是https請求那麼就信任全部SSL if (url.toString().contains("https")) { HTTPSTrustManager.allowAllSSL(); } return (HttpURLConnection) url.openConnection(); }
其實就是添加了一個 HTTPSTrustManager類 並在createConnection中調用一下HTTPSTrustManager.allowAllSSL()。
this