1.使用HttpClient4.3 调用https出现如下错误:


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


当使用网上其他的方式的时候,出现错误:javax.net.ssl.SSLException: hostname in certificate didn't match: <openapi.ysepay.com> != <default.ssl.cdn.jiasule.com>

原因:这是SSL证书请求问题。

2.原来的代码:


1     /**
2 * 拼接请求参数,发起请求
3 * @param request
4 * @param sParaTemp
5 * @param strMethod
6 * @param strButtonName
7 * @return
8 */
9 public static String sendRequest(String mch_id,HttpServletRequest request, Map<String, String> paraTemp) {
10 String result = null;// 返回的结果
11 CloseableHttpResponse response = null;
12 CloseableHttpClient client = null;
13
14 HttpPost httpPost = new HttpPost(SwiftpassConfig.yinsheng_YSEPAY_GATEWAY_URL); //创建HttpPost对象
15 // 存参列表
16 List <NameValuePair> params = new ArrayList<NameValuePair>();
17 // 参数不为空
18 if(!paraTemp.isEmpty()) {
19 // 遍历map,保存到List中
20 for (Map.Entry<String, String> entry : paraTemp.entrySet()) {
21 params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
22 }
23 try {
24 httpPost.setEntity(new UrlEncodedFormEntity(params ,HTTP.UTF_8));
25 // 创建 CloseableHttpClient 对象
26 client = HttpClients.createDefault();
27 response = client.execute(httpPost);
28 if(response.getStatusLine().getStatusCode() == 200) {
29 HttpEntity httpEntity = response.getEntity();
30 //取出应答字符串
31 result = EntityUtils.toString(httpEntity);
32 }
33 } catch (Exception e) {
34 e.printStackTrace();
35 result = e.getMessage().toString();
36 }
37 }
38 return result;
39 }


使用上诉代码调用https接口,出现上述的错误。

3.修改之后的代码:


/**
* buildSSLCloseableHttpClient:(设置允许所有主机名称都可以,忽略主机名称验证)
* @author xbq
* @return
* @throws Exception
*/
private static CloseableHttpClient buildSSLCloseableHttpClient() throws Exception {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
// 信任所有
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
// ALLOW_ALL_HOSTNAME_VERIFIER:这个主机名验证器基本上是关闭主机名验证的,实现的是一个空操作,并且不会抛出javax.net.ssl.SSLException异常。
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1" }, null,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
}

/**
* 拼接请求参数,发起请求
* @param request
* @param sParaTemp
* @param strMethod
* @param strButtonName
* @return
*/
public static String sendRequest(String mch_id,HttpServletRequest request, Map<String, String> paraTemp) {
String result = null;// 返回的结果
CloseableHttpResponse response = null;
CloseableHttpClient client = null;

HttpPost httpPost = new HttpPost(SwiftpassConfig.yinsheng_YSEPAY_GATEWAY_URL); //创建HttpPost对象
// 存参列表
List <NameValuePair> params = new ArrayList<NameValuePair>();
// 参数不为空
if(!paraTemp.isEmpty()) {
// 遍历map,保存到List中
for (Map.Entry<String, String> entry : paraTemp.entrySet()) {
params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
try {
httpPost.setEntity(new UrlEncodedFormEntity(params ,HTTP.UTF_8));
// 调用方法,创建 CloseableHttpClient 对象
client = buildSSLCloseableHttpClient();
response = client.execute(httpPost);
if(response.getStatusLine().getStatusCode() == 200) {
HttpEntity httpEntity = response.getEntity();
//取出应答字符串
result = EntityUtils.toString(httpEntity);
}
} catch (Exception e) {
e.printStackTrace();
result = e.getMessage().toString();
}
}
return result;
}