import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
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.HttpVersion;
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.params.HttpClientParams;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.scheme.PlainSocketFactory;
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.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
/**
* 优化httpclient,解决线程安全,重复连接池等性能问题。
*
* */
public class HttpUtils {
private final static boolean DEBUG = false;
public final static String CHARSET = "UTF-8";
/**
* 这定义了通过网络与服务器建立连接的超时时间。 Httpclient包中通过一个异步线程去创建与服务器的socket连接
* ,这就是该socket连接的超时时间(毫秒)
*/
public final static int DEFAULT_SOCKET_TIMEOUT = 2000;
/** 这定义了Socket读数据的超时时间,即从服务器获取响应数据需要等待的时间(毫秒) */
public final static int WAIT_GETDATA_TIME = 4000;
/** 配置每台主机最多连接数 */
public final static int DEFAULT_HOST_CONNECTIONS = 50;
/** 和连接池中的最多连接总数 */
public final static int DEFAULT_MAX_CONNECTIONS = 50;
/** Socket 缓存大小 */
public final static int DEFAULT_SOCKET_BUFFER_SIZE = 8192;
/** 这定义了从ConnectionManager管理的连接池中取出连接的超时时间(毫秒) */
public final static int GET_CONNECT_TIME = 1000;
private static HttpClient httpClient = null;
private static synchronized HttpClient getHttpClient() {
if (httpClient == null) {
final HttpParams httpParams = new BasicHttpParams();
ConnManagerParams.setTimeout(httpParams, GET_CONNECT_TIME);
HttpConnectionParams.setConnectionTimeout(httpParams, DEFAULT_SOCKET_TIMEOUT);
HttpConnectionParams.setSoTimeout(httpParams, WAIT_GETDATA_TIME);
ConnManagerParams.setMaxConnectionsPerRoute(httpParams, new ConnPerRouteBean(DEFAULT_HOST_CONNECTIONS));
ConnManagerParams.setMaxTotalConnections(httpParams, DEFAULT_MAX_CONNECTIONS);
/** 以先发送部分请求(如:只发送请求头)进行试探,如果服务器愿意接收,则继续发送请求体 */
HttpProtocolParams.setUseExpectContinue(httpParams, true);
/**
* 即在有传输数据需求时,会首先检查连接池中是否有可供重用的连接,如果有,则会重用连接。
* 同时,为了确保该“被重用”的连接确实有效,会在重用之前对其进行有效性检查
*/
HttpConnectionParams.setStaleCheckingEnabled(httpParams, false);
HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(httpParams, HTTP.UTF_8);
HttpClientParams.setRedirecting(httpParams, false);
// 设置代理
String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2) Gecko/20100115 Firefox/3.6";
HttpProtocolParams.setUserAgent(httpParams, userAgent);
// disable Nagle algorithm
HttpConnectionParams.setTcpNoDelay(httpParams, true);
HttpConnectionParams.setSocketBufferSize(httpParams, DEFAULT_SOCKET_BUFFER_SIZE);
// 配置 http and https
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
ClientConnectionManager manager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);
httpClient = new DefaultHttpClient(manager, httpParams);
}
return httpClient;
}
public static InputStream doHttpClientPost(String url, HashMap<String, String> params) {
if (DEBUG) {
System.out.println("doPost url is " + url);
}
HttpClient httpClient = getHttpClient();
HttpPost httpRequest = new HttpPost(url);
List<BasicNameValuePair> httpParams = new ArrayList<BasicNameValuePair>();
Iterator<Entry<String, String>> iter = params.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, String> entry = iter.next();
String key = entry.getKey();
String val = entry.getValue();
httpParams.add(new BasicNameValuePair(key, val));
}
InputStream inputStream = null;
String erroMsg = null;
try {
httpRequest.setEntity(new UrlEncodedFormEntity(httpParams, HTTP.UTF_8));
} catch (UnsupportedEncodingException e) {
}
HttpResponse httpResponse = null;
try {
httpResponse = httpClient.execute(httpRequest);
} catch (ClientProtocolException e) {
erroMsg = e.getMessage().toString();
e.printStackTrace();
} catch (IOException e) {
erroMsg = e.getMessage().toString();
e.printStackTrace();
}
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode == 200) {
try {
inputStream = httpResponse.getEntity().getContent();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else {
erroMsg = "Error Response: " + httpResponse.getStatusLine().toString();
}
if (erroMsg != null) {
System.out.println("doPost error, error message is " + erroMsg);
}
return inputStream;
}
public static InputStream doHttpsClientPost(String url, String params) {
if (DEBUG) {
System.out.println("doPost url is " + url);
}
HttpClient httpClient = getHttpClient();
HttpPost httpRequest = new HttpPost(url);
InputStream inputStream = null;
String erroMsg = null;
try {
HttpEntity entity = new StringEntity(params,"utf-8");
httpRequest.setEntity(entity);
} catch (UnsupportedEncodingException e) {
}
HttpResponse httpResponse = null;
try {
httpResponse = httpClient.execute(httpRequest);
} catch (ClientProtocolException e) {
erroMsg = e.getMessage().toString();
e.printStackTrace();
} catch (IOException e) {
erroMsg = e.getMessage().toString();
e.printStackTrace();
}
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode == 200) {
try {
inputStream = httpResponse.getEntity().getContent();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else {
erroMsg = "Error Response: " + httpResponse.getStatusLine().toString();
}
if (erroMsg != null) {
System.out.println("doPost error, error message is " + erroMsg);
}
return inputStream;
}
public static InputStream doHttpClientGet(String url, HashMap<String, String> params) {
HttpClient httpClient = getHttpClient();
if (DEBUG) {
System.out.println("doGet the url before encode is " + url);
}
if (params != null) {
String paramStr = "";
try {
Iterator<Entry<String, String>> iter = params.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, String> entry = iter.next();
String key = entry.getKey();
key = URLEncoder.encode(key, "UTF-8");
String val = entry.getValue();
val = URLEncoder.encode(val, "UTF-8");
paramStr += paramStr = "&" + key + "=" + val;
}
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
if (!paramStr.equals("")) {
paramStr = paramStr.replaceFirst("&", "?");
url += paramStr;
}
}
if (DEBUG) {
System.out.println("doGet the url after encode is " + url);
}
HttpGet httpRequest = null;
try {
httpRequest = new HttpGet(url);
} catch (IllegalArgumentException e) {
System.out.println("uri argument error");
return null;
}
InputStream inputStream = null;
HttpResponse httpResponse = null;
try {
httpResponse = httpClient.execute(httpRequest);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (SocketTimeoutException e) {
e.printStackTrace();
} catch (ConnectTimeoutException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
if (httpResponse == null) {
System.out.println("no response from server");
return null;
}
if (httpResponse.getStatusLine().getStatusCode() == 200) {
HttpEntity httpEntity = httpResponse.getEntity();
try {
inputStream = httpEntity.getContent();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
System.out.println("Error Response: " + httpResponse.getStatusLine().toString());
}
return inputStream;
}
// 未经优化的原声方法
public static String doHttpURLConnection(String myurl) throws IOException {
InputStream is = null;
// Only display the first 1000 characters of the retrieved
// web page content.
int len = 1000;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
int response = conn.getResponseCode();
if (DEBUG) {
System.out.println("The response is: " + response);
}
is = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = readIt(is, len);
return contentAsString;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} finally {
if (is != null) {
is.close();
}
}
}
// Reads an InputStream and converts it to a String.
public static String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
if (stream == null)
return null;
Reader reader = null;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[len];
reader.read(buffer);
return new String(buffer);
}
}
转载于:https://my.oschina.net/chainlong/blog/302536