Android 访问https的webservices接口
小编很久没有更新博客了,借着这两天之内周末将最近研究的Android 访问https webservices接口调用Mark这里。
知识储备
- 认识什么是https,https的交互原理是什么
- 什么是webservices接口
- Android是如何调用webservices接口的
以上都不是本文的重点,知识储备不足的同学自行度娘,本文主要介绍的是Android端如何访问带有证书的接口,以及介绍如何配置本地项目的Tomcat自定义的证书
Android 客户端
开始***********我就是一条间隔线*******************
咳咳,先说Androiod访问webservices使用的第三方的库Ksoap的jar包,访问http和https的区别无非在于https添加了证书而已,反应到代码中最直接的是需要讲http调用的HttpTransportSE 换成HttpsTransportSE(实际使用过程中发现有低版本的ksoapjar包找不到该Api,果断更换jar即可)。另外需要在访问中客户端需要携带服务器认证的客户端证书访问。
本文只要提供单项认证的代码实现,亲测可用,双向认证时间有限没有亲自验证,后边补上
public static void webservicesHelp(final String method, String nameSpace, String endPoint, HashMap<String, Object> properties,
final WebServiceCallBack webServiceCallBack) {
SoapObject rpc = new SoapObject(nameSpace, method);
if (properties != null) {
for (Iterator<Map.Entry<String, Object>> it = properties.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, Object> entry = it.next();
rpc.addProperty(entry.getKey(), entry.getValue());
}
}
final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);
new MarshalBase64().register(envelope);
envelope.bodyOut = rpc;
envelope.dotNet = false;
envelope.setOutputSoapObject(rpc);
//重新设置了超时时间为15s
//final HttpTransportSE transport = new HttpTransportSE(endPoint, 15000);
final HttpsTransportSE transport = new HttpsTransportSE("yuming", 9018, "/services/loginService", 15000);
try {
((HttpsServiceConnectionSE) transport.getServiceConnection()).setSSLSocketFactory(sunApplication.socketFactory);
} catch (IOException e) {
e.printStackTrace();
}
Runnable runable = new Runnable() {
@Override
public void run() {
SoapObject resultsRequestSOAP = null;
try {
//不为空就报类型转换错误""
transport.call("", envelope);
if (envelope.getResponse() != null) {
resultsRequestSOAP = (SoapObject) envelope.bodyIn;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
webServiceCallBack.callBack(resultsRequestSOAP);
}
}
};
new Thread(runable).start();
}
请注意代码中的
HttpstransportSE 和 SetSSLSocketFactoty方法,SetSSLSocketFactoty方法是读取本地的证书文件。
解释下
HttpsTransportSE("yuming", 9018, "/services/loginService", 15000)
其中的三个参数 分别是 域名,端口号,enidpoint(不解释)和最后的超时时间
接下来的问题就是如何读取cer证书了,建议将读取证书的方法放在application中执行,保证我们的app一运行就直接加载
读取证书如下
public class sunApplication extends Application {
private static final String TAG = "sunApplication";
public static SSLSocketFactory socketFactory = null;
@Override
public void onCreate() {
super.onCreate();
if (socketFactory == null) {
try {
socketFactory = SSLUtils.getSSLSocketFactory(getApplicationContext().getAssets().open("sun_server.cer"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
注意如果是,感觉吧证书直接放在assets文件中不妥的话,也可将证书的内容输出字符串,然后写在代码中,相应的方法变更为
//使用命令keytool -printcert -rfc -file srca.cer 导出证书为字符串,然后将字符串转换为输入流,如果使用的是okhttp可以直接使用new Buffer().writeUtf8(s).inputStream() //如果不是okhttp 可使用工具类String2InputStream(str)
//方法2 将文件转换成字符串以后转换成inputStram
//socketFactory = SSLUtils.getSSLSocketFactory(SSLUtils.String2InputStream("证书字符串"));
以上******************************************Android客户端的代码简介完毕(只是针对的单向认证)*******************************************
自定义证书的生成和配置服务器Tomcat
不啰嗦直接上码
生成证书使用的jdk自带的工具keytool,本地没有jdk环境的先行离去吧
cmd 定位到 jdk的bin目录下
生成服务器端的证书
- keytool -genkey -alias sun_server -keyalg RSA -keystore d:\keyStore\sun_server.jks -validity 3600 -storepass Passw0rd
- -alias 别名
- d:\keyStore\sun_server.jks证书的存储路径
- -validity 有效期
- -storepass 密码
注意我标注红色的部分,姓名地方填写正确的服务器域名!!
生成客户端用证书
接下来配置tomcat
找到tomcat的位置,定位到D:\MyEclipse10\apache-tomcat-6.0.44\conf 下的 server.xml
<Connector port="8088" SSLEnabled="true" acceptCount="100" clientAuth="false"
disableUploadTimeout="true" enableLookups="true" keystoreFile="d:\keyStore\sun_server.jks" keystorePass="Passw0rd"
maxThreads="200"
protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https"
secure="true" sslProtocol="TLS"
ciphers="TLS_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA"/>
需要注意的:
- protocol="org.apache.coyote.http11.Http11NioProtocol" tomcat 6默认的是http1.1,ci
- ciphers="TLS_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA" 解决Android6.0访问的问题
- keystorefile 配置自己本地的证书的位置,后边的密码要正确
- clientAuth 因为我们是单向认证此处为false
ok重启 服务器就可以测试了,测试本地服务器是否添加证书成功很简单,只要 浏览器访问 https:\\localhost:8088 看看有没有认证拦截皆可以了