引入依赖
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.12</version>
</dependency>
请求类型枚举
package com.common.enums;
import java.util.Arrays;
/**
* http请求类型 枚举
* @author
* @date 2019-01-08
*/
public enum EHttpContentType {
/**
* application/json
*/
JSON("application/json", "application/json"),
/**
* application/x-www-form-urlencoded
*/
FORM("application/x-www-form-urlencoded", "application/x-www-form-urlencoded"),
/**
* multipart/form-data
*/
FORMDATA("multipart/form-data", "multipart/form-data"),
/**
* application/xml
*/
XML("application/xml", "application/xml");
private String desc;//枚举描述
private String value;//枚举值
public String getValue() {
return value;
}
public String getDesc() {
return desc;
}
/**
* 构造方法
* @param desc 枚举描述
* @param value 枚举值
*/
EHttpContentType(String desc, String value) {
this.desc = desc;
this.value = value;
}
/**
* 根据值获取枚举
*
* @param value 枚举值
* @return
*/
public static EHttpContentType getByValue(String value) {
return Arrays.stream(EHttpContentType.values())
.filter(e -> e.getValue().equals(value))
.findFirst()
.orElse(null);
}
@Override
public String toString() {
return "EHttpContentType{" +
"desc='" + desc + '\'' +
", value=" + value +
'}';
}
}
封装请求工具类
package com.common.util;
import com.common.enums.EHttpContentType;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.config.RequestConfig;
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.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
/**
* Http请求工具类
* @author xiangyuanzhang
* @date 2018-12-25
*/
public final class HttpUtil {
//region 常量
static final String STR_LOGTITLE = "SendHttpRequest";
static final String STR_UTF8 = "utf-8";
private static final int CONNECTTIMEOUT=20000;
//endregion
private HttpUtil() {
throw new IllegalStateException("Utility class");
}
static Boolean isLogRequestContent(EHttpContentType contentType) {
Boolean isLog;
switch (contentType) {
case JSON:
case XML:
case FORM:
isLog = Boolean.TRUE;
break;
default:
isLog = Boolean.FALSE;
break;
}
return isLog;
}
/**
* 获取HttpPost对象
* @param url 请求url
* @param contentType 请求类型(EHttpContentType),默认application/x-www-Form-urlencoded
* @param headers 自定义请求头
* @param proxy http代理(例: http://ntproxy.qa.nt.ctripcorp.com:8080)
* @return
*/
private static HttpPost getHttpPost(String url, String contentType, Map<String, String> headers, String proxy) {
if(StringUtil.isNullOrEmpty(contentType)) {
contentType = EHttpContentType.FORM.getDesc();
}
HttpHost httpProxy = null;
if(StringUtil.isNotNullOrEmpty(proxy)) {
proxy = proxy.replace("https://", "").replace("http://", "");
String[] arrProxy = StringUtil.split(proxy, ":");
httpProxy = new HttpHost(arrProxy[0], Integer.valueOf(arrProxy[1]));
}
//创建httpPost
HttpPost httpPost = new HttpPost(url);
if(!EHttpContentType.FORMDATA.getDesc().equals(contentType)) {
httpPost.setHeader("Content-Type", contentType);
}
RequestConfig config = RequestConfig.custom()
//连接超时
.setConnectionRequestTimeout(Integer.parseInt("60000"))//60 * 1000
//请求超时
.setConnectTimeout(Integer.parseInt("300000"))//5 * 60 * 1000
//读取超时
.setSocketTimeout(Integer.parseInt("10000"))//10 * 1000
.setProxy(httpProxy)
.build();
httpPost.setConfig(config);
if(headers!=null && !headers.isEmpty()) {
for (Map.Entry<String, String> item : headers.entrySet()) {
httpPost.setHeader(item.getKey(), item.getValue());
}
}
return httpPost;
}
/**
* 发起post请求
* @param url 请求url
* @param postData 数据包
* @param contentType 请求类型
* @param headers 自定义header
* @param proxy http代理(例: http://ntproxy.qa.nt.ctripcorp.com:8080)
*/
public static String doPost(String url, HttpEntity postData, EHttpContentType contentType, Map<String, String> headers, String proxy) throws IOException {
String responseContent;
CloseableHttpClient httpclient = HttpClients.custom()
.build();
HttpPost httpPost = HttpUtil.getHttpPost(url, contentType.getDesc(), headers, proxy);
httpPost.setEntity(postData);
CloseableHttpResponse response = null;
Map<String, String> logTags = new HashMap<>();
logTags.put("url", url.toLowerCase());
StringBuilder sbLog = new StringBuilder(HttpUtil.createLog(url, httpPost, contentType, postData));
try {
response = httpclient.execute(httpPost);
sbLog.append(String.format("ResponseTime:%s%n", CalendarUtil.toNowDateTimeMSStr()));
StatusLine status = response.getStatusLine();
int state = status.getStatusCode();
if (state == HttpStatus.SC_OK) {
HttpEntity responseEntity = response.getEntity();
responseContent = EntityUtils.toString(responseEntity);
sbLog.append(String.format("ResponseData:%s%n", responseContent));
sbLog.append(String.format("ResponseDataReadedTime:%s%n", CalendarUtil.toNowDateTimeMSStr()));
}
else{
throw new RuntimeException(url+", the response “HttpStatus” of remote is :"+ state);
}
}
catch (Exception e) {
sbLog.append(String.format("the time at exception happend:%s%n", LocalDateTimeUtil.nowTimeStampStr()));
//TODO log
throw e;
}
finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
//TODO log
}
}
try {
httpclient.close();
} catch (IOException e) {
//TODO log
}
}
//TODO log
return responseContent;
}
static String createLog(String url, HttpPost httpPost, EHttpContentType contentType, HttpEntity postData) {
StringBuilder sbLog = new StringBuilder();
sbLog.append(String.format("url:%s%n", url));
sbLog.append(String.format("Request time:%s%n", CalendarUtil.toNowDateTimeMSStr()));
sbLog.append(String.format("Request method:%s%n", httpPost.getMethod()));
sbLog.append(String.format("ContentType:%s%n", httpPost.getEntity().getContentType()));
HttpHost hProxy = httpPost.getConfig().getProxy();
if(hProxy!=null && StringUtil.isNotNullOrEmpty(hProxy.getHostName())) {
sbLog.append(String.format("used http proxy:%s://%s:%s%n", hProxy.getSchemeName(), hProxy.getHostName(), hProxy.getPort()));
}
if(null!= httpPost.getAllHeaders() && httpPost.getAllHeaders().length>0) {
sbLog.append(String.format("headers:%s%n", SerializeUtil.toJson(httpPost.getAllHeaders())));
}
if(isLogRequestContent(contentType)) {
try {
sbLog.append(String.format("Request body:%s%n", EntityUtils.toString(postData, STR_UTF8)));
} catch (Exception e) {
//
}
} else {
BigDecimal sizeKB = new BigDecimal(postData.getContentLength()).divide(new BigDecimal("1024"));
sbLog.append(String.format("Request body:%s kb.%n", sizeKB.setScale(Integer.parseInt("2"), BigDecimal.ROUND_HALF_UP)));
}
sbLog.append(String.format("Request data readed time:%s%n", CalendarUtil.toNowDateTimeMSStr()));
return sbLog.toString();
}
/**
* 发起post请求
* @param url 请求url
* @param postData 数据包
* @param contentType 请求类型
*/
public static String doPost(String url, byte[] postData, EHttpContentType contentType) throws IOException {
return HttpUtil.doPost(url, postData, contentType, null, null);
}
/**
* 发起post请求
* @param url 请求url
* @param postData 数据包
* @param contentType 请求类型
* @param headers 自定义header
* @param proxy http代理(例: http://ntproxy.qa.nt.ctripcorp.com:8080)
*/
public static String doPost(String url, byte[] postData, EHttpContentType contentType, Map<String, String> headers, String proxy) throws IOException {
HttpEntity entity = new ByteArrayEntity(postData, ContentType.create(contentType.getDesc()));
return HttpUtil.doPost(url, entity, contentType, headers, proxy);
}
/**
* 发起文件上传请求
* @param url 请求url
* @param postData 数据包
* @param fileName 文件名
* @param fileContentType 文件类型
*/
public static String postFile(String url, byte[] postData, String fileName, String fileContentType) throws IOException {
return HttpUtil.postFile(url, postData, fileName, fileContentType, null, null);
}
/**
* 发起文件上传请求
* @param url 请求url
* @param postData 数据包
* @param fileName 文件名
* @param fileContentType 文件类型
* @param headers 自定义header
* @param proxy http代理(例: http://ntproxy.qa.nt.ctripcorp.com:8080)
*/
public static String postFile(String url, byte[] postData, String fileName, String fileContentType, Map<String, String> headers, String proxy) throws IOException {
MultipartEntityBuilder entity = MultipartEntityBuilder.create();
entity.addPart("file", new ByteArrayBody(postData, ContentType.create(fileContentType), fileName));
return HttpUtil.doPost(url, entity.build(), EHttpContentType.FORMDATA, headers, proxy);
}
/**
* 发起post请求
* @param url 请求url
* @param postData 数据包
* @param contentType 请求类型
*/
public static String doPost(String url, String postData, EHttpContentType contentType, Map<String, String> headers) throws IOException {
HttpEntity entity = new StringEntity(postData, STR_UTF8);
return HttpUtil.doPost(url, entity, contentType, headers, null);
}
/**
* 发起post请求
* @param url 请求url
* @param postData 数据包
* @param contentType 请求类型
* @param proxy http代理(例: http://ntproxy.qa.nt.ctripcorp.com:8080)
*/
public static String doPost(String url, String postData, EHttpContentType contentType, Map<String, String> headers, String proxy) throws IOException {
HttpEntity entity = new StringEntity(postData, STR_UTF8);
return HttpUtil.doPost(url, entity, contentType, headers, proxy);
}
/**
* 发起post请求
* @param url 请求url
* @param postData 数据包
* @param contentType 请求类型
*/
public static String doPost(String url, String postData, EHttpContentType contentType) throws IOException {
return HttpUtil.doPost(url, postData, contentType, null);
}
/**
* 以“application/json”方式发起post请求
* @param url 请求url
* @param postData 数据包
* @param headers 自定义header
*/
public static String postJson(String url, Object postData, Map<String, String> headers) throws IOException {
String json = SerializeUtil.toJson(postData);
HttpEntity entity = new StringEntity(json, STR_UTF8);
return HttpUtil.doPost(url, entity, EHttpContentType.JSON, headers, null);
}
/**
* 以“application/json”方式发起post请求
* @param url 请求url
* @param postData 数据包
* @param type 反序列化类型
* @param headers 自定义header
* @param <T> 反序列化对象泛型
*/
public static <T> T postJson(String url, Object postData, Class<T> type, Map<String, String> headers) throws IOException {
return HttpUtil.postJson(url, postData, type, headers, null);
}
/**
* 以“application/json”方式发起post请求
* @param url 请求url
* @param postData 数据包
* @param type 反序列化类型
* @param headers 自定义header
* @param proxy http代理(例: http://ntproxy.qa.nt.ctripcorp.com:8080)
* @param <T> 反序列化对象泛型
*/
public static <T> T postJson(String url, Object postData, Class<T> type, Map<String, String> headers, String proxy) throws IOException {
String json = SerializeUtil.toJson(postData);
HttpEntity entity = new StringEntity(json, STR_UTF8);
String response = doPost(url, entity, EHttpContentType.JSON, headers, proxy);
T result;
try {
result = SerializeUtil.toObject(response, type);
} catch (Exception e) {
result = null;
}
return result;
}
/**
* 从url获取响应流
* @param url 请求url
*/
public static byte[] getStreamByUrl(String url) {
CloseableHttpClient httpclient = HttpClients.custom().setConnectionManagerShared(true).build();
HttpGet httpGet = new HttpGet(url);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(CONNECTTIMEOUT).setConnectTimeout(CONNECTTIMEOUT).build();//设置请求和传输超时时间
httpGet.setConfig(requestConfig);
CloseableHttpResponse response = null;
try {
response = httpclient.execute(httpGet);
int statuscode = response.getStatusLine().getStatusCode();
if (statuscode == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
InputStream isStream = entity.getContent();
return HttpUtil.getBytesFromInputStream(isStream);
}
} catch (Exception e) {
//TODO log
} finally {
if (response != null) {
//TODO log
}
try {
httpclient.close();
} catch (IOException e) {
//TODO log
}
}
return new byte[0];
}
/**
* 从输入流返回字节数组
* @param input 输入流
*/
public static byte[] getBytesFromInputStream(InputStream input) {
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
byte[] buffer = new byte[1024];
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
return output.toByteArray();
} catch (IOException e) {
//TODO log
return new byte[0];
} finally {
try {
output.close();
input.close();
} catch (IOException e) {
//TODO log
}
}
}
/**
* 发起get请求,读取返回流为字符串
* @param url 请求url
* @param charset 读取返回流的字符集
*/
public static String doGet(String url, String charset) throws UnsupportedEncodingException {
byte[] result = HttpUtil.getStreamByUrl(url);
try {
return new String(result, charset);
} catch (UnsupportedEncodingException e) {
try {
return new String(result, STR_UTF8);
} catch (Exception ex) {
throw e;
}
}
}
/**
* 发起get请求,以“utf-8”字符集,读取返回流为字符串
* @param url 请求url
*/
public static String doGet(String url) {
try {
return HttpUtil.doGet(url, STR_UTF8);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e.getMessage());
}
}
/**
* 从url获取响应流
* @param url 请求url
* @param headers 自定义header
* @param proxy 代理地址([http:// | https://]www.baidu.com:8080)
*/
public static byte[] getStream(String url, Map<String, String> headers, String proxy) {
String action = "getStreamByUrl";
Map<String, String> logTags = new HashMap<>();
logTags.put("action", action);
logTags.put("url", url);
HttpHost httpProxy = null;
if(StringUtil.isNotNullOrEmpty(proxy)) {
proxy = proxy.replace("https://", "").replace("http://", "");
String[] arrProxy = StringUtil.split(proxy, ":");
httpProxy = new HttpHost(arrProxy[0], Integer.parseInt(arrProxy[1]));
}
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManagerShared(true)
.build();
HttpGet httpGet = new HttpGet(url);
if(null!=headers) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpGet.setHeader(entry.getKey(), entry.getValue());
}
}
//设置请求和传输超时时间
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(CONNECTTIMEOUT)
.setConnectTimeout(CONNECTTIMEOUT)
.setProxy(httpProxy)
.build();
httpGet.setConfig(requestConfig);
CloseableHttpResponse response = null;
try {
response = httpclient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
InputStream isStream = entity.getContent();
return HttpUtil.getBytesFromInputStream(isStream);
}
} catch (Exception e) {
//TODO log
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
//TODO log
}
}
try {
httpclient.close();
} catch (IOException e) {
//TODO log
}
}
return new byte[0];
}
public static byte[] getStream(String url, Map<String, String> headers) {
return HttpUtil.getStream(url, headers, null);
}
}