使用url API访问HTTPS协议的url,跟访问普通url一样,url api封装了底层复杂的ssl协议,暴露给上层应用的时候,使用方式跟普通的http请求无异了。需要做的是将服务端证书导入到本地可信任密钥库中。
代码:
System.setProperty("javax.net.ssl.trustStore","E:\\home\\ca\\server.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "qwe123");
URL url = new URL("https://localhost");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(6 * 60 * 1000);
conn.setReadTimeout(10 * 60 * 1000);
InputStream is = conn.getInputStream();
Reader reader = new InputStreamReader(conn.getInputStream(), "UTF-8");
BufferedReader br = new BufferedReader(reader);
String line = null;
do {
line = br.readLine();
System.out.println(line);
} while (line != null);
注意:
System.setProperty("javax.net.ssl.trustStore","E:\\home\\ca\\server.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "qwe123");
设置系统参数可省略,前提是需要把服务器证书导入到$JAVA_HOME/jre/lib/security/cacerts文件中
另 自签名的证书可能会存在证书hostname校验失败的情况:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching localhost found
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1611)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
这就需要设置connection的 HostnameVerifier
class MyHostnameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
return true;//不校验 全返回true
}
}
在连接前设置
((HttpsURLConnection) conn).setHostnameVerifier(new MyHostnameVerifier());