2018/11/8 對接aep扣費接口,接口是用https協議
坑1:
httpclient忽略https證書
//錯誤代碼
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] arg0,
String arg1) throws CertificateException {
// TODO Auto-generated method stub
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext, new String[] { "TLSv1" }, null,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Registry<ConnectionSocketFactory> registry = RegistryBuilder
.<ConnectionSocketFactory> create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", sslsf).build();
HttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(
registry);
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(clientConnectionManager).build();
//正確代碼
SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(
X509Certificate[] x509Certificates, String s)
throws CertificateException {
return true;
}
}).build();
String sslProConfig = "";// AepConfig.getSslProtocol();
if (StringUtils.isEmpty(sslProConfig)) {
sslProConfig = "SSLv2Hello,SSLv3,TLSv1,TLSv1.2";
}
// 獲取到協議列表數組
String[] sslProCfgArr = sslProConfig.split(",");
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext, sslProCfgArr, null, NoopHostnameVerifier.INSTANCE);// NoopHostnameVerifier.INSTANCE就是不用校驗服務端證書
Registry<ConnectionSocketFactory> registry = RegistryBuilder
.<ConnectionSocketFactory> create()
.register("http", new PlainConnectionSocketFactory())
.register("https", sslsf).build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(
registry);
// 最大連接
int maxConn = 20;// AepConfig.getMaxThreadsThreshold();
cm.setMaxTotal(maxConn);
// 每個路由的最大連接
cm.setDefaultMaxPerRoute(maxConn);
// 響應超時時間
int timeout = 50000;// AepConfig.getAepInvokeTimeout() *
// AepTool.MILLS_SECOND;
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setSocketTimeout(timeout).setConnectTimeout(timeout)
.setConnectionRequestTimeout(timeout)
.setStaleConnectionCheckEnabled(true).build();
HttpHost proxy = new HttpHost("127.0.0.1",8888);
CloseableHttpClient httpClient = HttpClients.custom()
.setProxy(proxy)
.setConnectionManager(cm)
.setDefaultRequestConfig(defaultRequestConfig)
.setSSLSocketFactory(sslsf).build();
區別:協議支持不一樣
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext, new String[] { "TLSv1" }, null,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
String sslProConfig = "SSLv2Hello,SSLv3,TLSv1,TLSv1.2";
String[] sslProCfgArr = sslProConfig.split(",");
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext, sslProCfgArr, null, NoopHostnameVerifier.INSTANCE);// NoopHostnameVerifier.INSTANCE就是不用校驗服務端證書
坑2:ssl解決後返回500狀態碼
發送的包體不一樣,不是一般的key-value的post包,而是json的body包,因爲服務器設置了header不合格或者body不合格就直接拋500狀態碼。
坑3:
Fiddler 抓包不能抓https的header信息
由於坑2和坑3共同的原因,一直在找header的問題,結果換了多少種方法都不行,後來發了一個http的包,結果就有header的信息了。最終才定位到時body的不合法。後面的就跟服務器通訊起來了,異常也會有提示了
坑4:
時間格式化時候需要與UTC時區來格式化
感謝 https://blog.csdn.net/u012528092/article/details/79080650 ,他的示例代碼然我看到了fiddler的header信息,從而判斷了https不會有header信息的