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.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; 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.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.springframework.util.Assert; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.*; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; import java.text.SimpleDateFormat; import java.util.*; @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 EMPTY_HEADERS = new HashMap(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 HttpEntity postJsonRequestV2(String url, HttpEntity reqEntity, Class respBodyClass) { Assert.hasLength(url, "请求url不能为空字符串。"); Assert.notNull(reqEntity, "请求request不能为null。"); Assert.notNull(reqEntity.getBody(), "Post请求body不能为null。"); EntityEnclosingMethod httpMethod = new PostMethod(url); //设置header信息 Map 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 respHeaders = getRespHeaders(httpMethod); //响应体 HttpEntity rep = null; if (isNullOrEmpty(respStr) || null == respBodyClass) { rep = new HttpEntity(respHeaders, null); // 无响应 } else { if (respBodyClass != String.class) { RESPBODY respBody = JSON.parseObject(respStr, respBodyClass); rep = new HttpEntity(respHeaders, respBody); } else { rep = new HttpEntity(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 HttpEntity postJsonRequest(String url, HttpEntity reqEntity, Class respBodyClass) { Assert.hasLength(url, "请求url不能为空字符串。"); Assert.notNull(reqEntity, "请求request不能为null。"); Assert.notNull(reqEntity.getBody(), "Post请求body不能为null。"); EntityEnclosingMethod httpMethod = new PostMethod(url); //设置header信息 Map 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 respHeaders = getRespHeaders(httpMethod); //响应体 HttpEntity rep = null; if (isNullOrEmpty(respStr) || null == respBodyClass) { rep = new HttpEntity(respHeaders, null); ;// 无响应 } else { RESPBODY respBody = JSON.parseObject(respStr, respBodyClass); rep = new HttpEntity(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 url, Map params) 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"); try { // 发送请求参数 StringBuilder param = new StringBuilder(); for (Map.Entry 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 getRespHeaders(HttpMethodBase httpMethod) { //得到响应头 Header[] respHeaders = httpMethod.getResponseHeaders(); Map headers = new HashMap(respHeaders.length); for (Header header : respHeaders) headers.put(header.getName(), header.getValue()); return headers; } protected static void setReqHeaders(Map headers, HttpMethodBase httpMethod) { //设置请求头 for (Map.Entry 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; } }