使用java原生方法,HttpURLConnection请求https
开放一个https接口,返回字符串https test! (服务器证书是用keytool自己生成的)
浏览器可正常调用
使用原生的HttpURLConnection方法调用自己的https接口报错
分析:https请求的时候会验证证书,所以会有此异常
有2种方法解决:
1.信任所有证书
在http请求前加入以下代码,调用该方法可跳过所有证书的验证
请求成功
2.手动导入证书
首先解决这个异常No subject alternative names present
方法1,重写主机名验证:
URL为IP时,默认是通不过验证的,需要自己定义HostName的验证方法:在调用http请求之前,加如下代码就可以解决了
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName + " vs. "
+ session.getPeerHost());
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hv);
HostnameVerifier 接口是用于主机名验证,准确说是验证服务器ca证书中的host是否和请求地址host一致,其实目的是加强一层安全防护,防止恶意程序利用中间人攻击,这里直接返回true,强制验证通过。
方法2,使用域名访问:
另一种方法,不用ip地址去访问,改用域名去访问,
修改hosts文件,仍然行不通,后发现ca证书中的CN值与域名不匹配便会出现此问题
于是在本地修改hosts文件,添加一行127.0.0.1 xu,将域名设为与CN值一致,此异常解决。
之后出现以下报错
解决这个异常unable to find valid certification path to requested target
此异常是找不到安全证书,需要导入安全证书
导入安全证书有2种方式
1.使用代码生成安全证书文件jssecacerts
通过java代码,下载证书
放在项目根目录下,在调用http请求前设置安全证书System.setProperty(“javax.net.ssl.trustStore”, “jssecacerts”);
System.setProperty(“javax.net.ssl.trustStorePassword”, “changeit”);
成功运行
也可以将安全证书文件直接放在jdk\jre\lib\security
请求成功
2.导入cer证书文件
从浏览器下载cer证书,使用keytool将证书导入密钥库
keytool -import -trustcacerts -alias 别名 -keystore %JAVA_HOME%\jre\lib\security\cacerts -file .cer证书路径 -storepass changeit
请求成功