HttpClient工具類
package com.cucpay.tradeportal.util;import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; 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.HttpGet; import org.apache.http.client.methods.HttpPost; 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.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils;
/**
- 封裝了一些采用HttpClient發送HTTP請求的方法
- @see 本工具所采用的是最新的HttpComponents-Client-4.2.1
- @see 關于本工具類中的一些解釋說明,可參考下方列出的我的三篇文章
- @see http://blog.csdn.net/jadyer/article/details/7615830
- @see http://blog.csdn.net/jadyer/article/details/7615880
- @see http://blog.csdn.net/jadyer/article/details/7802139
- @create Feb 1, 2012 3:02:27 PM
- @update Oct 8, 2012 3:48:55 PM
- @author 玄玉<http://blog.csdn/net/jadyer>
- @version v1.3
- @history v1.0-->新建<code>sendGetRequest(String,String)</code>和<code>sendPostRequest(String,Map<String,String>,String,String)</code>方法
- @history v1.1-->新增<code>sendPostSSLRequest(String,Map<String,String>,String,String)</code>方法,用于發送HTTPS的POST請求
- @history v1.2-->新增<code>sendPostRequest(String,String,boolean,String,String)</code>方法,用于發送HTTP協議報文體為任意字符串的POST請求
@history v1.3-->新增<code>java.net.HttpURLConnection</code>實現的<code>sendPostRequestByJava()</code>方法 */ public class HttpClientUtil { private HttpClientUtil(){}
/**
- 發送HTTP_GET請求
- @see 該方法會自動關閉連接,釋放資源
- @param requestURL 請求地址(含參數)
- @param decodeCharset 解碼字符集,解析響應數據時用之,其為null時默認采用UTF-8解碼
- @return 遠程主機響應正文
*/
public static String sendGetRequest(String reqURL, String decodeCharset){
long responseLength = 0; //響應長度
String responseContent = null; //響應內容
HttpClient httpClient = new DefaultHttpClient(); //創建默認的httpClient實例
HttpGet httpGet = new HttpGet(reqURL); //創建org.apache.http.client.methods.HttpGet
try{
}catch(ClientProtocolException e){HttpResponse response = httpClient.execute(httpGet); //執行GET請求 HttpEntity entity = response.getEntity(); //獲取響應實體 if(null != entity){ responseLength = entity.getContentLength(); responseContent = EntityUtils.toString(entity, decodeCharset==null ? "UTF-8" : decodeCharset); EntityUtils.consume(entity); //Consume response content } System.out.println("請求地址: " + httpGet.getURI()); System.out.println("響應狀態: " + response.getStatusLine()); System.out.println("響應長度: " + responseLength); System.out.println("響應內容: " + responseContent);
}catch(ParseException e){LogUtil.getLogger().error("該異常通常是協議錯誤導致,比如構造HttpGet對象時傳入的協議不對(將'http'寫成'htp')或者服務器端返回的內容不符合HTTP協議要求等,堆棧信息如下", e);
}catch(IOException e){LogUtil.getLogger().error(e.getMessage(), e);
}finally{LogUtil.getLogger().error("該異常通常是網絡原因引起的,如HTTP服務器未啟動等,堆棧信息如下", e);
} return responseContent; }httpClient.getConnectionManager().shutdown(); //關閉連接,釋放資源
/**
* 發送HTTP_POST請求
* @see 該方法為<code>sendPostRequest(String,String,boolean,String,String)</code>的簡化方法
* @see 該方法在對請求數據的編碼和響應數據的解碼時,所采用的字符集均為UTF-8
* @see 當<code>isEncoder=true</code>時,其會自動對<code>sendData</code>中的[中文][|][ ]等特殊字符進行<code>URLEncoder.encode(string,"UTF-8")</code>
* @param isEncoder 用于指明請求數據是否需要UTF-8編碼,true為需要
*/
public static String sendPostRequest(String reqURL, String sendData, boolean isEncoder){
return sendPostRequest(reqURL, sendData, isEncoder, null, null);
}
/**
* 發送HTTP_POST請求
* @see 該方法會自動關閉連接,釋放資源
* @see 當<code>isEncoder=true</code>時,其會自動對<code>sendData</code>中的[中文][|][ ]等特殊字符進行<code>URLEncoder.encode(string,encodeCharset)</code>
* @param reqURL 請求地址
* @param sendData 請求參數,若有多個參數則應拼接成param11=value11?m22=value22?m33=value33的形式后,傳入該參數中
* @param isEncoder 請求數據是否需要encodeCharset編碼,true為需要
* @param encodeCharset 編碼字符集,編碼請求數據時用之,其為null時默認采用UTF-8解碼
* @param decodeCharset 解碼字符集,解析響應數據時用之,其為null時默認采用UTF-8解碼
* @return 遠程主機響應正文
*/
public static String sendPostRequest(String reqURL, String sendData, boolean isEncoder, String encodeCharset, String decodeCharset){
String responseContent = null;
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(reqURL);
//httpPost.setHeader(HTTP.CONTENT_TYPE, "application/x-www-form-urlencoded; charset=UTF-8");
httpPost.setHeader(HTTP.CONTENT_TYPE, "application/x-www-form-urlencoded");
try{
if(isEncoder){
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
for(String str : sendData.split("&")){
formParams.add(new BasicNameValuePair(str.substring(0,str.indexOf("=")), str.substring(str.indexOf("=")+1)));
}
httpPost.setEntity(new StringEntity(URLEncodedUtils.format(formParams, encodeCharset==null ? "UTF-8" : encodeCharset)));
}else{
httpPost.setEntity(new StringEntity(sendData));
}
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
if (null != entity) {
responseContent = EntityUtils.toString(entity, decodeCharset==null ? "UTF-8" : decodeCharset);
EntityUtils.consume(entity);
}
}catch(Exception e){
LogUtil.getLogger().error("與[" + reqURL + "]通信過程中發生異常,堆棧信息如下", e);
}finally{
httpClient.getConnectionManager().shutdown();
}
return responseContent;
}
/**
* 發送HTTP_POST請求
* @see 該方法會自動關閉連接,釋放資源
* @see 該方法會自動對<code>params</code>中的[中文][|][ ]等特殊字符進行<code>URLEncoder.encode(string,encodeCharset)</code>
* @param reqURL 請求地址
* @param params 請求參數
* @param encodeCharset 編碼字符集,編碼請求數據時用之,其為null時默認采用UTF-8解碼
* @param decodeCharset 解碼字符集,解析響應數據時用之,其為null時默認采用UTF-8解碼
* @return 遠程主機響應正文
*/
public static String sendPostRequest(String reqURL, Map<String, String> params, String encodeCharset, String decodeCharset){
String responseContent = null;
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(reqURL);
List<NameValuePair> formParams = new ArrayList<NameValuePair>(); //創建參數隊列
for(Map.Entry<String,String> entry : params.entrySet()){
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
try{
httpPost.setEntity(new UrlEncodedFormEntity(formParams, encodeCharset==null ? "UTF-8" : encodeCharset));
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
if (null != entity) {
responseContent = EntityUtils.toString(entity, decodeCharset==null ? "UTF-8" : decodeCharset);
EntityUtils.consume(entity);
}
}catch(Exception e){
LogUtil.getLogger().error("與[" + reqURL + "]通信過程中發生異常,堆棧信息如下", e);
}finally{
httpClient.getConnectionManager().shutdown();
}
return responseContent;
}
/**
* 發送HTTPS_POST請求
* @see 該方法為<code>sendPostSSLRequest(String,Map<String,String>,String,String)</code>方法的簡化方法
* @see 該方法在對請求數據的編碼和響應數據的解碼時,所采用的字符集均為UTF-8
* @see 該方法會自動對<code>params</code>中的[中文][|][ ]等特殊字符進行<code>URLEncoder.encode(string,"UTF-8")</code>
*/
public static String sendPostSSLRequest(String reqURL, Map<String, String> params){
return sendPostSSLRequest(reqURL, params, null, null);
}
/**
* 發送HTTPS_POST請求
* @see 該方法會自動關閉連接,釋放資源
* @see 該方法會自動對<code>params</code>中的[中文][|][ ]等特殊字符進行<code>URLEncoder.encode(string,encodeCharset)</code>
* @param reqURL 請求地址
* @param params 請求參數
* @param encodeCharset 編碼字符集,編碼請求數據時用之,其為null時默認采用UTF-8解碼
* @param decodeCharset 解碼字符集,解析響應數據時用之,其為null時默認采用UTF-8解碼
* @return 遠程主機響應正文
*/
public static String sendPostSSLRequest(String reqURL, Map<String, String> params, String encodeCharset, String decodeCharset){
String responseContent = "";
HttpClient httpClient = new DefaultHttpClient();
X509TrustManager xtm = new X509TrustManager(){
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public X509Certificate[] getAcceptedIssuers() {return null;}
};
try {
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[]{xtm}, null);
SSLSocketFactory socketFactory = new SSLSocketFactory(ctx);
httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory));
HttpPost httpPost = new HttpPost(reqURL);
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
for(Map.Entry<String,String> entry : params.entrySet()){
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
httpPost.setEntity(new UrlEncodedFormEntity(formParams, encodeCharset==null ? "UTF-8" : encodeCharset));
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
if (null != entity) {
responseContent = EntityUtils.toString(entity, decodeCharset==null ? "UTF-8" : decodeCharset);
EntityUtils.consume(entity);
}
} catch (Exception e) {
LogUtil.getLogger().error("與[" + reqURL + "]通信過程中發生異常,堆棧信息為", e);
} finally {
httpClient.getConnectionManager().shutdown();
}
return responseContent;
}
/**
* 發送HTTP_POST請求
* @see 若發送的<code>params</code>中含有中文,記得按照雙方約定的字符集將中文<code>URLEncoder.encode(string,encodeCharset)</code>
* @see 本方法默認的連接超時時間為30秒,默認的讀取超時時間為30秒
* @param reqURL 請求地址
* @param params 發送到遠程主機的正文數據,其數據類型為<code>java.util.Map<String, String></code>
* @return 遠程主機響應正文`HTTP狀態碼,如<code>"SUCCESS`200"</code><br>若通信過程中發生異常則返回"Failed`HTTP狀態碼",如<code>"Failed`500"</code>
*/
public static String sendPostRequestByJava(String reqURL, Map<String, String> params){
StringBuilder sendData = new StringBuilder();
for(Map.Entry<String, String> entry : params.entrySet()){
sendData.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
if(sendData.length() > 0){
sendData.setLength(sendData.length() - 1); //刪除最后一個&符號
}
return sendPostRequestByJava(reqURL, sendData.toString());
}
/**
* 發送HTTP_POST請求
* @see 若發送的<code>sendData</code>中含有中文,記得按照雙方約定的字符集將中文<code>URLEncoder.encode(string,encodeCharset)</code>
* @see 本方法默認的連接超時時間為30秒,默認的讀取超時時間為30秒
* @param reqURL 請求地址
* @param sendData 發送到遠程主機的正文數據
* @return 遠程主機響應正文`HTTP狀態碼,如<code>"SUCCESS`200"</code><br>若通信過程中發生異常則返回"Failed`HTTP狀態碼",如<code>"Failed`500"</code>
*/
public static String sendPostRequestByJava(String reqURL, String sendData){
HttpURLConnection httpURLConnection = null;
OutputStream out = null; //寫
InputStream in = null; //讀
int httpStatusCode = 0; //遠程主機響應的HTTP狀態碼
try{
URL sendUrl = new URL(reqURL);
httpURLConnection = (HttpURLConnection)sendUrl.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true); //指示應用程序要將數據寫入URL連接,其值默認為false
httpURLConnection.setUseCaches(false);
httpURLConnection.setConnectTimeout(30000); //30秒連接超時
httpURLConnection.setReadTimeout(30000); //30秒讀取超時
out = httpURLConnection.getOutputStream();
out.write(sendData.toString().getBytes());
//清空緩沖區,發送數據
out.flush();
//獲取HTTP狀態碼
httpStatusCode = httpURLConnection.getResponseCode();
//該方法只能獲取到[HTTP/1.0 200 OK]中的[OK]
//若對方響應的正文放在了返回報文的最后一行,則該方法獲取不到正文,而只能獲取到[OK],稍顯遺憾
//respData = httpURLConnection.getResponseMessage();
// //處理返回結果 // BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream())); // String row = null; // String respData = ""; // if((row=br.readLine()) != null){ //readLine()方法在讀到換行[\n]或回車[\r]時,即認為該行已終止 // respData = row; //HTTP協議POST方式的最后一行數據為正文數據 // } // br.close();
in = httpURLConnection.getInputStream();
byte[] byteDatas = new byte[in.available()];
in.read(byteDatas);
return new String(byteDatas) + "`" + httpStatusCode;
}catch(Exception e){
LogUtil.getLogger().error(e.getMessage());
return "Failed`" + httpStatusCode;
}finally{
if(out != null){
try{
out.close();
}catch (Exception e){
LogUtil.getLogger().error("關閉輸出流時發生異常,堆棧信息如下", e);
}
}
if(in != null){
try{
in.close();
}catch(Exception e){
LogUtil.getLogger().error("關閉輸入流時發生異常,堆棧信息如下", e);
}
}
if(httpURLConnection != null){
httpURLConnection.disconnect();
httpURLConnection = null;
}
}
}
}</pre>來自:http://blog.csdn.net/jadyer/article/details/8087960