Java HTTPComponents SOAP请求,SSLHandshake异常(PKIX路径生成失败)
我正在尝试使用HTTPComponents向特定的Web服务发送自定义SOAP消息。我们使用证书进行通信,webservice端点使用证书进行https加密 通过自定义Java操作,我试图发送SOAP消息,但在执行httppost时抛出错误:Java HTTPComponents SOAP请求,SSLHandshake异常(PKIX路径生成失败),java,web-services,ssl,soap,Java,Web Services,Ssl,Soap,我正在尝试使用HTTPComponents向特定的Web服务发送自定义SOAP消息。我们使用证书进行通信,webservice端点使用证书进行https加密 通过自定义Java操作,我试图发送SOAP消息,但在执行httppost时抛出错误: Executing request POST https://webserviceurl/endpoint HTTP/1.1 Exception While Connecting sun.security.validator.ValidatorExcept
Executing request POST https://webserviceurl/endpoint HTTP/1.1
Exception While Connecting sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
我对这个问题做了一些研究,显然Java需要证书,该证书用于其cacerts中的webservice URL。使用名为InstallCert的Java工具,我试图将证书添加到cacerts,但仍然出现此错误
PS:我还尝试使用keytool将证书添加到cacerts,但也没有成功
那么为什么连接会失败呢。我需要将端点证书添加到cacerts文件中是否正确?关于如何解决此问题/如何成功地将证书添加到受信任证书,您有何想法
下面是我的完整java代码,用于执行请求:
// Trust own CA and all self-signed certs
SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(new File("C:/ourcert.p12"), "MyPass".toCharArray(),
new TrustSelfSignedStrategy())
.build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[] { "TLSv1" },
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
Byte[] result = null;
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
int timeoutConnection = 15000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 35000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
byte[] result1 = null;
HttpPost httppost = new HttpPost(webserviceUrl);
httppost.setHeader("soapaction", "aanleveren");
httppost.setHeader("Content-Type", "text/xml; charset=utf-8");
System.out.println("Executing request " + httppost.getRequestLine());
try {
HttpEntity entity = new StringEntity(soapBericht,HTTP.UTF_8);
httppost.setEntity(entity);
HttpResponse response = httpclient.execute(httppost);// calling server
HttpEntity r_entity = response.getEntity(); //get response
if (r_entity != null) {
result1 = new byte[(int) r_entity.getContentLength()];
if (r_entity.isStreaming()) {
DataInputStream is = new DataInputStream(
r_entity.getContent());
is.readFully(result1);
}
}
EntityUtils.consume(entity);
} catch (Exception E) {
Core.getLogger("SBR").log(LogLevel.WARNING,"ERROR " + E.getMessage() + E.getStackTrace());
System.out.println("Exception While Connecting " +E.getMessage());
E.printStackTrace();
}
httpclient.close(); //shut down the connection
与其将其添加到系统根证书,不如尝试将其添加到您的应用程序信任中
keytool -import -alias <ALIAS_NAME> -keystore <your_app_trust>.jks -trustcacerts -file <CERTIFICATE_TO_ADD.der> -v
keytool-import-alias-keystore.jks-trustcacerts-file-v
我也遇到了同样的问题,它解决了我的问题。这是使用自签名证书时非常常见的情况。。 试试这个:
SSLContext sslContext = null;
try
{
sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy() {
@Override
public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException
{
return true;
}
}).build();
}
catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e)
{
//Show some Msg
}
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultHeaders(headers)
.setSSLContext(sslContext)
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();