項目中常常須要經過apache的http client模擬發送請求,因而動手寫了HttpClientUtil這個工具類。該工具類主要出於下面幾個方面考慮做設計: java
一、具有發送http post請求的功能; apache
二、請求參數編碼和讀取內容編碼的設置,解決亂碼問題; 數組
三、請求超時和鏈接關閉。 工具
經過單例模式,提供HttpClientUtil的實例,提供的API有: post
//獲取單例對象,並設置默認的頁面編碼 public static HttpClientUtil getInstance(String urlCharset); //設置編碼 public void setUrlCharset(String urlCharset); //獲取字符串型返回結果,經過發起http post請求 public String getResponseBodyAsString(String targetUrl,Map params)throws Exception; //獲取字符數組型返回結果,經過發起http post請求 public byte[] getResponseBodyAsByteArray(String targetUrl,Map params)throws Exception; //將response的返回流寫到outputStream中,經過發起http post請求 public void getResponseBodyAsStream(String targetUrl,Map params,OutputStream outputStream)throws Exception;完整的代碼以下:
/* * 建立日期 2014-3-13 * * TODO 要更改今生成的文件的模板,請轉至 * 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板 */ package com.excellence.explatform.client.util; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.SimpleHttpConnectionManager; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.params.HttpClientParams; import org.apache.commons.httpclient.params.HttpMethodParams; import org.apache.commons.lang.StringUtils; /** * @author administrator * * Http Client工具類 * 發起http client 請求 * * 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板 */ public final class HttpClientUtil { private static final String TYPE_STRING = "string"; private static final String TYPE_BYTEARRAY = "byte[]"; private static final String TYPE_STREAM = "stream"; private static HttpClientUtil instance; private HttpClientUtil(){} /** * 使用默認的頁面請求編碼:utf-8 * @return */ public static HttpClientUtil getInstance(){ return getInstance("UTF-8"); } public static HttpClientUtil getInstance(String urlCharset){ if(instance == null){ instance = new HttpClientUtil(); } //設置默認的url編碼 instance.setUrlCharset(urlCharset); return instance; } /** * 請求編碼,默認使用utf-8 */ private String urlCharset = "UTF-8"; /** * @param urlCharset 要設置的 urlCharset。 */ public void setUrlCharset(String urlCharset) { this.urlCharset = urlCharset; } /** * 獲取字符串型返回結果,經過發起http post請求 * @param targetUrl * @param params * @return * @throws Exception */ public String getResponseBodyAsString(String targetUrl,Map params)throws Exception{ return (String)setPostRequest(targetUrl,params,TYPE_STRING,null); } /** * 獲取字符數組型返回結果,經過發起http post請求 * @param targetUrl * @param params * @return * @throws Exception */ public byte[] getResponseBodyAsByteArray(String targetUrl,Map params)throws Exception{ return (byte[])setPostRequest(targetUrl,params,TYPE_BYTEARRAY,null); } /** * 將response的返回流寫到outputStream中,經過發起http post請求 * @param targetUrl 請求地址 * @param params 請求參數<paramName,paramValue> * @param outputStream 輸出流 * @throws Exception */ public void getResponseBodyAsStream(String targetUrl,Map params,OutputStream outputStream)throws Exception{ if(outputStream == null){ throw new IllegalArgumentException("調用HttpClientUtil.setPostRequest方法,targetUrl不能爲空!"); } //response 的返回結果寫到輸出流 setPostRequest(targetUrl,params,TYPE_STREAM,outputStream); } /** * 利用http client模擬發送http post請求 * @param targetUrl 請求地址 * @param params 請求參數<paramName,paramValue> * @return Object 返回的類型多是:String 或者 byte[] 或者 outputStream * @throws Exception */ private Object setPostRequest(String targetUrl,Map params,String responseType,OutputStream outputStream)throws Exception{ if(StringUtils.isBlank(targetUrl)){ throw new IllegalArgumentException("調用HttpClientUtil.setPostRequest方法,targetUrl不能爲空!"); } Object responseResult = null; HttpClient client = null; PostMethod post = null; NameValuePair[] nameValuePairArr = null; SimpleHttpConnectionManager connectionManager = null; try{ connectionManager = new SimpleHttpConnectionManager(true); //鏈接超時,單位毫秒 connectionManager.getParams().setConnectionTimeout(3000); //讀取超時,單位毫秒 connectionManager.getParams().setSoTimeout(60000); //設置獲取內容編碼 connectionManager.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,urlCharset); client = new HttpClient(new HttpClientParams(),connectionManager); post = new PostMethod(targetUrl); //設置請求參數的編碼 post.getParams().setContentCharset(urlCharset); //服務端完成返回後,主動關閉連接 post.setRequestHeader("Connection","close"); if(params != null){ nameValuePairArr = new NameValuePair[params.size()]; Set key = params.keySet(); Iterator keyIte = key.iterator(); int index = 0; while(keyIte.hasNext()){ Object paramName = keyIte.next(); Object paramValue = params.get(paramName); if(paramName instanceof String && paramValue instanceof String){ NameValuePair pair = new NameValuePair((String)paramName,(String)paramValue); nameValuePairArr[index] = pair; index++; } } post.addParameters(nameValuePairArr); } int sendStatus = client.executeMethod(post); if(sendStatus == HttpStatus.SC_OK){ System.out.println("HttpClientUtil.setPostRequest()-responseType:"+responseType); if(StringUtils.equals(TYPE_STRING,responseType)){ responseResult = post.getResponseBodyAsString(); }else if(StringUtils.equals(TYPE_BYTEARRAY,responseType)){ responseResult = post.getResponseBody(); }else if(StringUtils.equals(TYPE_STREAM,responseType)){ InputStream tempStream = post.getResponseBodyAsStream(); byte[] temp = new byte[1024]; int index = -1; while((index = tempStream.read(temp)) != -1){ outputStream.write(temp); } } }else{ System.err.println("***************************"); System.err.println("HttpClientUtil.setPostRequest()-請求url:"+targetUrl+" 出錯\n請求參數有:"+JsonUtil.java2JsonStr(params)+"!!!"); System.err.println("***************************"); } }catch(Exception e){ e.printStackTrace(); }finally{ //釋放連接 if(post != null){ post.releaseConnection(); } //關閉連接 if(connectionManager != null){ connectionManager.shutdown(); } } return responseResult; } /** * 測試方法 * @param args */ public static void main(String[] args)throws Exception{ //String url = "http://192.168.33.33:7001/rworg/rworg/poPublic.do?method=portalSearch"; String url = "http://localhost:9080/platform/baseService/um/dataSync.do"; Map params = new HashMap(); params.put("method","saveUser"); params.put("userAccount","admin"); params.put("keyWords","111"); params.put("type","中午 個人是"); HttpClientUtil util = HttpClientUtil.getInstance("GBK"); String resultStr = util.getResponseBodyAsString(url,params); byte[] resultArr = util.getResponseBodyAsByteArray(url,params); File file = new File("D:\\result.txt"); FileOutputStream out = new FileOutputStream(file); util.getResponseBodyAsStream(url,params,out); System.out.println("HttpClientUtil.main()-result:"+resultStr); if(resultArr != null){ System.out.println("HttpClientUtil.main()-result:"+new String(resultArr)); } } }須要注意的兩個問題:
一、代碼中使用的http-client版本是3.1,這個比較重要,直接使用該工具類還須要增長其餘的依賴包(commons-codec.jar和commons-logging) 測試
二、該版本的源碼中,能夠將鏈接超時和讀取超時設計成可配置,在使用工具類的時候,可以依據實際的狀況設置鏈接超時和讀取超時的具體值。 this