java大部分人都能掌握,但是如果是层级较深的知识可能大部分人都蒙了,就以继承这一面向对象的知识,能做到灵活运用的就为数不多。前几天做微信定制开发的时候就遇到了比较棘手的问题如:https请求不知道如何正确使用、java对象转成xml字符串等。这次借着放假给不会的童鞋脑补一下。
一 什么是HTTPS
百科是这样介绍的:
HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。 它是一个URI scheme(抽象标识符体系),句法类同http:体系。用于安全的HTTP数据传输。https:URL表明它使用了HTTP,但HTTPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。这个系统的最初研发由网景公司(Netscape)进行,并内置于其浏览器Netscape Navigator中,提供了身份验证与加密通讯方法。现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面。
我的口头理解是:https是一种安全性较高的Http通道,需要使用SSL进行加密,主要用于安全性很高的领域如金融、在线支付等方面
二 什么是SSL
SSL(Secure Sockets Layer 安全套接层)协议,及其继任者TLS(Transport Layer Security传输层安全)协议,是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密,用于保障网络数据传输安全,利用数据加密技术,确保数据在网络传输过程中不会被截取及窃听。SSL协议已成为全球化标准,所有主要的浏览器和WEB服务器程序都支持SSL协议,可通过安装SSL证书激活SSL协议。SSL 证书就是遵守 SSL协议的服务器数字证书,由受信任的证书颁发机构(CA机构),验证服务器身份后颁发,部署在服务器上,具有网站身份验证和加密传输双重功能。
三 java如何使用HTTPS请求
从上面的描述我们可以知道https比较核心的内容是证书,但是重点在于怎么弄个证书出来,这个全凭经验吧,不是每个java程序员都能想到,下面是对X50接口的说明
javax.net.ssl.X509TrustManager
Instance of this interface manage which X509 certificates may be used to authenticate the remote side of a secure socket. Decisions may be based on trusted certificate authorities, certificate revocation lists, online status checking or other means.
从上面可以看出X50就是对SSL的一种实现,只要写一个Java类让它实现该接口就实现的证书管理器的功能,如下所示:
package com.debug.weixin.util;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
/**
* 证书信任管理器(用于https请求)
* @date 2013-08-08
*/
public class MyX509TrustManager implements X509TrustManager{
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
考虑到证书颁发机构的权威性,该类的实现方法不加任何内容,即信任所有机构颁发的证书。
下面来个实际的例子,假如需要通过发起GET请求来获取接口返回数据,但是该接口是HTTPS这种类型。一起看下代码吧:
public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
httpUrlConn.setSSLSocketFactory(ssf);
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
// 设置请求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod)) {
httpUrlConn.connect();
}
// 当有数据需要提交时
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 将返回的输入流转换成字符串
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 释放资源
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
ce.printStackTrace();
// log.error("Weixin server connection timed out.");
} catch (Exception e) {
//log.error("https request error:{}", e);
e.printStackTrace();
}
return jsonObject;
}