Android 使Volley完美支持自定义证书的Https
其实在最早的版本里,Volley甚至是不支持https协议的,只能跑http,当然你也可以自己修改他的源码让他支持,如今volley的代码经过一些改进以后,
已经可以完美支持https协议了,无论是在2.3版本以上还是在2.3版本以下,大家可以尝试用volley去访问github 是成功的,但是你如果用volley去访问
12306这种类似的 用自定义证书的网站 就很容易失败。那我下面就把volley 代码稍作修改,让volley也可以完美支持自定义证书的https请求。
当然代码只是展示功能使用,你们可以用更优雅的方式 ----实现一个HttpStack,然后直接传你自定义好的stack即可。我这里图简便就写了个最简单
的演示代码。其实难倒是也不难,主要还是要考虑2.3版本以上和以下的两种情况。
第一步,把你的自定义证书 拷贝到res/raw/下。

第二步,稍微修改下volley的源码
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package com.android.volley.toolbox; import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.http.AndroidHttpClient;
import android.os.Build;
import android.util.Log; import com.android.volley.Network;
import com.android.volley.RequestQueue; import org.apache.http.client.HttpClient;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams; import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory; public class Volley { /**
* Default on-disk cache directory.
*/
private static final String DEFAULT_CACHE_DIR = "volley"; private Context mContext; /**
* 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, boolean selfSignedCertificate, int rawId) {
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) {
if (selfSignedCertificate) {
stack = new HurlStack(null, buildSSLSocketFactory(context, rawId));
} else {
stack = new HurlStack();
}
} else {
// Prior to Gingerbread, HttpUrlConnection was unreliable.
// See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
if (selfSignedCertificate)
stack = new HttpClientStack(getHttpClient(context, rawId));
else {
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
}
} Network network = new BasicNetwork(stack); RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
queue.start(); return queue;
} /**
* 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.
* @return A started {@link RequestQueue} instance.
*/
public static RequestQueue newRequestQueue(Context context) {
return newRequestQueue(context, null, false, 0);
} private static SSLSocketFactory buildSSLSocketFactory(Context context, int certRawResId) {
KeyStore keyStore = null;
try {
keyStore = buildKeyStore(context, certRawResId);
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = null;
try {
tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore); } catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLS");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
sslContext.init(null, tmf.getTrustManagers(), null);
} catch (KeyManagementException e) {
e.printStackTrace();
} return sslContext.getSocketFactory(); } private static HttpClient getHttpClient(Context context, int certRawResId) {
KeyStore keyStore = null;
try {
keyStore = buildKeyStore(context, certRawResId);
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (keyStore != null) {
}
org.apache.http.conn.ssl.SSLSocketFactory sslSocketFactory = null;
try {
sslSocketFactory = new org.apache.http.conn.ssl.SSLSocketFactory(keyStore);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} HttpParams params = new BasicHttpParams(); SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", sslSocketFactory, 443)); ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, schemeRegistry); return new DefaultHttpClient(cm, params);
} private static KeyStore buildKeyStore(Context context, int certRawResId) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null); Certificate cert = readCert(context, certRawResId);
keyStore.setCertificateEntry("ca", cert); return keyStore;
} private static Certificate readCert(Context context, int certResourceID) {
InputStream inputStream = context.getResources().openRawResource(certResourceID);
Certificate ca = null; CertificateFactory cf = null;
try {
cf = CertificateFactory.getInstance("X.509");
ca = cf.generateCertificate(inputStream); } catch (CertificateException e) {
e.printStackTrace();
}
return ca;
}
}
第三步就是调用方式稍微做下修改:
其实主要就是你如果想使用自定义的证书https的时候 第三个参数记得传true,并且把证书也传进去,
当然写的优雅的话还是最好自己写个httpstack,然后volley的源码可以不用改,只需要在使用的时候
传自己的stack即可

