关闭

Android Volley框架支持https请求

标签: Volleyhttpssslhttps认证
3023人阅读 评论(1) 收藏 举报
分类:

转载请标明出处:【http://blog.csdn.net/hlglinglong/article/details/42553829

1.概述

Volley框架相信大家都不陌生了,具体的介绍就不多说了,自己百度~
但是在实际的使用中,我们服务端的接口大多使用https的方式进行访问,volley默认不支持https的访问方式。
这就需要我们来手动的修改来是volley可以支持volley

2.问题分析

其实Volley可以支持HTTPS,但是框架中默认没有加上去我们可以修改一小部分源码来实现这以功能。

volley的网络请求 先要通过toolbox包下的Volley.java生成一个requestQueue.在requestQueue去分发请求,处理请求是使用HttpStack接口来完成的。看下面的代码Volley.java中的newRequestQueueInDisk

 

<span style="font-family:SimSun;"><span style="font-family:SimSun;font-size:14px;"><strong> /**
     * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
     *
     * @param context A {@link Context} to use for creating the cache dir.
     * @param stack An {@link HttpStack} to use for the network, or null for default.
     * @return A started {@link RequestQueue} instance.
     */
    public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
        File cacheDir = new File(context.getCacheDir(), 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) {
            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;
    }
</strong></span></span>

我们来看下HurlStack这个类的构造大家就会发现其实volley可以支持https了,同样位于toolbox包下

<span style="font-family:SimSun;">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;
    }</span>

<span style="font-family:SimSun;">   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);

        // use caller-provided custom SslSocketFactory, if any, for HTTPS
        if ("https".equals(url.getProtocol()) && mSslSocketFactory != null) {
            ((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory);
        }

        return connection;
    }</span>

由此可以看出HurlStack 是支持HTTPS 只是在Volley.java生成对象时调用的是无参构造。所以 SSLSocketFactory并没有实例对象。导致默认Volley不支持https请求

3.解决方案

1)既然volley框架里面有https请求方式,只不过没有调用,那么一种修改的方法是重写Volley.java newRequestQueueInDisk方法 调用第三个构造。又因为这三个构造最后调用的都是参数最多的那个所以也可以在第三个构造中直接默认生成SSLSocketFactory示例。但是我没有用这种方法。
2)

在toolbox中添加HTTPSTrustManager类(代码网上找的- -、),并对HurlStack的createConnetcion方法进行了小小的修改。

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.android.volley.toolbox;  
  2.   
  3. import java.security.KeyManagementException;  
  4. import java.security.NoSuchAlgorithmException;  
  5. import java.security.SecureRandom;  
  6. import java.security.cert.X509Certificate;  
  7.   
  8. import javax.net.ssl.HostnameVerifier;  
  9. import javax.net.ssl.HttpsURLConnection;  
  10. import javax.net.ssl.SSLContext;  
  11. import javax.net.ssl.SSLSession;  
  12. import javax.net.ssl.TrustManager;  
  13. import javax.net.ssl.X509TrustManager;  
  14.   
  15. public class HTTPSTrustManager implements X509TrustManager {  
  16.   
  17.     private static TrustManager[] trustManagers;  
  18.     private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[] {};  
  19.   
  20.     @Override  
  21.     public void checkClientTrusted(  
  22.             java.security.cert.X509Certificate[] x509Certificates, String s)  
  23.             throws java.security.cert.CertificateException {  
  24.         // To change body of implemented methods use File | Settings | File  
  25.         // Templates.  
  26.     }  
  27.   
  28.     @Override  
  29.     public void checkServerTrusted(  
  30.             java.security.cert.X509Certificate[] x509Certificates, String s)  
  31.             throws java.security.cert.CertificateException {  
  32.         // To change body of implemented methods use File | Settings | File  
  33.         // Templates.  
  34.     }  
  35.   
  36.     public boolean isClientTrusted(X509Certificate[] chain) {  
  37.         return true;  
  38.     }  
  39.   
  40.     public boolean isServerTrusted(X509Certificate[] chain) {  
  41.         return true;  
  42.     }  
  43.   
  44.     @Override  
  45.     public X509Certificate[] getAcceptedIssuers() {  
  46.         return _AcceptedIssuers;  
  47.     }  
  48.   
  49.     public static void allowAllSSL() {  
  50.         HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {  
  51.   
  52.             @Override  
  53.             public boolean verify(String arg0, SSLSession arg1) {  
  54.                 // TODO Auto-generated method stub  
  55.                 return true;  
  56.             }  
  57.   
  58.         });  
  59.   
  60.         SSLContext context = null;  
  61.         if (trustManagers == null) {  
  62.             trustManagers = new TrustManager[] { new HTTPSTrustManager() };  
  63.         }  
  64.   
  65.         try {  
  66.             context = SSLContext.getInstance("TLS");  
  67.             context.init(null, trustManagers, new SecureRandom());  
  68.         } catch (NoSuchAlgorithmException e) {  
  69.             e.printStackTrace();  
  70.         } catch (KeyManagementException e) {  
  71.             e.printStackTrace();  
  72.         }  
  73.   
  74.         HttpsURLConnection.setDefaultSSLSocketFactory(context  
  75.                 .getSocketFactory());  
  76.     }  
  77.   
  78. }  

createConnction方法的修改

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. protected HttpURLConnection createConnection(URL url) throws IOException {  
  2.     //如果请求是https请求那么就信任所有SSL  
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <span style="white-space:pre">  </span>if (url.toString().contains("https")) {  
  2.               HTTPSTrustManager.allowAllSSL();  
  3.         }  
  4.         return (HttpURLConnection) url.openConnection();  
  5.     }  

其实就是添加了一个 HTTPSTrustManager类 并在createConnection中调用一下HTTPSTrustManager.allowAllSSL()。
3)
不修改volley框架代码,在创建Request请求之前设置,如下
<span style="font-family:SimSun;">HttpTrustManager.allowAllSSL();
mStringRequest = new StringRequest(Request.Method.POST,url,getDefaultSuccessListener(),
  mErrorListener){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                return params;
            }
  };
mRequestQueue.add(mStringRequest);</span>
同样可以达到效果。




1
0

猜你在找
深度学习基础与TensorFlow实践
【在线峰会】前端开发重点难点技术剖析与创新实践
【在线峰会】一天掌握物联网全栈开发之道
【在线峰会】如何高质高效的进行Android技术开发
机器学习40天精英计划
Python数据挖掘与分析速成班
微信小程序开发实战
JFinal极速开发企业实战
备战2017软考 系统集成项目管理工程师 学习套餐
Python大型网络爬虫项目开发实战(全套)
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:116598次
    • 积分:1839
    • 等级:
    • 排名:千里之外
    • 原创:60篇
    • 转载:30篇
    • 译文:0篇
    • 评论:18条
    最新评论