Java-HTTPClient實現HTTPS請求

目前只實現了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

https://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientCustomSSL.java

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章