背景
今天通過HttpClient請求一個外部接口時,出現
SSLHandshakeException
異常,通過查詢並解決了問題,現做記錄
- 以HTTP POST方式調用外部接口
public class HttpClientUtil {
public static JSONObject httpPost(String url, String strParam,String appid, String sign) throws Exception {
// 針對http
CloseableHttpClient httpClient = HttpClients.createDefault();
JSONObject jsonResult = null;
HttpPost httpPost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(10000).setConnectTimeout(10000).build();
httpPost.setConfig(requestConfig);
httpPost.addHeader("appid", appid);
httpPost.addHeader("sign", sign);
try {
if (null != strParam) {
StringEntity entity = new StringEntity(strParam,"utf-8");
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
}
CloseableHttpResponse result = httpClient.execute(httpPost);
if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String str = "";
try {
str = EntityUtils.toString(result.getEntity(), "utf-8");
jsonResult = JSONObject.parseObject(str);
} catch (Exception e) {
logger.error("post請求提交失敗:" + url, e);
}
}
} catch (IOException e) {
logger.error("post請求提交失敗:" + url, e);
} finally {
httpPost.releaseConnection();
}
return jsonResult;
}
}
-
以HTTPS POST方式調用外部接口
- 在使用HttpClient完成對HTTPS 接口請求之前,還存在一個
證書
問題,需要將被調接口的證書下載並安裝到本地 - 現已百度爲例:
- 在使用HttpClient完成對HTTPS 接口請求之前,還存在一個
-
選擇路徑並保存到本地
-
在確保正確安裝了JDK之後,後以管理員方式打開CMD,並執行
keytool -import -file D://****.cer -keystore "%JAVA_HOME%\jre\lib\security\cacerts" -alias server
# `D://****.cer`: 證書保存路徑
# `server`:別名
- 這裏還需要用到一個工具類
public class SSLClientCustom {
private static final String HTTP = "http";
private static final String HTTPS = "https";
private static SSLConnectionSocketFactory sslConnectionSocketFactory = null;
private static PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = null;
private static SSLContextBuilder sslContextBuilder = null;
{
try {
sslContextBuilder = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
});
sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE);
Registry<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory>create()
.register(HTTP, new PlainConnectionSocketFactory())
.register(HTTPS, sslConnectionSocketFactory)
.build();
poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(registryBuilder);
poolingHttpClientConnectionManager.setMaxTotal(200);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
public static CloseableHttpClient getHttpClinet() throws Exception {
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory)
.setConnectionManager(poolingHttpClientConnectionManager)
.setConnectionManagerShared(true)
.build();
return httpClient;
}
}
- 在創建httpClient時就需要發生變化
public class HttpClientUtil {
public static JSONObject httpPost(String url, String strParam,String appid, String sign) throws Exception {
// 針對https
CloseableHttpClient httpClient = SSLClientCustom.getHttpClinet();
JSONObject jsonResult = null;
HttpPost httpPost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(10000).setConnectTimeout(10000).build();
httpPost.setConfig(requestConfig);
httpPost.addHeader("appid", appid);
httpPost.addHeader("sign", sign);
try {
if (null != strParam) {
StringEntity entity = new StringEntity(strParam,"utf-8");
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
}
CloseableHttpResponse result = httpClient.execute(httpPost);
if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String str = "";
try {
str = EntityUtils.toString(result.getEntity(), "utf-8");
jsonResult = JSONObject.parseObject(str);
} catch (Exception e) {
logger.error("post請求提交失敗:" + url, e);
}
}
} catch (IOException e) {
logger.error("post請求提交失敗:" + url, e);
} finally {
httpPost.releaseConnection();
}
return jsonResult;
}
}
這樣就完成了使用HttpClient調用https接口的工作,若存在問題還望指正