package com.lunhan.xxx.common.util;
|
|
import com.lunhan.xxx.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);
|
}
|
}
|