使用HttpClient管理HTTP请求

阅读更多

HTTP请求工具类,基于HttpClient4.5.1实现,可以帮你在程序后台默默完成POST、GET请求,使用方法参见注释,上代码:

 

HttpHandler httpHandler = new HttpHandler();
try {

	httpHandler.init();

	Map resultMap = httpHandler.doGet("http://www.baidu.com");
	if (CollectionUtil.isNotEmpty(resultMap)) {

		String result = new String((byte[]) resultMap.get(HttpHandler.BODY_KEY));

		System.out.println(result);
	}
} catch (Exception ex) {

	ex.printStackTrace();
} finally {

	httpHandler.destroy();
}

 

另外有大量的重载方法用于一些特殊场合,参数、Cookie等都可以通过Map动态传递,如需连续请求,连续调用同一对象即可,代码也支持自动跳转。

 

工具类源码:

 

/**
 * HttpHandler.java
 * Copyright ® 2012 窦海宁
 * All right reserved
 */

package org.aiyu.core.common.util.net;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.zip.GZIPInputStream;

import org.aiyu.core.common.util.CollectionUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
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.client.protocol.HttpClientContext;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.DefaultRedirectStrategy;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

/**
 * 

Http工具类 * *

Http工具类,为系统提供通用Http访问操作方法: *

*

1、发送GET请求; *

2、发送POST请求。 * * @author 窦海宁, [email protected] * @since AiyuCommonCore-1.0 * @version AiyuCommonCore-1.0 */ public class HttpHandler { //日志对象 private static final Logger logger = Logger.getLogger(HttpHandler.class); private static final String DEFAULT_CHARSET = "UTF-8"; public static final String BODY_KEY = "body"; public static final String REDIRECT_BODY_KEY = "redirect_body"; public static final String HEADER_KEY = "header"; public static final String REDIRECT_HEADER_KEY = "redirect_header"; public static final String COOKIE_KEY = "cookie"; //浏览器Agent public static final String USER_AGENT_FIREFOX = "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"; private String charset = null; //字符编码,默认为UTF-8 private String proxyUrl = null; //代理服务器地址 private int proxyPort = 0; //代理服务器端口号 private int timeout = 0; //请求超时时间 private int cookieVersion = 0; private String cookiePath = null; private String cookieDomain = null; private CookieStore cookieStore = null; private HttpClientContext localContext = null; //本地会话上下文 private CloseableHttpClient httpClient = null; private CloseableHttpResponse httpResponse = null; /** *

默认构造函数 * * @modify 窦海宁, 2017-01-17 */ public HttpHandler() { if (StringUtils.isBlank(this.charset)) { this.charset = HttpHandler.DEFAULT_CHARSET; } } /** *

初始化访问对象 * * @modify 窦海宁, 2017-01-17 */ public void init() { //设置默认的恢复策略,在发生异常时候将自动重试3次,在这里你也可以设置成自定义的恢复策略 HttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(); //配置超时时间(连接服务端超时1秒,请求数据返回超时2秒) RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.DEFAULT).build(); this.cookieStore = new BasicCookieStore(); this.localContext = HttpClientContext.create(); //设置默认跳转以及存储cookie this.httpClient = HttpClientBuilder.create() .setRedirectStrategy(new DefaultRedirectStrategy()) .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) .setRetryHandler(retryHandler).setDefaultRequestConfig(requestConfig).build(); this.localContext.setCookieStore(this.cookieStore); } /** *

关闭访问对象并释放资源 * * @modify 窦海宁, 2017-01-17 */ public void destroy() { if (this.httpClient != null) { try { this.httpClient.close(); } catch (Exception ex) { ex.printStackTrace(); } } System.gc(); } /** *

发送GET请求 * * @param url GET请求地址 * * @return 与当前请求对应的响应内容集合 * * @modify 窦海宁, 2017-01-15 */ public Map doGet(String url) { return this.doGet(url , null , null); } /** *

发送GET请求 * * @param url GET请求地址 * @param headerMap GET请求头参数容器 * @param charset 参数字符集名称 * * @return 与当前请求对应的响应内容集合 * * @modify 窦海宁, 2017-01-15 */ public Map doGet(String url , Map headerMap) { return this.doGet(url , null , null , headerMap); } /** *

发送GET请求 * * @param url GET请求地址 * @param cookieMap POST请求Cookie参数容器 * @param headerMap GET请求头参数容器 * * @return 与当前请求对应的响应内容集合 * * @modify 窦海宁, 2017-01-15 */ public Map doGet(String url , Map cookieMap , Map headerMap) { return this.doGet(url , null , cookieMap , headerMap); } /** *

发送GET请求 * * @param url GET请求地址 * @param queryStringMap 查询字符串参数容器 * @param cookieMap POST请求Cookie参数容器 * @param headerMap GET请求头参数容器 * * @return 与当前请求对应的响应内容容器,包括响应头、响应主体,可通过本类提供的静态常量作为键值提取 * * @modify 窦海宁, 2017-01-15 */ public Map doGet(String url , Map queryStringMap , Map cookieMap , Map headerMap) { Map resultMap = null; try { HttpGet httpGet = new HttpGet(this.createUrl(url , queryStringMap)); Builder configBuilder = RequestConfig.custom(); //设置请求超时时间(毫秒) if (this.timeout > 0) { configBuilder.setSocketTimeout(this.timeout); configBuilder.setConnectTimeout(this.timeout); configBuilder.setConnectionRequestTimeout(this.timeout); } //设置代理 if (StringUtils.isNotBlank(this.proxyUrl)) { HttpHost proxy = new HttpHost(this.proxyUrl , this.proxyPort); configBuilder.setProxy(proxy); } //设置默认Cookie环境 if (StringUtils.isBlank(this.cookiePath)) { this.cookiePath = httpGet.getURI().getPath(); } if (StringUtils.isBlank(this.cookieDomain)) { this.cookieDomain = httpGet.getURI().getHost(); } //设置请求策略 httpGet.setConfig(configBuilder.build()); //设置请求头 this.addHeader(headerMap , httpGet); //设置请求Cookie this.addCookie(cookieMap); this.httpResponse = this.httpClient.execute(httpGet , this.localContext); if (this.httpResponse.getStatusLine().getStatusCode() == 200) { resultMap = new HashMap(); //读取头内容 Map responseHeaderMap = new HashMap(); Header[] headerArray = this.httpResponse.getAllHeaders(); for (int i = 0 ; i < headerArray.length ; i++) { responseHeaderMap.put(headerArray[i].getName() , headerArray[i].getValue()); } resultMap.put(HttpHandler.HEADER_KEY , responseHeaderMap); //读取内容 resultMap.put(HttpHandler.BODY_KEY , this.getBody(this.httpResponse)); } else { System.err.println("Method failed: " + this.httpResponse.getStatusLine()); } EntityUtils.consume(this.httpResponse.getEntity()); this.initCookieEnvironment(); } catch (Exception ex) { ex.printStackTrace(); } finally { this.closeHttpResponse(); } return resultMap; } /** *

发送POST请求(如返回跳转指令,该方法会自动以GET方式跳转) * * @param url POST请求地址 * @param param 请求参数实体对象 * * @return 与当前请求对应的响应内容字节数组 * * @modify 窦海宁, 2017-01-15 */ public Map doPost(String url , Object param) { return this.doPost(url , null , null , null , param); } /** *

发送POST请求(如返回跳转指令,该方法会自动以GET方式跳转) * * @param url POST请求地址 * @param headerMap POST请求头参数容器 * @param param 请求参数实体对象 * * @return 与当前请求对应的响应内容字节数组 * * @modify 窦海宁, 2017-01-15 */ public Map doPost(String url , Map headerMap , Object param) { return this.doPost(url , null , null , headerMap , param); } /** *

发送POST请求(如返回跳转指令,该方法会自动以GET方式跳转) * * @param url POST请求地址 * @param queryStringMap 查询字符串参数容器 * @param headerMap POST请求头参数容器 * @param param 请求参数实体对象 * * @return 与当前请求对应的响应内容容器,包括响应头、响应主体,可通过本类提供的静态常量作为键值提取 * * @modify 窦海宁, 2017-01-15 */ public Map doPost(String url , Map queryStringMap , Map headerMap , Object param) { return this.doPost(url , queryStringMap , null , headerMap , param); } /** *

发送POST请求(如返回跳转指令,该方法会自动以GET方式跳转) * * @param url POST请求地址 * @param queryStringMap 查询字符串参数容器 * @param cookieMap POST请求Cookie参数容器 * @param headerMap POST请求头参数容器 * @param param 请求参数实体对象 * * @return 与当前请求对应的响应内容容器,包括响应头、响应主体,可通过本类提供的静态常量作为键值提取 * * @modify 窦海宁, 2017-01-15 */ public Map doPost(String url , Map queryStringMap , Map cookieMap , Map headerMap , Object param) { Map resultMap = null; String redirectUrl = null; try { HttpPost httpPost = new HttpPost(this.createUrl(url , queryStringMap)); Builder configBuilder = RequestConfig.custom(); //设置请求超时时间(毫秒) if (this.timeout > 0) { configBuilder.setSocketTimeout(this.timeout); configBuilder.setConnectTimeout(this.timeout); configBuilder.setConnectionRequestTimeout(this.timeout); } //设置代理 if (StringUtils.isNotBlank(this.proxyUrl)) { HttpHost proxy = new HttpHost(this.proxyUrl , this.proxyPort); configBuilder.setProxy(proxy); } //设置默认Cookie环境 this.cookiePath = httpPost.getURI().getPath(); this.cookieDomain = httpPost.getURI().getHost(); //设置请求策略 httpPost.setConfig(configBuilder.build()); //设置请求头 this.addHeader(headerMap , httpPost); //设置请求Cookie this.addCookie(cookieMap); //设置请求参数 HttpEntity postEntity = this.addParam(param , httpPost); httpPost.setEntity(postEntity); this.httpResponse = this.httpClient.execute(httpPost , this.localContext); switch (this.httpResponse.getStatusLine().getStatusCode()) { case 301 : case 302 : case 304 : redirectUrl = this.httpResponse.getFirstHeader("Location").getValue(); case 200 : case 500 : resultMap = new HashMap(); //读取头内容 Map responseHeaderMap = new HashMap(); Header[] headerArray = httpPost.getAllHeaders(); for (int i = 0 ; i < headerArray.length ; i++) { responseHeaderMap.put(headerArray[i].getName() , headerArray[i].getValue()); } resultMap.put(HttpHandler.HEADER_KEY , responseHeaderMap); //读取内容 resultMap.put(HttpHandler.BODY_KEY , this.getBody(this.httpResponse)); break; default : System.err.println("Method failed: " + this.httpResponse.getStatusLine()); } EntityUtils.consume(this.httpResponse.getEntity()); } catch (Exception ex) { ex.printStackTrace(); } finally { this.closeHttpResponse(); } if (StringUtils.isNotBlank(redirectUrl)) { if (!StringUtils.startsWith(redirectUrl , "http://")) { redirectUrl = StringUtils.substringBeforeLast(url , "/") + "/" + redirectUrl; } headerMap.put("Referer" , url); Map redirectResultMap = this.doGet(redirectUrl , headerMap); Map redirectHeaderMap = (Map) redirectResultMap.get(HttpHandler.HEADER_KEY); resultMap.put(HttpHandler.REDIRECT_HEADER_KEY , redirectResultMap.get(HttpHandler.HEADER_KEY)); resultMap.put(HttpHandler.REDIRECT_BODY_KEY , redirectResultMap.get(HttpHandler.BODY_KEY)); } return resultMap; } /** *

获取响应内容 * * @param httpResponse 响应对象 * * @return 与当前请求对应的响应内容字节数组 * @throws Exception * * @modify 窦海宁, 2017-01-18 */ private byte[] getBody(HttpResponse httpResponse) throws Exception { byte[] bodyByteArray = null; Header contentEncodingHeader = httpResponse.getFirstHeader("Content-Encoding"); if (contentEncodingHeader != null && StringUtils.indexOf(contentEncodingHeader.getValue().toLowerCase() , "gzip") > -1) { try { //建立gzip解压工作流 bodyByteArray = IOUtils.toByteArray(new GZIPInputStream(httpResponse.getEntity().getContent())); } catch (Exception ex) { ex.printStackTrace(); } } else { try { bodyByteArray = IOUtils.toByteArray(httpResponse.getEntity().getContent()); } catch (IOException ex) { ex.printStackTrace(); } } return bodyByteArray; } /** *

添加查询字符串 * * @param url POST请求地址 * @param queryStringMap 查询字符串参数容器 * * @return 拼装后的查询字符串 * @throws Exception * * @modify 窦海宁, 2015-10-18 */ public String createUrl(String url , Map queryStringMap) throws Exception { StringBuffer queryStringBuffer = new StringBuffer(url); if (CollectionUtil.isNotEmpty(queryStringMap)) { //拼装查询字符串 queryStringBuffer.append("?"); Iterator iterator = queryStringMap.keySet().iterator(); while (iterator.hasNext()) { Object key = iterator.next(); try { key = URLEncoder.encode((String) key , this.charset); String value = null; if (queryStringMap.get(key) == null) { value = ""; } else { value = URLEncoder.encode((String) queryStringMap.get(key) , this.charset); } queryStringBuffer.append(key).append("=").append(value); } catch (UnsupportedEncodingException ex) { ex.printStackTrace(); } if (iterator.hasNext()) { queryStringBuffer.append("&"); } } } return queryStringBuffer.toString(); } /** *

初始化Cookie网络环境(版本号、域名、路径信息,以会话ID变量为样本) * * @modify 窦海宁, 2017-01-17 */ private void initCookieEnvironment() throws Exception { List cookieList = this.cookieStore.getCookies(); for (int i = 0 ; i < cookieList.size() ; i++) { BasicClientCookie cookie = (BasicClientCookie) cookieList.get(i); if (StringUtils.equalsIgnoreCase("JSESSIONID" , cookie.getName())) { this.cookiePath = cookie.getPath(); this.cookieDomain = cookie.getDomain(); this.cookieVersion = cookie.getVersion(); break; } } } /** *

添加请求Cookie * * @param cookieMap 请求Cookie参数容器 * * @modify 窦海宁, 2017-01-17 */ private void addCookie(Map cookieMap) { if (CollectionUtil.isNotEmpty(cookieMap)) { //Cookie请求信息 Iterator iterator = cookieMap.entrySet().iterator(); while (iterator.hasNext()) { Entry entry = (Entry) iterator.next(); BasicClientCookie cookie = new BasicClientCookie(entry.getKey().toString() , entry.getValue().toString()); cookie.setPath(this.cookiePath); cookie.setDomain(this.cookieDomain); cookie.setVersion(this.cookieVersion); this.cookieStore.addCookie(cookie); } this.localContext.setCookieStore(this.cookieStore); } } /** *

添加请求头 * * @param headerMap 请求头参数容器 * @param httpRequest 请求对象 * * @modify 窦海宁, 2017-02-13 */ private void addHeader(Map headerMap , HttpRequest httpRequest) { if (CollectionUtil.isNotEmpty(headerMap)) { //头部请求信息 Iterator iterator = headerMap.entrySet().iterator(); while (iterator.hasNext()) { Entry entry = (Entry) iterator.next(); if (entry.getKey() != null && entry.getValue() != null) { httpRequest.addHeader(entry.getKey().toString() , entry.getValue().toString()); } } httpRequest.addHeader("Charset" , this.charset); } } /** *

添加请求参数 * * @param paramMap 请求参数容器 * @param httpPost Post请求对象 * * @return 添加后的参数列表 * * @modify 窦海宁, 2017-02-13 */ private HttpEntity addParam(Object param , HttpPost httpPost) { HttpEntity postEntity = null; if (param != null) { if (param instanceof String) { postEntity = new StringEntity((String) param , this.charset); } else if (param instanceof Map) { MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create(); multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); // multipartEntityBuilder.setCharset(Charset.forName(this.charset)); Map paramMap = (Map) param; Iterator keyIterator = paramMap.keySet().iterator(); boolean containFile = false; while (keyIterator.hasNext()) { Object key = keyIterator.next(); Object value = paramMap.get(key); if (value instanceof String) { //文本处理 StringBody stringBody = new StringBody((String) value , ContentType.TEXT_PLAIN); multipartEntityBuilder.addPart((String) key , stringBody); } else if (value instanceof File) { //文件处理 FileBody fileBody = new FileBody((File) value); multipartEntityBuilder.addPart((String) key , fileBody); containFile = true; } else { //输出错误信息 } } // if (containFile) { // // multipartEntityBuilder.setContentType(ContentType.MULTIPART_FORM_DATA); // } else { // // multipartEntityBuilder.setContentType(ContentType.APPLICATION_FORM_URLENCODED); // } postEntity = multipartEntityBuilder.build(); } else { HttpHandler.logger.debug("this -> addParam : 请求参数类型不匹配,传入参数类型为 : " + param.getClass().getName()); //此处应抛出异常 } } return postEntity; } /** *

关闭请求对象 * * @modify 窦海宁, 2017-02-06 */ private void closeHttpResponse() { if (this.httpResponse != null) { try { this.httpResponse.close(); } catch (Exception ex) { ex.printStackTrace(); } } } /*对象变量Get、Set方法*/ public void setCharset(String charset) { this.charset = charset; } public void setProxyUrl(String proxyUrl) { this.proxyUrl = proxyUrl; } public void setProxyPort(int proxyPort) { this.proxyPort = proxyPort; } public void setTimeout(int timeout) { this.timeout = timeout; } public void setCookiePath(String cookiePath) { this.cookiePath = cookiePath; } }

  • HttpHandler.rar (4.7 KB)
  • 下载次数: 2

你可能感兴趣的:(java,http,httpclient)