package com.ruoyi.common.utils;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import com.github.pagehelper.util.StringUtil;
|
import com.ruoyi.common.exception.HttpRequestException;
|
import com.ruoyi.common.utils.http.HttpEntity;
|
import com.ruoyi.common.utils.json.JsonRequestBody;
|
import com.ruoyi.common.utils.json.JsonResponseBody;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.codec.Charsets;
|
import org.apache.commons.httpclient.*;
|
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
|
import org.apache.commons.httpclient.methods.PostMethod;
|
import org.apache.commons.httpclient.methods.RequestEntity;
|
import org.apache.commons.httpclient.methods.StringRequestEntity;
|
import org.apache.commons.httpclient.params.HttpClientParams;
|
import org.springframework.util.Assert;
|
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
|
import java.io.*;
|
import java.net.HttpURLConnection;
|
import java.net.URL;
|
import java.net.URLEncoder;
|
import java.nio.charset.Charset;
|
import java.nio.charset.StandardCharsets;
|
import java.text.SimpleDateFormat;
|
import java.util.HashMap;
|
import java.util.Locale;
|
import java.util.Map;
|
|
@Slf4j
|
public class HttpUtil {
|
|
protected static final int DEFAULT_STATUS_ERROR_CODE = 100001;//默认http异常状态码
|
|
protected static final String CONTENT_TYPE = "Content-Type";
|
|
protected static final String APPLICATION_JSON = "application/json";
|
protected static final String APPLICATION_JSON_UTF8 = "application/json; charset=utf-8";
|
|
protected static final String TEXT_XML = "text/xml";
|
protected static final String TEXT_XML_UTF8 = "text/xml; charset=utf-8";
|
|
protected static final int OK = 200;
|
|
|
/**
|
* 空的报文头
|
*/
|
protected static final Map<String, String> EMPTY_HEADERS = new HashMap<String, String>(0);
|
/**
|
* 编码错误
|
*/
|
protected static final int ENCODING_ERROR_CODE = 999997;
|
/**
|
* HTTP 错误: 死锁、文件过大等文件
|
*/
|
protected static final int HTTP_ERROR_CODE = 999996;
|
/**
|
* IO 错误
|
*/
|
protected static final int IO_ERROR_CODE = 999995;
|
/**
|
* 响应为null
|
*/
|
protected static final int RESPONSE_NULL_ERROR_CODE = 999994;
|
|
protected static final String USER_IP_KEY = "x-remoteip";
|
|
protected static final String TEXT_NORMAL = "application/x-www-form-urlencoded; charset=utf-8";
|
protected static final HttpClient httpClient = getHttpClient();
|
|
private static final SimpleDateFormat formatHttpData = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
|
|
|
private static HttpClient getHttpClient() {
|
// 此处运用连接池技术。
|
MultiThreadedHttpConnectionManager manager = new MultiThreadedHttpConnectionManager();
|
|
// 设定参数:与每个主机的最大连接数
|
manager.getParams().setDefaultMaxConnectionsPerHost(100);
|
// 设定参数:客户端的总连接数
|
manager.getParams().setMaxTotalConnections(400);
|
// 设置连接超时时间,单位:毫秒
|
manager.getParams().setConnectionTimeout(30000);
|
// 设置请求读取超时时间,单位:毫秒
|
manager.getParams().setSoTimeout(30000);
|
// 设置从连接池中获取链接时间, 单位:毫秒
|
manager.getParams().setParameter(HttpClientParams.CONNECTION_MANAGER_TIMEOUT, 8000);
|
// 使用连接池技术创建HttpClient对象
|
HttpClient httpClient = new HttpClient(manager);
|
|
return httpClient;
|
}
|
|
public static String postJsonRequest(String url, String request) throws HttpRequestException {
|
Assert.hasLength(url, "请求url不能为空字符串。");
|
EntityEnclosingMethod httpMethod = new PostMethod(url);
|
|
httpMethod.addRequestHeader("Content-Type", "application/json; charset=UTF-8");
|
setHeaderRequestId(httpMethod);
|
try {
|
RequestEntity entity = new StringRequestEntity(request, "application/json", "utf-8");
|
httpMethod.setRequestEntity(entity);
|
|
int resultCode = httpClient.executeMethod(httpMethod);
|
InputStream inputStream = httpMethod.getResponseBodyAsStream();
|
if (inputStream == null) {
|
throw new HttpRequestException(RESPONSE_NULL_ERROR_CODE, "响应为null");
|
}
|
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
StringBuffer stringBuffer = new StringBuffer();
|
String str = "";
|
while ((str = reader.readLine()) != null) {
|
stringBuffer.append(str);
|
}
|
reader.close();
|
String respJson = stringBuffer.toString();
|
// String respJson = httpMethod.getResponseBodyAsString();
|
if (resultCode == OK) {
|
return respJson;
|
} else {
|
throw new HttpRequestException(resultCode, respJson);
|
}
|
} catch (UnsupportedEncodingException e) {
|
throw new HttpRequestException(ENCODING_ERROR_CODE, e);
|
} catch (HttpException e) {
|
throw new HttpRequestException(HTTP_ERROR_CODE, e);
|
} catch (IOException e) {
|
throw new HttpRequestException(IO_ERROR_CODE, e);
|
} finally {
|
if (httpMethod != null) {
|
httpMethod.releaseConnection();
|
}
|
}
|
}
|
|
/**
|
* json的post请求
|
*
|
* @param url 请求url
|
* @param reqEntity 请求头与请求体的封装
|
* @param respBodyClass 响应体类型
|
* @return 返回的响应结果
|
*/
|
@SuppressWarnings("unchecked")
|
public static <RESPBODY> HttpEntity<RESPBODY> postJsonRequestV2(String url, HttpEntity<?> reqEntity, Class<RESPBODY> respBodyClass) {
|
Assert.hasLength(url, "请求url不能为空字符串。");
|
Assert.notNull(reqEntity, "请求request不能为null。");
|
Assert.notNull(reqEntity.getBody(), "Post请求body不能为null。");
|
|
EntityEnclosingMethod httpMethod = new PostMethod(url);
|
//设置header信息
|
Map<String, String> headers = reqEntity.getHeaders();
|
//若传入报文头,则设置值
|
if (headers != HttpEntity.EMPTY_HEADERS) {
|
setReqHeaders(headers, httpMethod);
|
}
|
|
//设置body信息
|
String reqJson = JSON.toJSONString(reqEntity.getBody());
|
|
String charset = com.google.common.base.Charsets.UTF_8.name();
|
// 发送含xml消息体的对象
|
try {
|
RequestEntity entity = new StringRequestEntity(reqJson, APPLICATION_JSON, charset);
|
httpMethod.setRequestEntity(entity);
|
|
// 执行请求并接收响应码
|
int resultCode = httpClient.executeMethod(httpMethod);
|
InputStream inputStream = httpMethod.getResponseBodyAsStream();
|
if (inputStream == null) {
|
throw new HttpRequestException(RESPONSE_NULL_ERROR_CODE, "响应为null");
|
}
|
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("GB2312")));
|
StringBuffer stringBuffer = new StringBuffer();
|
String str = "";
|
while ((str = reader.readLine()) != null) {
|
stringBuffer.append(str);
|
}
|
reader.close();
|
String respStr = stringBuffer.toString();
|
//String respStr = httpMethod.getResponseBodyAsString();
|
if (resultCode == OK) {
|
//响应头
|
Map<String, String> respHeaders = getRespHeaders(httpMethod);
|
//响应体
|
HttpEntity<RESPBODY> rep = null;
|
if (isNullOrEmpty(respStr) || null == respBodyClass) {
|
rep = new HttpEntity<RESPBODY>(respHeaders, null);
|
// 无响应
|
} else {
|
if (respBodyClass != String.class) {
|
RESPBODY respBody = JSON.parseObject(respStr, respBodyClass);
|
rep = new HttpEntity<RESPBODY>(respHeaders, respBody);
|
} else {
|
rep = new HttpEntity<RESPBODY>(respHeaders, (RESPBODY) new String(respStr.getBytes("ISO8859-1"), StandardCharsets.UTF_8));
|
}
|
}
|
return rep;
|
} else if (resultCode == DEFAULT_STATUS_ERROR_CODE) {
|
JSONObject model = JSON.parseObject(respStr);
|
throw new HttpRequestException(model.getIntValue("code"), model.getString("msg"));
|
} else {
|
throw new HttpRequestException(resultCode, respStr);
|
}
|
} catch (UnsupportedEncodingException e) {
|
throw new HttpRequestException(ENCODING_ERROR_CODE, e);
|
} catch (HttpException e) {
|
throw new HttpRequestException(HTTP_ERROR_CODE, e);
|
} catch (IOException e) {
|
throw new HttpRequestException(IO_ERROR_CODE, e);
|
} finally {
|
if (httpMethod != null) {
|
httpMethod.releaseConnection();
|
}
|
}
|
}
|
|
public static <RESPBODY extends JsonResponseBody> HttpEntity<RESPBODY> postJsonRequest(String url, HttpEntity<? extends JsonRequestBody> reqEntity, Class<RESPBODY> respBodyClass) {
|
Assert.hasLength(url, "请求url不能为空字符串。");
|
Assert.notNull(reqEntity, "请求request不能为null。");
|
Assert.notNull(reqEntity.getBody(), "Post请求body不能为null。");
|
|
EntityEnclosingMethod httpMethod = new PostMethod(url);
|
//设置header信息
|
Map<String, String> headers = reqEntity.getHeaders();
|
//若传入报文头,则设置值
|
if (headers != HttpEntity.EMPTY_HEADERS) {
|
setReqHeaders(headers, httpMethod);
|
}
|
|
//设置body信息
|
String reqJson = JSON.toJSONString(reqEntity.getBody());
|
|
String charset = Charsets.UTF_8.name();
|
// 发送含xml消息体的对象
|
try {
|
RequestEntity entity = new StringRequestEntity(reqJson, APPLICATION_JSON, charset);
|
httpMethod.setRequestEntity(entity);
|
|
// 执行请求并接收响应码
|
int resultCode = httpClient.executeMethod(httpMethod);
|
InputStream inputStream = httpMethod.getResponseBodyAsStream();
|
if (inputStream == null) {
|
throw new HttpRequestException(RESPONSE_NULL_ERROR_CODE, "响应为null");
|
}
|
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
StringBuffer stringBuffer = new StringBuffer();
|
String str = "";
|
while ((str = reader.readLine()) != null) {
|
stringBuffer.append(str);
|
}
|
reader.close();
|
String respStr = stringBuffer.toString();
|
if (resultCode == OK) {
|
//响应头
|
Map<String, String> respHeaders = getRespHeaders(httpMethod);
|
//响应体
|
HttpEntity<RESPBODY> rep = null;
|
if (isNullOrEmpty(respStr) || null == respBodyClass) {
|
rep = new HttpEntity<RESPBODY>(respHeaders, null);
|
;// 无响应
|
} else {
|
RESPBODY respBody = JSON.parseObject(respStr, respBodyClass);
|
rep = new HttpEntity<RESPBODY>(respHeaders, respBody);
|
}
|
return rep;
|
} else if (resultCode == DEFAULT_STATUS_ERROR_CODE) {
|
JSONObject model = JSON.parseObject(respStr);
|
throw new HttpRequestException(model.getIntValue("code"), model.getString("msg"));
|
} else {
|
throw new HttpRequestException(resultCode, respStr);
|
}
|
} catch (UnsupportedEncodingException e) {
|
throw new HttpRequestException(ENCODING_ERROR_CODE, e);
|
} catch (HttpException e) {
|
throw new HttpRequestException(HTTP_ERROR_CODE, e);
|
} catch (IOException e) {
|
throw new HttpRequestException(IO_ERROR_CODE, e);
|
} finally {
|
if (httpMethod != null) {
|
httpMethod.releaseConnection();
|
}
|
}
|
}
|
|
public static String postFormRequest(String baseUrl, Map<String, String> params, Map<String, String> headers, String body) {
|
HttpURLConnection connection = null;
|
BufferedReader reader = null;
|
|
try {
|
// 构建完整的URL(包含查询参数)
|
String fullUrl = buildUrlWithParams(baseUrl, params);
|
URL requestUrl = new URL(fullUrl);
|
connection = (HttpURLConnection) requestUrl.openConnection();
|
|
// 设置请求方法
|
connection.setRequestMethod("POST");
|
connection.setDoOutput(true);
|
connection.setDoInput(true);
|
connection.setUseCaches(false);
|
|
// 设置请求头
|
if (headers != null) {
|
for (Map.Entry<String, String> entry : headers.entrySet()) {
|
connection.setRequestProperty(entry.getKey(), entry.getValue());
|
}
|
}
|
|
// 设置默认的Content-Type
|
if (!connection.getRequestProperties().containsKey("Content-Type")) {
|
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
|
}
|
|
// 如果有请求体,写入数据
|
if (body != null && !body.isEmpty()) {
|
try (OutputStream os = connection.getOutputStream()) {
|
byte[] input = body.getBytes(StandardCharsets.UTF_8);
|
os.write(input, 0, input.length);
|
}
|
}
|
|
// 获取响应码
|
int responseCode = connection.getResponseCode();
|
|
// 读取响应
|
StringBuilder response = new StringBuilder();
|
if (responseCode == HttpURLConnection.HTTP_OK) {
|
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
} else {
|
reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
|
}
|
|
String line;
|
while ((line = reader.readLine()) != null) {
|
response.append(line);
|
}
|
|
return response.toString();
|
|
} catch (Exception e) {
|
throw new RuntimeException("POST请求失败: " + e.getMessage(), e);
|
} finally {
|
// 关闭连接
|
if (reader != null) {
|
try {
|
reader.close();
|
} catch (Exception e) { /* ignore */ }
|
}
|
if (connection != null) {
|
connection.disconnect();
|
}
|
}
|
}
|
|
private static String buildUrlWithParams(String baseUrl, Map<String, String> params) {
|
if (params == null || params.isEmpty()) {
|
return baseUrl;
|
}
|
|
StringBuilder urlBuilder = new StringBuilder(baseUrl);
|
boolean firstParam = true;
|
|
for (Map.Entry<String, String> entry : params.entrySet()) {
|
if (firstParam) {
|
urlBuilder.append("?");
|
firstParam = false;
|
} else {
|
urlBuilder.append("&");
|
}
|
|
try {
|
urlBuilder.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8.toString())).append("=").append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8.toString()));
|
} catch (UnsupportedEncodingException e) {
|
e.printStackTrace();
|
}
|
}
|
|
return urlBuilder.toString();
|
}
|
// public static String postFormRequest(String url, Map<String, String> params,Map<String, String> headers) throws HttpRequestException {
|
// Assert.hasLength(url, "请求url不能为空字符串。");
|
// Assert.notNull(params, "请求params不能为空。");
|
//
|
// PostMethod httpMethod = new PostMethod(url);
|
//
|
// httpMethod.addRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
|
//
|
// if(!ObjectUtils.isEmpty(headers)) {
|
// httpMethod.addRequestHeader(headers.get(), "application/json");
|
// }
|
//
|
// try {
|
// // 发送请求参数
|
// StringBuilder param = new StringBuilder();
|
// for (Map.Entry<String, String> entry : params.entrySet()) {
|
// if (param.length() > 0) {
|
// param.append("&");
|
// }
|
// param.append(entry.getKey());
|
// param.append("=");
|
// param.append(entry.getValue());
|
// }
|
//
|
// RequestEntity entity = new StringRequestEntity(param.toString(), "application/json", "utf-8");
|
// httpMethod.setRequestEntity(entity);
|
// // 执行请求并接收响应码
|
// int resultCode = httpClient.executeMethod(httpMethod);
|
//
|
// String respJson = httpMethod.getResponseBodyAsString();
|
// if (resultCode == OK) {
|
// return respJson;
|
// } else {
|
// throw new HttpRequestException(resultCode, respJson);
|
// }
|
// } catch (UnsupportedEncodingException e) {
|
// throw new HttpRequestException(ENCODING_ERROR_CODE, e);
|
// } catch (HttpException e) {
|
// throw new HttpRequestException(HTTP_ERROR_CODE, e);
|
// } catch (IOException e) {
|
// throw new HttpRequestException(IO_ERROR_CODE, e);
|
// } finally {
|
// if (httpMethod != null) {
|
// httpMethod.releaseConnection();
|
// }
|
// }
|
// }
|
|
|
private static Map<String, String> getRespHeaders(HttpMethodBase httpMethod) {
|
//得到响应头
|
Header[] respHeaders = httpMethod.getResponseHeaders();
|
Map<String, String> headers = new HashMap<String, String>(respHeaders.length);
|
for (Header header : respHeaders)
|
headers.put(header.getName(), header.getValue());
|
return headers;
|
}
|
|
protected static void setReqHeaders(Map<String, String> headers, HttpMethodBase httpMethod) {
|
//设置请求头
|
for (Map.Entry<String, String> header : headers.entrySet()) {
|
httpMethod.addRequestHeader(header.getKey(), header.getValue());
|
}
|
}
|
|
protected static void setHeaderRequestId(HttpMethodBase httpMethod) {
|
//设置请求头
|
ServletRequestAttributes req = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
if (null != req) {
|
String requestId = req.getRequest().getHeader("x-request-id");
|
if (StringUtil.isNotEmpty(requestId)) {
|
httpMethod.addRequestHeader("x-request-id", requestId);
|
log.info("header中x-request-id值为:{}", requestId);
|
}
|
}
|
}
|
|
private static boolean isNullOrEmpty(String obj) {
|
if (obj == null || obj.isEmpty()) {
|
return true;
|
}
|
return false;
|
}
|
}
|