apache httpclient-4.5 https通訊 雙向認證

  1. maven dependence

		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5.2</version>
		</dependency>

2. 測試類

package com.iraid.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;

import javax.net.ssl.SSLContext;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

/**
 * 使用 httpclient4.5 進行 https 通訊,
 * 採用雙向認證, 連接池管理connection
 * 
 * @author wangfeihu
 *
 */
public class HttpClientforSSL {

	public static HttpClientConnectionManager CONNECTION_MANAGER = null;

	/**
	 * 初始化 connection manager.
	 * @param keyStoreFile
	 * @param keyStorePass
	 * @param trustStoreFile
	 * @param trustStorePass
	 * @throws Exception
	 */
	public void init(String keyStoreFile, String keyStorePass,
			String trustStoreFile, String trustStorePass) throws Exception {
		System.out.println("init conection pool...");

		InputStream ksis = new FileInputStream(new File(keyStoreFile));
		InputStream tsis = new FileInputStream(new File(trustStoreFile));

		KeyStore ks = KeyStore.getInstance("PKCS12");
		ks.load(ksis, keyStorePass.toCharArray());

		KeyStore ts = KeyStore.getInstance("JKS");
		ts.load(tsis, trustStorePass.toCharArray());

		SSLContext sslContext = SSLContexts.custom()
				.loadKeyMaterial(ks, keyStorePass.toCharArray())
				// 如果有 服務器證書
				.loadTrustMaterial(ts, new TrustSelfSignedStrategy())
				// 如果沒有服務器證書,可以採用自定義 信任機制
				// .loadTrustMaterial(null, new TrustStrategy() {
				//
				// // 信任所有
				// public boolean isTrusted(X509Certificate[] arg0,
				// String arg1) throws CertificateException {
				// 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();
		ksis.close();
		tsis.close();
		CONNECTION_MANAGER = new PoolingHttpClientConnectionManager(registry);

	}

	/**
	 * do post
	 * @param url
	 * @param params
	 * @throws Exception
	 */
	public void post(String url, String params) throws Exception {
		if (CONNECTION_MANAGER == null) {
			return;
		}
		CloseableHttpClient httpClient = HttpClients.custom()
				.setConnectionManager(CONNECTION_MANAGER).build();
		HttpPost httpPost = new HttpPost(url);

		httpPost.setEntity(new StringEntity(params,
				ContentType.APPLICATION_JSON));

		CloseableHttpResponse resp = httpClient.execute(httpPost);
		System.out.println(resp.getStatusLine());
		InputStream respIs = resp.getEntity().getContent();
		String content = convertStreamToString(respIs);
		System.out.println(content);
		EntityUtils.consume(resp.getEntity());
	}

	
	public static String convertStreamToString(InputStream is) {
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		StringBuilder sb = new StringBuilder();

		String line = null;
		try {
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return sb.toString();
	}

	public static void main(String[] args) {
		// 服務地址
		String url = "https://www.demo.com/api/rest/UidApiService/authCardWithoutOTP";
		// 服務參數,這裏接口的參數採用 json 格式傳遞
		String params = "{\"merchantCode\": \"www.demo.com\","
				+ "\"sessionId\": \"10000011\"," + "\"userName\": \"jack\","
				+ "\"idNumber\": \"432652515\"," + "\"cardNo\": \"561231321\","
				+ "\"phoneNo\": \"\"}";
		// 私鑰證書
		String keyStoreFile = "D:\\workspaces\\test\\httpclient\\src\\main\\resources\\www.demo.com.p12";
		String keyStorePass = "052537159932766";

		// 配置信任證書庫及密碼
		String trustStoreFile = "D:\\workspaces\\test\\httpclient\\src\\main\\resources\\cacerts.jks";
		String trustStorePass = "changeit";

		HttpClientforSSL obj = new HttpClientforSSL();
		try {
			obj.init(keyStoreFile, keyStorePass, trustStoreFile, trustStorePass);
			for (int i = 0; i < 10; i++) {
				obj.post(url, params);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


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