Android Volley框架支持https请求 - Go语言中文社区

Android Volley框架支持https请求


转载请标明出处:【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>
同样可以达到效果。




版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/hlglinglong/article/details/42553829
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-06-27 21:56:46
  • 阅读 ( 1591 )
  • 分类:Go Web框架

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