Android 使Volley完美支持自定义证书的Https的更多相关文章
- 使Volley完美支持自定义证书的Https
其实在最早的版本里,Volley甚至是不支持https协议的,只能跑http,当然你也可以自己修改他的源码让他支持,如今volley的代码经过一些改进以后, 已经可以完美支持https协议了,无论是在 ...
- (转载)Android快速开发偷懒必备,一句话搞定所有ViewGroup的Adapter . 支持自定义ViewGroup
[置顶] [Android]快速开发偷懒必备,一句话搞定所有ViewGroup的Adapter . 支持自定义ViewGroup 标签: androidAdapter快速开发0耦合 2016-12-1 ...
- Retrofit 2.0 超能实践(一),okHttp完美支持Https传输
http: //blog.csdn.net/sk719887916/article/details/51597816 Tamic首发 前阵子看到圈子里Retrofit 2.0,RxJava(Andro ...
- Retrofit 2.0 超能实践,完美支持Https传输
http://blog.csdn.NET/sk719887916/article/details/51597816 前阵子看到圈子里Retrofit 2.0,RxJava(Android), OkHt ...
- 让个人域名下GithubPage完美支持https
让个人域名下GithubPage完美支持https 欢迎访问完美HTTPS支持的GithubPage个人博客 : https://zggdczfr.cn/ 前言 最近笔记本挂了送去维修,耽误了我的学习 ...
- Volley框架支持HTTPS请求。
第一次写帖子,嘿嘿. 最近了解到google2013IO大会出了个网络框架,正好项目也需要用到,就看了下. 最后发现接口都是HTTPS的,但是Volley默认是不支持HTTPS,网上找了好久,都没有对 ...
- 强烈推荐:Android史上最强大的自定义任务软件Tasker
强烈推荐:Android史上最强大的自定义任务软件Taskerhttp://bbs.mumayi.com/thread-28387-1-1.html(出处: 木蚂蚁手机乐园) Android上的Tas ...
- 并发编程概述 委托(delegate) 事件(event) .net core 2.0 event bus 一个简单的基于内存事件总线实现 .net core 基于NPOI 的excel导出类,支持自定义导出哪些字段 基于Ace Admin 的菜单栏实现 第五节:SignalR大杂烩(与MVC融合、全局的几个配置、跨域的应用、C/S程序充当Client和Server)
并发编程概述 前言 说实话,在我软件开发的头两年几乎不考虑并发编程,请求与响应把业务逻辑尽快完成一个星期的任务能两天完成绝不拖三天(剩下时间各种浪),根本不会考虑性能问题(能接受范围内).但随着工 ...
- Android线程管理之ThreadPoolExecutor自定义线程池
前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...
随机推荐
- 配置IIS应用程序池
IIS 6的核心在于工作进程隔离模式,而应用程序池则是定义工作进程如何进行工作,因此,可以说应用程序池是整个IIS 6的核心. 和IIS 5中只能使用单个应用程序池不同,工作在工作进程隔离模式的IIS ...
- centOS学习part1:操作系统安装
0 linux作为服务器的主要操作系统,在处理速度以及安全性上都要优于windows,虽然需要很多命令要记,但是一般常用的命令不多,用多了就熟悉了,而且现在很多都要图形界面,也降低了学习成本. cen ...
- 2011 ACM/ICPC 成都赛区(为2013/10/20成都现场赛Fighting)
hdu 4111 Alice and Bob 博弈:http://www.cnblogs.com/XDJjy/p/3350014.html hdu 4112 Break the Chocolate ...
- web.xml文件中加载顺序的优先级
在项目中总会遇到一些关于加载的优先级问题,近期也同样遇到过类似的,所以自己查找资料总结了下,下面有些是转载其他人的,毕竟人家写的不错,自己也就不重复造轮子了,只是略加点了自己的修饰. 首先可以肯定的是 ...
- Haproxy均衡负载部署和配置文件详解
HAproxy均衡负载部署和配置文件详解 HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.根据官方数据,其最高极限支持10G ...
- CentOS下支持exFAT与NTFS
exFAT: 1.下载fuse-exfat支持软件: exfat支持是通过fuse模块的方式支持的,其项目地址是: https://code.google.com/p/exfat/ ,当前版本是:1. ...
- C++:delete和delete[]释放内存的区别
C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]. 关于 new[] 和 delete[], ...
- Data Flow ->> Term Extraction
中文意思是关键词抽取,用于计算在文本中哪些词汇或者词组出现的频率最高.其实算法有两张:1)Frequency 2)TFIDF TFIDF的全称是Term Frequency and Inverse D ...
- 机器人学 —— 机器人视觉(Bundle Adjustment)
今天完成了机器人视觉的所有课程以及作业,确实是受益匪浅啊! 最后一个话题是Bundle Adjustment. 机器人视觉学中,最顶尖的方法. 1.基于非线性优化的相机位姿估计 之前已经在拟合一篇中, ...
- Java 类加载器(转)
java虚拟机中可以安装多个类加载,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap(内嵌在java虚拟机中由C++编写),ExtClassLoader,AppClassLoa ...