HttpClientUtil-用於後臺發起請求

項目中常常須要經過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

相關文章
相關標籤/搜索