直接上码
最近用到多线程来对请求HTTP , 但是http的每次请求都是一次连接后重新连接,导致大量的数据积压,所以根据资料,重新写了一个HTTP的工具类
- package cn.zto.util;
- import java.io.UnsupportedEncodingException;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- import org.apache.commons.lang.StringUtils;
- import org.apache.http.HttpEntity;
- import org.apache.http.NameValuePair;
- import org.apache.http.client.config.RequestConfig;
- import org.apache.http.client.entity.UrlEncodedFormEntity;
- import org.apache.http.client.methods.CloseableHttpResponse;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.entity.StringEntity;
- import org.apache.http.impl.client.CloseableHttpClient;
- import org.apache.http.impl.client.HttpClients;
- import org.apache.http.impl.client.LaxRedirectStrategy;
- import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
- import org.apache.http.message.BasicNameValuePair;
- import org.apache.http.util.EntityUtils;
- import cn.zto.entity.HttpResEntity;
- public class HttpUtils {
- private static final CloseableHttpClient httpClient;
- public static final String CHARSET_GBK = "GBK";
- public static final String CHARSET_UTF8 = "UTF-8";
- // 将最大连接数增加到
- public static final int MAX_TOTAL = 600;
- // 将每个路由基础的连接增加到
- public static final int MAX_ROUTE_TOTAL = 300;
- public static final int REQUEST_TIMEOUT = 5*1000;
- public static final int REQUEST_SOCKET_TIME = 5*1000;
- /*static {
- //设置连接超时 的时间
- RequestConfig config = RequestConfig.custom().setConnectTimeout(60000)
- .setSocketTimeout(15000).build();
- httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config)
- .build();
- }*/
- static {
- // 设置连接超时 的时间
- PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager();
- httpClientConnectionManager.setMaxTotal(MAX_TOTAL);
- httpClientConnectionManager.setDefaultMaxPerRoute(MAX_ROUTE_TOTAL);
- RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(REQUEST_TIMEOUT)
- .setSocketTimeout(REQUEST_SOCKET_TIME).build();
- //设置重定向策略
- LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy();
- httpClient = HttpClients.custom().setConnectionManager(httpClientConnectionManager)
- .setDefaultRequestConfig(requestConfig).setRedirectStrategy(redirectStrategy).build();
- }
- public static HttpResEntity doGet(String url, Map<String, Object> params,
- String charset) {
- HttpResEntity entity = new HttpResEntity();
- if (StringUtils.isBlank(url)) {
- entity.setMsg("请求地址异常");
- entity.setStatus(404);
- return entity;
- }
- try {
- if (params != null && !params.isEmpty()) {
- List<NameValuePair> pairs = new ArrayList<NameValuePair>(
- params.size());
- for (Map.Entry<String, Object> entry : params.entrySet()) {
- Object value = entry.getValue();
- if (value != null) {
- pairs.add(new BasicNameValuePair(entry.getKey(),
- (String) value));
- }
- }
- url += "?"
- + EntityUtils.toString(new UrlEncodedFormEntity(pairs,
- charset));
- }
- HttpGet httpGet = new HttpGet(url);
- CloseableHttpResponse response = httpClient.execute(httpGet);
- int statusCode = response.getStatusLine().getStatusCode();
- if (statusCode != 200) {
- httpGet.abort();
- entity.setData("请求异常");
- entity.setStatus(statusCode);
- return entity;
- }
- HttpEntity httpEntity = response.getEntity();
- String result = null;
- if (entity != null) {
- result = EntityUtils.toString(httpEntity, charset);
- }
- EntityUtils.consume(httpEntity);
- response.close();
- entity.setStatus(statusCode);
- entity.setData(result);
- return entity;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- public static HttpResEntity doPost(String url, Map<String, Object> params,
- String charset) {
- List<NameValuePair> pairs = null;
- if (params != null && !params.isEmpty()) {
- pairs = new ArrayList<NameValuePair>(params.size());
- for (Map.Entry<String, Object> entry : params.entrySet()) {
- Object value = entry.getValue();
- if (value != null) {
- pairs.add(new BasicNameValuePair(entry.getKey(),
- (String) value));
- }
- }
- }
- StringEntity httpEntity = null;
- try {
- httpEntity = new UrlEncodedFormEntity(pairs, charset);
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
- return doPost(url, httpEntity, charset);
- }
- public static HttpResEntity doPost(String url, String params, String charset) {
- StringEntity entity = null;
- try {
- entity = new StringEntity(params, charset);
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
- return doPost(url, entity, charset);
- }
- /**
- * HTTP Post 获取内容
- *
- * @param url
- * 请求的url地址 ?之前的地址
- * @param params
- * 请求的参数
- * @param charset
- * 编码格式
- * @return 页面内容
- */
- public static HttpResEntity doPost(String url, StringEntity params,
- String charset) {
- HttpResEntity entity = new HttpResEntity();
- if (StringUtils.isBlank(url)) {
- entity.setMsg("请求地址异常");
- entity.setStatus(404);
- return entity;
- }
- try {
- HttpPost httpPost = new HttpPost(url);
- if (params != null) {
- httpPost.setEntity(params);
- }
- CloseableHttpResponse response = httpClient.execute(httpPost);
- int statusCode = response.getStatusLine().getStatusCode();
- if (statusCode != 200) {
- httpPost.abort();
- entity.setData("请求异常");
- entity.setStatus(statusCode);
- return entity;
- }
- HttpEntity httpEntity = response.getEntity();
- String result = null;
- if (httpEntity != null) {
- result = EntityUtils.toString(httpEntity, charset);
- }
- EntityUtils.consume(httpEntity);
- response.close();
- entity.setStatus(statusCode);
- entity.setData(result);
- return entity;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- }
- static {
- //设置连接超时 的时间
- RequestConfig config = RequestConfig.custom().setConnectTimeout(60000)
- .setSocketTimeout(15000).build();
- httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config)
- .build();
这是原先的设置的超时时间,其中并没有设置连接池,所以在500个线程并发,并且每个线程有100次循环时,耗时极长。
贴上来一段多线程的测试
- public static void main(String[] args) throws InterruptedException,
- ExecutionException {
- long startTime = System.currentTimeMillis();
- System.out.println("程序开始运行");
- int taskSize = 500;
- Date date = new Date();
- // 创建一个线程池
- ExecutorService pool = Executors.newFixedThreadPool(taskSize);
- // 创建多个有返回值的任务
- List<Future> list = new ArrayList<Future>();
- for (int i = 0; i < taskSize; i++) {
- Callable c = new MyCallable2(i + "");
- Future f = pool.submit(c);
- list.add(f);
- }
- pool.shutdown();
- // 获取所有并发任务的运行结果
- for (Future f : list) {
- // 从Future对象上获取任务的返回值,并输出到控制台
- System.out.println(">>>" + f.get().toString());
- Date date2 = new Date();
- System.out.println("----程序结束运行----,程序运行时间【"
- + (date2.getTime() - date.getTime()) + "毫秒】");
- }
- System.out.println("程序共耗时:"+(System.currentTimeMillis()-startTime)+"毫秒");
- }
现在把配置改为
- static {
- // 设置连接超时 的时间
- PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager();
- httpClientConnectionManager.setMaxTotal(MAX_TOTAL);
- httpClientConnectionManager.setDefaultMaxPerRoute(MAX_ROUTE_TOTAL);
- RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(REQUEST_TIMEOUT)
- .setSocketTimeout(REQUEST_SOCKET_TIME).build();
- //设置重定向策略
- LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy();
- httpClient = HttpClients.custom().setConnectionManager(httpClientConnectionManager)
- .setDefaultRequestConfig(requestConfig).setRedirectStrategy(redirectStrategy).build();
- }
推荐文章
使用httpclient必须知道的参数设置及代码写法、存在的风险 :http://jinnianshilongnian.iteye.com/blog/2089792
HttpClient4.3教程 第二章 连接管理:http://niuzhenxin.iteye.com/blog/2100100
原文章地址:http://blog.csdn.net/wangqingqi20005/article/details/47904153