java网络学习之 HttpsURLConnection 源码解析
HttpsURLConnection 请求示例:
import javax.net.ssl.*;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class HttpsUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(HttpsUtil.class);
private static String charset = "utf-8";
private static class TrustAnyTrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
}
private static class TrustAnyHostnameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
/**
* post方式请求服务器(https协议)
*
* @param url
* 请求地址
* @param content
* 参数
* 编码
* @return
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
* @throws IOException
*/
public static String post(String url, String content, Map<String,String> headers, int connTimeOut, int soTimeOut ) {
SSLContext sc =null; //构造一个sslcontext上下文,这个上下文里记录了会信任哪些服务器的证书以及自己上传的证书
try{
sc=SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },
new java.security.SecureRandom());
}catch (Exception e){
LOGGER.error("getSSLContextError: ", e);
return URLConnUtil.EXCEPTION_MAP.get("GET_SSL_EXCEPTION");
}
URL console =null;
try{
console=new URL(url);
}catch (Exception e){
LOGGER.error("urlException: ", e);
return URLConnUtil.EXCEPTION_MAP.get("URI_SYNTAX_EXCEPTION");
}
HttpsURLConnection conn =null;
try{
conn=(HttpsURLConnection) console.openConnection();
}catch (Exception e){
LOGGER.error("IO_EXCEPTION: ", e);
return URLConnUtil.EXCEPTION_MAP.get("IO_EXCEPTION");
}
//conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
if(headers!=null){
Iterator<String> keys= headers.keySet().iterator();
while(keys.hasNext()){
String key=keys.next();
conn.setRequestProperty(key,headers.get(key));
}
}
conn.setSSLSocketFactory(sc.getSocketFactory()); //把初始化的上下文作为https 连接的一个属性设置进去
conn.setHostnameVerifier(new TrustAnyHostnameVerifier()); // 设置连接是否校验 hostname
conn.setDoOutput(true);
conn.setConnectTimeout(connTimeOut);
conn.setReadTimeout(soTimeOut);
try{
conn.connect();
}catch (Exception e){
LOGGER.error("IO_EXCEPTION: ", e);
return URLConnUtil.EXCEPTION_MAP.get("IO_EXCEPTION");
}
try {
DataOutputStream out=new DataOutputStream(conn.getOutputStream());
out.write(content.getBytes(charset));
// 刷新、关闭
out.flush();
out.close();
InputStream is = conn.getInputStream();
if (is != null) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
is.close();
return new String(outStream.toByteArray());
}
return null;
}catch (ConnectTimeoutException e) {
LOGGER.error("IO_EXCEPTION: ", e);
return URLConnUtil.EXCEPTION_MAP.get("ConnectTimeoutException");
} catch (UnsupportedEncodingException e) {
LOGGER.error("UnsupportedEncodingException: ", e);
return URLConnUtil.EXCEPTION_MAP.get("UnsupportedEncodingException");
} catch (ClientProtocolException e) {
LOGGER.error("ClientProtocolException: ", e);
return URLConnUtil.EXCEPTION_MAP.get("ClientProtocolException");
} catch (ParseException e) {
LOGGER.error("ParseException: ", e);
return URLConnUtil.EXCEPTION_MAP.get("ParseException");
} catch (IOException e) {
LOGGER.error("IO_EXCEPTION: ", e);
return URLConnUtil.EXCEPTION_MAP.get("IOException");
} catch (Exception e) {
LOGGER.error("EXCEPTION: ", e);
return URLConnUtil.EXCEPTION_MAP.get("EXCEPTION");
}
}
}
从以上代码看你来,httpsUrlConnection 和httpUrlConnection 的区别就是 在连接上多做了一些ssl 属性相关的设置,其他没有区别。
httpsUrlConnection的其他特殊方法:
string getciphersuite()返回所有连接所使用的 ssl 密码套件的名称。