HttpClient進行POST請求(HTTPS方式)
原文:http://blog.csdn.net/rongyongfeikai2/article/details/41659353
http://blog.csdn.net/lanshengsheng2012/article/details/41483929
異常資訊如下:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
原因:伺服器的證書不被信任。一般是這樣造成的。
使用KEYTOOL工具建立證書,然後用TOMCAT啟動後,在瀏覽器開啟網站時,會出現證書不被信任的提示。當然,利用HTTPCLIENT向服務端HTTPS傳送資料時,HTTPCLIENT也會檢測服務端的證書是否被信任,不被信任就丟擲上面的異常。
解決辦法有兩種,一種是使證書被客戶端信任。另一種是使用HTTPCLIENT傳送資料時不檢測伺服器證書是否可信。
----------------------------------------------------------------------------------------------雙向認證:保證client和server是真的,通道是安全的(對稱金鑰);
單向認證:
1.clinet<——server
2.clinet——>server
1.client從server處拿到server的證書,通過公司的CA去驗證該證書,以確認server是真實的;
2.從server的證書中取出公鑰,對client端產生的一個金鑰加密(該金鑰即對稱金鑰)。將加密後的金鑰傳送到server端。server端用其私鑰解密出資料,即得到了對稱金鑰;
3.以後的交易都是http+該對稱金鑰加密的方式來處理;
雙向認證:
與單向認證的區別就是在1.2步驟中產生的是二分之一的對稱金鑰。
即對稱金鑰是client與server各自產生一半; ----------------------------------------------------------------------------------------------------------------------------
目前,要為另一個專案提供介面,介面是用HTTP URL實現的,最初的想法是另一個專案用JQuery post進行請求。
但是,很可能另一個專案是部署在別的機器上,那麼就存在跨域問題,而JQuery的post請求是不允許跨域的。
這時,就只能夠用HttpClient包進行請求了,同時由於請求的URL是HTTPS的,為了避免需要證書,所以用一個類繼承DefaultHttpClient類,忽略校驗過程。
1.寫一個SSLClient類,繼承至HttpClient
- import java.security.cert.CertificateException;
- import java.security.cert.X509Certificate;
- import javax.net.ssl.SSLContext;
- import javax.net.ssl.TrustManager;
- import javax.net.ssl.X509TrustManager;
- import org.apache.http.conn.ClientConnectionManager;
- import org.apache.http.conn.scheme.Scheme;
- import org.apache.http.conn.scheme.SchemeRegistry;
- import org.apache.http.conn.ssl.SSLSocketFactory;
- import org.apache.http.impl.client.DefaultHttpClient;
- //用於進行Https請求的HttpClient
- publicclass SSLClient extends DefaultHttpClient{
- public SSLClient() throws Exception{
- super();
- SSLContext ctx = SSLContext.getInstance("TLS");
-
//SSLContext ctx = SSLContext.getInstance("SSL");
- X509TrustManager tm = new X509TrustManager() {
- @Override
- publicvoid checkClientTrusted(X509Certificate[] chain,
- String authType) throws CertificateException {
- }
- @Override
- publicvoid checkServerTrusted(X509Certificate[] chain,
- String authType) throws CertificateException {
- }
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- returnnull;
- }
- };
- ctx.init(null, new TrustManager[]{tm}, null);
- SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
- ClientConnectionManager ccm = this.getConnectionManager();
- SchemeRegistry sr = ccm.getSchemeRegistry();
- sr.register(new Scheme("https", 443, ssf));
- }
- }
2.寫一個利用HttpClient傳送post請求的類
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import java.util.Map.Entry;
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.NameValuePair;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.entity.UrlEncodedFormEntity;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.message.BasicNameValuePair;
- import org.apache.http.util.EntityUtils;
- /*
- * 利用HttpClient進行post請求的工具類
- */
- publicclass HttpClientUtil {
- public String doPost(String url,Map<String,String> map,String charset){
- HttpClient httpClient = null;
- HttpPost httpPost = null;
- String result = null;
- try{
- httpClient = new SSLClient();
- httpPost = new HttpPost(url);
- //設定引數
- List<NameValuePair> list = new ArrayList<NameValuePair>();
- Iterator iterator = map.entrySet().iterator();
- while(iterator.hasNext()){
- Entry<String,String> elem = (Entry<String, String>) iterator.next();
- list.add(new BasicNameValuePair(elem.getKey(),elem.getValue()));
- }
- if(list.size() > 0){
- UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,charset);
- httpPost.setEntity(entity);
- }
- HttpResponse response = httpClient.execute(httpPost);
- if(response != null){
- HttpEntity resEntity = response.getEntity();
- if(resEntity != null){
- result = EntityUtils.toString(resEntity,charset);
- }
- }
- }catch(Exception ex){
- ex.printStackTrace();
- }
- return result;
- }
- }
- import java.util.HashMap;
- import java.util.Map;
- //對介面進行測試
- publicclass TestMain {
- private String url = "https://192.168.1.101/";
- private String charset = "utf-8";
- private HttpClientUtil httpClientUtil = null;
- public TestMain(){
- httpClientUtil = new HttpClientUtil();
- }
- publicvoid test(){
- String httpOrgCreateTest = url + "httpOrg/create";
- Map<String,String> createMap = new HashMap<String,String>();
- createMap.put("authuser","*****");
- createMap.put("authpass","*****");
- createMap.put("orgkey","****");
- createMap.put("orgname","****");
- String httpOrgCreateTestRtn = httpClientUtil.doPost(httpOrgCreateTest,createMap,charset);
- System.out.println("result:"+httpOrgCreateTestRtn);
- }
- publicstaticvoid main(String[] args){
- TestMain main = new TestMain();
- main.test();
- }
- }
httpClient4.2的jar包下載路徑:http://download.csdn.net/detail/hqmryang/4582440#comment