我正在尝试调用HTTPS Web服务,这是我使用的代码,此功能部署在带有OS amazon linux的AWS实例上
public static <T> T postSecureJsonRequest(String url, Object request, Type responseType) throws Exception {
BufferedReader br;
HttpsURLConnection con = null;
try {
URL obj = new URL(null, url, new sun.net.www.protocol.https.Handler());
con = (HttpsURLConnection) obj.openConnection();
con.setReadTimeout(IntegrationConfiguration.getConnectionTimeOut());
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
if (request.getClass().equals(String.class)) {
wr.writeBytes(request + "");
} else {
wr.writeBytes(gson.toJson(request));
}
wr.flush();
wr.close();
if (con.getResponseCode() != 200) {
throw new Exception(IntegrationConstants.TECHNICAL_ERROR + " "
+ ("failed : HTTP error code : " + con.getResponseCode() + " from the main server : " + url));
}
br = new BufferedReader(new InputStreamReader((con.getInputStream())));
String inputLine;
StringBuffer outputResponse = new StringBuffer();
while ((inputLine = br.readLine()) != null) {
outputResponse.append(inputLine);
}
return (T) gson.fromJson(outputResponse.toString(), responseType);
} catch (Exception e) {
throw e;
} finally {
if (con != null) {
con.disconnect();
}
}
}
问题是函数总是抛出Exception
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1989)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1096)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1342)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1369)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1353)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1157)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:259)
at com.wsg.bit.casino.integration.util.IntegrationUtility.postSecureJsonRequest(IntegrationUtility.java:524)
我在这里缺少什么?
编辑:我从服务器获得了这些信息
* TCP_NODELAY set
* Connected to api..... (1xx.2xx.1xx.1xx) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* ALPN, server accepted to use http/1.1
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate:
* subject: CN=api.....
* start date: Apr 27 09:29:11 2018 GMT
* expire date: Jul 26 09:29:11 2018 GMT
* common name: api.server1.ih.testenv.io
* issuer: CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US
> GET / HTTP/1.1
> Host: api.server1.ih.testenv.io
> User-Agent: curl/7.53.1
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Server: nginx/1.10.3 (Ubuntu)
< Date: Thu, 03 May 2018 08:43:05 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 39
< Connection: keep-alive
< cache-control: max-age=0, private, must-revalidate
< x-request-id: 2klhbq0t5ahtlndlmc0003k2
修改:当我从其他HTTPS
客户端拨打REST
服务时,postman
就可以了。
答案 0 :(得分:1)
您需要在java密钥库中导入证书链。如果它们是私有证书,您可以向Web服务所有者索取证书。 如果它们是公共证书,您可以在任何标准浏览器中打开Web服务链接并下载证书链。
请参阅以下链接以进行导入:
How do I find out what keystore my JVM is using?
How to import a .cer certificate into a java keystore?
您还可以创建自定义密钥库并在其中导入证书,并在代码中对其进行配置。
如果您遇到此问题,则可能会遇到hostverification异常。要解决这个问题,您可以插入以下代码。
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new javax.net.ssl.HostnameVerifier() {
public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
return hostname.equals("www.domainname.com");
}
});