目前只實現了https的GET請求,後續還會繼續更新
一、GET請求
public static void submitGet() {
try {
//顯示https握手過程,方便調試
// System.setProperty("javax.net.debug", "all");
//調試雙向認證使用,暫不使用
SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(new File("D:\\Java\\jdkSE-8u201\\bin\\steven.keystore"), "123456".toCharArray(),
new TrustSelfSignedStrategy())
.build();
// 證書全部信任 不做身份鑑定
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] ax509certificate,
String s) throws CertificateException {
// TODO Auto-generated method stub
return true;
}
});
//使用谷歌瀏覽器查看網頁使用的是哪一個SSL協議,SSLv2Hello需要刪掉,不然會報握手失敗,具體原因還不知道
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(), new String[] {
"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2" }, null,
NoopHostnameVerifier.INSTANCE);
Registry<ConnectionSocketFactory> registry = RegistryBuilder
.<ConnectionSocketFactory> create()
.register("http", new PlainConnectionSocketFactory())
.register("https", sslsf).build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(200);// max connection
CloseableHttpClient client = HttpClients.custom()
.setSSLSocketFactory(sslsf).setConnectionManager(cm)
.setConnectionManagerShared(true).build();
//開始設置請求相關信息
HttpGet httpGet = new HttpGet("https://192.168.1.245/test/pages/login.jsp");
CloseableHttpResponse response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
if(entity != null) {
System.out.println("長度:" + entity.getContentLength());
System.out.println("內容:" + EntityUtils.toString(entity, "gbk"));
}
response.close();
client.close();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
相關擴展
錯誤1:javax.net.ssl.SSLException: Received fatal alert: protocol_version
可以在代碼中添加:System.setProperty("javax.net.debug", "all");打印握手過程,幫助分析
查看客戶端網頁使用的哪個ssl,我用的谷歌看的
錯誤2:java.net.ConnectException: Connection refused: connect
服務器沒有啓動
錯誤3:.javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed
服務端證書不可信
錯誤4:java.net.SocketException: Software caused connection abort: recv failed
服務端是雙向認證,客戶端發送的是單向認證,沒有將客戶端證書一起發送
錯誤5:org.apache.commons.httpclient.NoHttpResponseException
一般是服務端防火牆攔截,也有可能是負載過重
錯誤6:javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
這是由於服務端配置的是SSL雙向認證,而客戶端發送數據是按照服務器是單向認證時發送的,即沒有將客戶端證書信息一起發送給服務端。服務端驗證客戶端證書時,發現客戶端沒有證書,然後就斷開了握手連接。
參考資料:
https://blog.csdn.net/coqcnbkggnscf062/article/details/79812102