您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關HttpClient 4.0封裝工具類是怎樣的,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
以下為本人在實際開發過程中封裝的HttpClient工具類,HttpClient 4 較之 HttpClient 3 的變動較大,尤其是在SSL方面,包結構已經改得面目全非, 不過使用HttpClient 4 的SSL 及數字證書的雙向認證方面更為清晰及簡單了。[@more@]
/*
* @{#} HttpclientUtil.java
*
* Pingzonglangji.com Inc.
*
* Copyright (c) 2008-2009 All Rights Reserved.
*/
package com.pingzonglangji.common.net;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.net.ssl.SSLHandshakeException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URLEncodedUtils;
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.params.CoreProtocolPNames;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import com.pingzonglangji.common.lang.StringUtil;
/**
* Apache Httpclient 4.0 工具包裝類
*
* @author shezy
*/
@SuppressWarnings("all")
public class HttpclientUtil {
private static final String CHARSET_UTF8 = "UTF-8";
private static final String CHARSET_GBK = "GBK";
private static final String SSL_DEFAULT_SCHEME = "https";
private static final int SSL_DEFAULT_PORT = 443;
// 異常自動恢復處理, 使用HttpRequestRetryHandler接口實現請求的異常恢復
private static HttpRequestRetryHandler requestRetryHandler = new HttpRequestRetryHandler() {
// 自定義的恢復策略
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
// 設置恢復策略,在發生異常時候將自動重試3次
if (executionCount >= 3) {
// Do not retry if over max retry count
return false;
}
if (exception instanceof NoHttpResponseException) {
// Retry if the server dropped connection on us
return true;
}
if (exception instanceof SSLHandshakeException) {
// Do not retry on SSL handshake exception
return false;
}
HttpRequest request = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
boolean idempotent = (request instanceof HttpEntityEnclosingRequest);
if (!idempotent) {
// Retry if the request is considered idempotent
return true;
}
return false;
}
};
// 使用ResponseHandler接口處理響應,HttpClient使用ResponseHandler會自動管理連接的釋放,解決了對連接的釋放管理
private static ResponseHandler
// 自定義響應處理
public String handleResponse(HttpResponse response)throws ClientProtocolException, IOException {
HttpEntity entity = response.getEntity();
if (entity != null) {
String charset = EntityUtils.getContentCharSet(entity) == null ? CHARSET_GBK : EntityUtils.getContentCharSet(entity);
return new String(EntityUtils.toByteArray(entity), charset);
} else {
return null;
}
}
};
/**
* Get方式提交,URL中包含查詢參數, 格式:http://www.g.cn?search=p&name=s.....
*
* @param url
* 提交地址
* @return 響應消息
*/
public static String get(String url) {
return get(url, null, null);
}
/**
* Get方式提交,URL中不包含查詢參數, 格式:http://www.g.cn
*
* @param url
* 提交地址
* @param params
* 查詢參數集, 鍵/值對
* @return 響應消息
*/
public static String get(String url, Map
return get(url, params, null);
}
/**
* Get方式提交,URL中不包含查詢參數, 格式:http://www.g.cn
*
* @param url
* 提交地址
* @param params
* 查詢參數集, 鍵/值對
* @param charset
* 參數提交編碼集
* @return 響應消息
*/
public static String get(String url, Map
if (url == null || StringUtil.isEmpty(url)) {
return null;
}
List
if (qparams != null && qparams.size() > 0) {
charset = (charset == null ? CHARSET_GBK : charset);
String formatParams = URLEncodedUtils.format(qparams, charset);
url = (url.indexOf("?")) < 0 ? (url + "?" + formatParams) : (url
.substring(0, url.indexOf("?") + 1) + formatParams);
}
DefaultHttpClient httpclient = getDefaultHttpClient(charset);
HttpGet hg = new HttpGet(url);
// 發送請求,得到響應
String responseStr = null;
try {
responseStr = httpclient.execute(hg, responseHandler);
} catch (ClientProtocolException e) {
throw new NetServiceException("客戶端連接協議錯誤", e);
} catch (IOException e) {
throw new NetServiceException("IO操作異常", e);
} finally {
abortConnection(hg, httpclient);
}
return responseStr;
}
/**
* Post方式提交,URL中不包含提交參數, 格式:http://www.g.cn
*
* @param url
* 提交地址
* @param params
* 提交參數集, 鍵/值對
* @return 響應消息
*/
public static String post(String url, Map
return post(url, params, null);
}
/**
* Post方式提交,URL中不包含提交參數, 格式:http://www.g.cn
*
* @param url
* 提交地址
* @param params
* 提交參數集, 鍵/值對
* @param charset
* 參數提交編碼集
* @return 響應消息
*/
public static String post(String url, Map
if (url == null || StringUtil.isEmpty(url)) {
return null;
}
// 創建HttpClient實例
DefaultHttpClient httpclient = getDefaultHttpClient(charset);
UrlEncodedFormEntity formEntity = null;
try {
if (charset == null || StringUtil.isEmpty(charset)) {
formEntity = new UrlEncodedFormEntity(getParamsList(params));
} else {
formEntity = new UrlEncodedFormEntity(getParamsList(params), charset);
}
} catch (UnsupportedEncodingException e) {
throw new NetServiceException("不支持的編碼集", e);
}
HttpPost hp = new HttpPost(url);
hp.setEntity(formEntity);
// 發送請求,得到響應
String responseStr = null;
try {
responseStr = httpclient.execute(hp, responseHandler);
} catch (ClientProtocolException e) {
throw new NetServiceException("客戶端連接協議錯誤", e);
} catch (IOException e) {
throw new NetServiceException("IO操作異常", e);
} finally {
abortConnection(hp, httpclient);
}
return responseStr;
}
/**
* Post方式提交,忽略URL中包含的參數,解決SSL雙向數字證書認證
*
* @param url
* 提交地址
* @param params
* 提交參數集, 鍵/值對
* @param charset
* 參數編碼集
* @param keystoreUrl
* 密鑰存儲庫路徑
* @param keystorePassword
* 密鑰存儲庫訪問密碼
* @param truststoreUrl
* 信任存儲庫絕路徑
* @param truststorePassword
* 信任存儲庫訪問密碼, 可為null
* @return 響應消息
* @throws NetServiceException
*/
public static String post(String url, Map
final String keystorePassword, final URL truststoreUrl,final String truststorePassword) {
if (url == null || StringUtil.isEmpty(url)) {
return null;
}
DefaultHttpClient httpclient = getDefaultHttpClient(charset);
UrlEncodedFormEntity formEntity = null;
try {
if (charset == null || StringUtil.isEmpty(charset)) {
formEntity = new UrlEncodedFormEntity(getParamsList(params));
} else {
formEntity = new UrlEncodedFormEntity(getParamsList(params), charset);
}
} catch (UnsupportedEncodingException e) {
throw new NetServiceException("不支持的編碼集", e);
}
HttpPost hp = null;
String responseStr = null;
try {
KeyStore keyStore = createKeyStore(keystoreUrl, keystorePassword);
KeyStore trustStore = createKeyStore(truststoreUrl, keystorePassword);
SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore,keystorePassword, trustStore);
Scheme scheme = new Scheme(SSL_DEFAULT_SCHEME, socketFactory, SSL_DEFAULT_PORT);
httpclient.getConnectionManager().getSchemeRegistry().register(scheme);
hp = new HttpPost(url);
hp.setEntity(formEntity);
responseStr = httpclient.execute(hp, responseHandler);
} catch (NoSuchAlgorithmException e) {
throw new NetServiceException("指定的加密算法不可用", e);
} catch (KeyStoreException e) {
throw new NetServiceException("keytore解析異常", e);
} catch (CertificateException e) {
throw new NetServiceException("信任證書過期或解析異常", e);
} catch (FileNotFoundException e) {
throw new NetServiceException("keystore文件不存在", e);
} catch (IOException e) {
throw new NetServiceException("I/O操作失敗或中斷 ", e);
} catch (UnrecoverableKeyException e) {
throw new NetServiceException("keystore中的密鑰無法恢復異常", e);
} catch (KeyManagementException e) {
throw new NetServiceException("處理密鑰管理的操作異常", e);
} finally {
abortConnection(hp, httpclient);
}
return responseStr;
}
/**
* 獲取DefaultHttpClient實例
*
* @param charset
* 參數編碼集, 可空
* @return DefaultHttpClient 對象
*/
private static DefaultHttpClient getDefaultHttpClient(final String charset){
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
//模擬瀏覽器,解決一些服務器程序只允許瀏覽器訪問的問題
httpclient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)");
httpclient.getParams().setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, Boolean.FALSE);
httpclient.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, charset == null ? CHARSET_GBK : charset);
httpclient.setHttpRequestRetryHandler(requestRetryHandler);
return httpclient;
}
/**
* 釋放HttpClient連接
*
* @param hrb
* 請求對象
* @param httpclient
* client對象
*/
private static void abortConnection(final HttpRequestBase hrb, final HttpClient httpclient){
if (hrb != null) {
hrb.abort();
}
if (httpclient != null) {
httpclient.getConnectionManager().shutdown();
}
}
/**
* 從給定的路徑中加載此 KeyStore
*
* @param url
* keystore URL路徑
* @param password
* keystore訪問密鑰
* @return keystore 對象
*/
private static KeyStore createKeyStore(final URL url, final String password)
throws KeyStoreException, NoSuchAlgorithmException,CertificateException, IOException {
if (url == null) {
throw new IllegalArgumentException("Keystore url may not be null");
}
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream is = null;
try {
is = url.openStream();
keystore.load(is, password != null ? password.toCharArray() : null);
} finally {
if (is != null){
is.close();
is = null;
}
}
return keystore;
}
/**
* 將傳入的鍵/值對參數轉換為NameValuePair參數集
*
* @param paramsMap
* 參數集, 鍵/值對
* @return NameValuePair參數集
*/
private static List
if (paramsMap == null || paramsMap.size() == 0) {
return null;
}
List
for (Map.Entry
params.add(new BasicNameValuePair(map.getKey(), map.getValue()));
}
return params;
}
}
關于HttpClient 4.0封裝工具類是怎樣的就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。