之前,我讲了如何让tomcat支持https访问,当时浏览器通过https:localhost:8443即可访问tomcat。可是android此时如何访问已经搭建好的tomcat的https了?我在网上找了很多资料,发现还是有问题,后来自己改了一些,终于是做出来了。

1.搭建tomcat的https服务器。

这个,我之前的博客已经讲过,所有不在细讲了。


2.将搭建tomcat服务器时生成的server.cer证书放在android的assets目录下,应为客户端用https访问时需要检测服务器的证书是否符合要求。


3.编写一个类继承X509TrustManager,X509TrustManager是证书信任管理器类,我们可以自己实现该接口,让它信任我们指定的证书。

自己实现了信任管理器类,如何使用呢?类HttpsURLConnection似乎并没有提供方法设置信任管理器。其实,HttpsURLConnection通过SSLSocket来建立与HTTPS的安全连接,SSLSocket对象是由SSLSocketFactory生成的。HttpsURLConnection提供了方法setSSLSocketFactory(SSLSocketFactory)设置它使用的SSLSocketFactory对象。SSLSocketFactory通过SSLContext对象来获得,在初始化SSLContext对象时,可指定信任管理器对象。

public class TrustAllCertsManager implements X509TrustManager {    @Override    public void checkClientTrusted(X509Certificate[] chain, String authType)            throws CertificateException {        // Do nothing -> accept any certificates    }    @Override    public void checkServerTrusted(X509Certificate[] chain, String authType)            throws CertificateException {        // Do nothing -> accept any certificates    }    @Override    public X509Certificate[] getAcceptedIssuers() {        return new X509Certificate[0];    }}


4.编写一个类实现HostnameVerifier接口,此类是用于主机名验证的基接口。

在握手期间,如果 URL 的主机名和服务器的标识主机名不匹配,则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。

策略可以是基于证书的或依赖于其他验证方案。

当验证 URL 主机名使用的默认规则失败时使用这些回调。

public class VerifyEverythingHostnameVerifier implements HostnameVerifier {    @Override    public boolean verify(String hostname, SSLSession session) {        return true;    }}

此时,我设置对所有主机都可以访问。

5.实例化服务器的证书。

private TrustManager[] createTrustManager() {    BufferedInputStream cerInputStream = null;    try {        // 获取客户端存放的服务器公钥证书        cerInputStream = new BufferedInputStream(getAssets().open("server.cer"));        // 根据公钥证书生成Certificate对象        CertificateFactory cf = CertificateFactory.getInstance("X.509");        Certificate ca = cf.generateCertificate(cerInputStream);        Log.e("TAG", "ca=" + ((X509Certificate) ca).getSubjectDN());        // 生成包含当前CA证书的keystore        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());        keyStore.load(null, null);        keyStore.setCertificateEntry("ca", ca);        // 使用包含指定CA证书的keystore生成TrustManager[]数组        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);        tmf.init(keyStore);        return tmf.getTrustManagers();    } catch (CertificateException e) {        e.printStackTrace();    } catch (IOException e) {        e.printStackTrace();    } catch (KeyStoreException e) {        e.printStackTrace();    } catch (NoSuchAlgorithmException e) {        e.printStackTrace();    } finally {        if (cerInputStream != null) {            try {                cerInputStream.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    return null;}


上面的代码比较固定,其中server.cer是配置tomcat时的服务器证书。具体我也不是很清楚,可以去百度找一下。


6.具体实现https请求。

 private void httpsRequest(){        String name="健康科技";        String pass="123456";        TrustManager[] trustManager = createTrustManager();//        TrustManager[] trustManager = new TrustManager[]{new TrustAllCertsManager()};        SSLContext sslContext = null;        if (trustManager == null) {            Log.e("TAG", "tmf create failed!");            return;        }        try {            sslContext = SSLContext.getInstance("SSL");            sslContext.init(null, trustManager, new java.security.SecureRandom());        } catch (NoSuchAlgorithmException e) {            // do nothing        }catch (KeyManagementException e) {            // do nothing        }        HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());        HttpsURLConnection httpsURLConnection = null;        BufferedReader reader = null;        URL url = null;        try {            url = new URL("https://192.168.1.190:8443/MyWeb/HttpServlet");            httpsURLConnection = (HttpsURLConnection) url.openConnection();            httpsURLConnection.setHostnameVerifier(new VerifyEverythingHostnameVerifier());            httpsURLConnection.setConnectTimeout(5000);            httpsURLConnection.setDoInput(true);            httpsURLConnection.setUseCaches(false);            //将用户名和密码放入HashMap            Map<String,String> params=new HashMap<String,String>();            params.put("userName", name);            params.put("passWord", pass);            StringBuffer stringBuffer = new StringBuffer();        //存储封装好的请求体信息            try {                for(Map.Entry<String, String> entry : params.entrySet()) {                    stringBuffer.append(entry.getKey())                            .append("=")                            .append(URLEncoder.encode(entry.getValue(), "UTF-8"))                            .append("&");                }                stringBuffer.deleteCharAt(stringBuffer.length() - 1);    //删除最后的一个"&"            } catch (Exception e) {                e.printStackTrace();            }            byte[] data=stringBuffer.toString().getBytes();            httpsURLConnection.setRequestMethod("POST");   //设置请求为POST            httpsURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");            httpsURLConnection.setRequestProperty("Content-Length", String.valueOf(data.length));            httpsURLConnection.connect();            OutputStream outputStream = httpsURLConnection.getOutputStream();            outputStream.write(data);            reader = new BufferedReader(new InputStreamReader(httpsURLConnection.getInputStream()));            StringBuilder sBuilder = new StringBuilder();            String line;            while ((line = reader.readLine()) != null) {                sBuilder.append(line);            }            Log.e("TAG", "Wiki content=" + sBuilder.toString());            final String s=sBuilder.toString();            runOnUiThread(new Runnable() {                @Override                public void run() {                    mTextView.setText(s.toString());                }            });        } catch (MalformedURLException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }


到这来,客户端就可以做https请求了,不过服务器的tomcat需要自己写一个简单的HttpServlet,这个很简单,自己完全可以百度。


更多相关文章

  1. 万字长文带你了解最常用的开源 Squid 代理服务器
  2. Nginx系列教程(一)| 手把手教你在Linux环境下搭建Nginx服务
  3. Nginx系列教程(三)| 一文带你读懂Nginx的负载均衡
  4. Handler全面解析
  5. Android(安卓)MINA框架之实战总结(一) Mina连接,断开,重连
  6. android连接远程数据库教程1
  7. Android网络请求报错:java.net.SocketException: recvfrom failed
  8. Android如何打开/关闭系统解锁服务?—典型错误分析
  9. Android中的Handler用法

随机推荐

  1. 虚函数和纯虚函数的区别是什么?
  2. c语言的输入输出语句有哪些?
  3. windows.h有哪些函数
  4. c语言中字符常量是什么?
  5. C语言中的指针有什么作用
  6. c语言程序中的基本功能模块为什么?
  7. C语言的三种基本程序结构是什么
  8. c语言源文件经过编译后生成文件的后缀是
  9. c语言是一种什么的程序设计语言?
  10. c语言指针用法有哪些