jadyer[java]
package com.jadyer.util;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
/**
* @see =====================================================================================================
* @see 在開發HTTPS應用時,時常會遇到兩種情況
* @see 1、要麼測試服務器沒有有效的SSL證書,客戶端連接時就會拋異常
* @see javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
* @see 2、要麼測試服務器有SSL證書,但可能由於各種不知名的原因,它還是會拋一個堆爛碼七糟的異常
* @see =====================================================================================================
* @see 由於我們這裡使用的是HttpComponents-Client-4.1.2創建的連接,所以,我們就要告訴它使用一個不同的TrustManager
* @see TrustManager是一個用於檢查給定的證書是否有效的類
* @see SSL使用的模式是X.509....對於該模式,Java有一個特定的TrustManager,稱為X509TrustManager
* @see 所以我們自己創建一個X509TrustManager實例
* @see 而在X509TrustManager實例中,若證書無效,那麼TrustManager在它的checkXXX()方法中將拋出CertificateException
* @see 既然我們要接受所有的證書,那麼X509TrustManager裡面的方法體中不拋出異常就行了
* @see 然後創建一個SSLContext並使用X509TrustManager實例來初始化之
* @see 接著通過SSLContext創建SSLSocketFactory,最後將SSLSocketFactory注冊給HttpClient就可以了
* @see =====================================================================================================
* @create Jul 30, 2012 1:11:52 PM
* @author 玄玉(http://blog.csdn/net/jadyer)
*/
public class HttpClientUtil {
public static void main(String[] args)throws Exception{
Map<String, String> params = new HashMap<String, String>();
params.put("TransName", "IQSR");
params.put("Plain", "transId=IQSR~|~originalorderId=2012~|~originalTransAmt= ~|~merURL= ");
params.put("Signature", "9b759887e6ca9d4c24509d22ee4d22494d0dd2dfbdbeaab3545c1acee62eec7");
sendSSLPostRequest("https://www.cebbank.com/per/QueryMerchantEpay.do", params);
}
/**
* 向HTTPS地址發送POST請求
* @param reqURL 請求地址
* @param params 請求參數
* @return 響應內容
*/
@SuppressWarnings("finally")
public static String sendSSLPostRequest(String reqURL, Map<String, String> params){
long responseLength = 0; //響應長度
String responseContent = null; //響應內容
HttpClient httpClient = new DefaultHttpClient(); //創建默認的httpClient實例
X509TrustManager xtm = new X509TrustManager(){ //創建TrustManager
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public X509Certificate[] getAcceptedIssuers() { return null; }
};
try {
//TLS1.0與SSL3.0基本上沒有太大的差別,可粗略理解為TLS是SSL的繼承者,但它們使用的是相同的SSLContext
SSLContext ctx = SSLContext.getInstance("TLS");
//使用TrustManager來初始化該上下文,TrustManager只是被SSL的Socket所使用
ctx.init(null, new TrustManager[]{xtm}, null);
//創建SSLSocketFactory
SSLSocketFactory socketFactory = new SSLSocketFactory(ctx);
//通過SchemeRegistry將SSLSocketFactory注冊到我們的HttpClient上
httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory));
HttpPost httpPost = new HttpPost(reqURL); //創建HttpPost
List<NameValuePair> formParams = new ArrayList<NameValuePair>(); //構建POST請求的表單參數
for(Map.Entry<String,String> entry : params.entrySet()){
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
HttpResponse response = httpClient.execute(httpPost); //執行POST請求
HttpEntity entity = response.getEntity(); //獲取響應實體
if (null != entity) {
responseLength = entity.getContentLength();
responseContent = EntityUtils.toString(entity, "UTF-8");
EntityUtils.consume(entity); //Consume response content
}
System.out.println("請求地址: " + httpPost.getURI());
System.out.println("響應狀態: " + response.getStatusLine());
System.out.println("響應長度: " + responseLength);
System.out.println("響應內容: " + responseContent);
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
httpClient.getConnectionManager().shutdown(); //關閉連接,釋放資源
return responseContent;
}
}
}