Android 当Volley遇到Https

前言

皇天不负有心人, 先感谢hongyang大哥的文章:
Android Https相关彻底解析 当OkHttp遇到Httpshtml

说实话,若是你认真看完顶上那篇hongyang大哥的文章(我认可有点长,我也看了好久也不止一遍),你会发现,其实https就是用证书嘛,具体怎么弄别人都给你封装好了,你只要把证书放到 SSLSocketFactory 就好了java

你们若是有须要,能够先看了后面的【关于证书】后再次看hongyang大哥的生成方法,由于我提到了几个我踩的坑,但愿你们别踩到了android

准备

  • 单向验证(准备一对证书)、双向验证(准备两对证书)
  • Volley(jar也好,compile也好)
  • copy进来hongyang大哥的工具类HttpsUtils

操做

具体能够去看这里 https://github.com/mBigFlower/volley-utils/blob/master/volleyutil/src/main/java/com/flowerfat/volleyutil/https/HttpsUtils.java
我对hongyang大哥的HttpsUtils作了改动,如今返回SSLSocketFactory,而后在建立RequestQueue是就把它加进去git

HurlStack hurlStack = new HurlStack(null, HttpsUtils.initCertificates(bksFile, password, certificates));
 mRequestQueue = Volley.newRequestQueue(context, hurlStack);

原理

用过Volley的都知道,咱们发起网络请求前,会先建立一个请求队列github

RequestQueue mRequestQueue = Volley.newRequestQueue(context);

咱们进入newRequestQueue所在的类Volley去看看咋回事儿web

public static RequestQueue newRequestQueue(Context context) {
        return newRequestQueue(context, null);
    }

    public static RequestQueue newRequestQueue(Context context, HttpStack stack)
    {
        return newRequestQueue(context, stack, -1);
    }

    public static RequestQueue newRequestQueue(Context context, HttpStack stack, int maxDiskCacheBytes) {
        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;
        if (maxDiskCacheBytes <= -1)
        {
            // No maximum size specified
            queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
        }
        else
        {
            // Disk cache size specified
            queue = new RequestQueue(new DiskBasedCache(cacheDir, maxDiskCacheBytes), network);
        }

        queue.start();

        return queue;
    }
public static RequestQueue newRequestQueue(Context context) {
        return newRequestQueue(context, null);
    }

其实这里面默认的HttpStack是为null的,那HttpStack是什么?咱们来看第三个构造函数里的这句话tomcat

if (stack == null) {
        if (Build.VERSION.SDK_INT >= 9) {
            stack = new HurlStack();
        } else {
            stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
        }
    }

额,这个判断我也是醉了,咱们能够直接忽略4.0如下吧?那直接看 new HurlStack();服务器

public HurlStack() {
        this(null);
    }

    public HurlStack(UrlRewriter urlRewriter) {
        this(urlRewriter, null);
    }

    public HurlStack(UrlRewriter urlRewriter, SSLSocketFactory sslSocketFactory) {
        mUrlRewriter = urlRewriter;
        mSslSocketFactory = sslSocketFactory;
    }

看到没,看到没?那个SSLSocketFactory !
没错,若是你看过hongyang大哥的文章,你就会直到,okhttp就是经过这个把证书信任进去的网络

关于证书

在跟服务器联调前,咱们能够先验证下咱们的方法是否正确
具体的操做就去看洪洋大哥的文章吧,我就再也不墨迹了。可是有几个坑须要注意一下:svg

  1. 在生成证书的时候,最好再后面加上这个:-ext san=ip:192.168.56.1 后面的ip地址换成道友大家电脑的ip,否则可能会出现 hostname 192…….. not verified的错误
  2. 下图中,那些是一块儿的,别看是四行,当初我就脑残的只输入第一行。。。hongyang大哥文章里的
  3. 在双向验证证书中,jks转bks,使用portecle时,这句话“解压后,里面包含bcprov.jar文件,使用jave -jar bcprov.jar便可打开GUI界面。” ,其实应该是java -jar portecle.jar
  4. 你们使用tomcat的时候,我不造为啥有的时候下载下来的zip不能用,start到一半就没有下文了。多是配置的问题,你们也能够下载安装包哈,今天我本子就是用安装包的。(若是你用的是zip解压的,打开tomcat7w.exe前,可能须要在命令行中输入server.bat install)

源码

源码都在 https://github.com/mBigFlower/volley-utils 里,这是我本身封装的Volley,对于证书的配置在VolleyUtils里的init()