開發 HTTPS 應用時常遇兩類問題:
SSLPeerUnverifiedException解決核心:自定義 TrustManager 接受所有證書。
public class HttpClientUtil {
public static void main(String[] args) throws Exception {
Map<String, String> params = new HashMap<>();
params.put("TransName", "IQSR");
params.put("Plain", "transId=IQSR~|~originalOrderId=2012...");
params.put("Signature", "9b759887e6ca9d4c24509d22ee4d2249...");
sendSSLPostRequest("https://www.cebbank.com/per/QueryMerchantEpay.do", params);
}
@SuppressWarnings("finally")
public static String sendSSLPostRequest(String reqURL, Map<String, String> params) {
long responseLength = 0;
String responseContent = null;
HttpClient httpClient = new DefaultHttpClient();
// 1. 創建信任所有證書的 TrustManager
X509TrustManager xtm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
public X509Certificate[] getAcceptedIssuers() { return null; }
};
try {
// 2. 初始化 SSLContext
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[]{xtm}, null);
// 3. 創建 SSLSocketFactory 並註冊
SSLSocketFactory socketFactory = new SSLSocketFactory(ctx);
httpClient.getConnectionManager().getSchemeRegistry()
.register(new Scheme("https", 443, socketFactory));
// 4. 構建 POST 請求
HttpPost httpPost = new HttpPost(reqURL);
List<NameValuePair> formParams = new ArrayList<>();
for (Map.Entry<String, String> entry : params.entrySet()) {
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
// 5. 執行請求並處理響應
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
if (entity != null) {
responseLength = entity.getContentLength();
responseContent = EntityUtils.toString(entity, "UTF-8");
EntityUtils.consume(entity);
}
System.out.println("請求地址: " + httpPost.getURI());
System.out.println("響應狀態: " + response.getStatusLine());
System.out.println("響應長度: " + responseLength);
System.out.println("響應內容: " + responseContent);
} catch (Exception e) {
e.printStackTrace();
} finally {
httpClient.getConnectionManager().shutdown(); // 釋放資源
return responseContent;
}
}
}
| 組件 | 作用 |
|---|---|
| X509TrustManager | 證書驗證管理器,重寫三個方法為空實現「信任所有」 |
| SSLContext | SSL 上下文環境,用 TrustManager 初始化 |
| SSLSocketFactory | SSL 套接字工廠,基於 SSLContext 創建 |
| SchemeRegistry | 將自定義工廠註冊到「https」協議(端口 443) |
⚠️ 僅限測試環境使用! 生產環境必須驗證服務器證書,防止中間人攻擊。正確做法是將服務器 CA 證書導入客戶端信任庫,或使用有效的商業證書。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>