http请求工具类

package com.template.utils.http;

import cn.hutool.core.map.MapUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
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.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author
 * @Title: HttpsPoolUtil.java
 * @Description: http请求工具类
 * @date
 */
public class HttpsPoolUtil {

  private static Logger log = LoggerFactory.getLogger(HttpsPoolUtil.class);
  private static final String _HTTP = "http";
  private static final String _HTTPS = "https";

  /**
   * 配置连接池获取超时时间
   */
  private static final int CONNECTION_REQUEST_TIMEOUT = 1 * 1000;
  /**
   * 配置客户端连接服务器超时时间
   */
  private static final int CONNECT_TIMEOUT = 3 * 1000;
  /**
   * 配置服务器响应超时时间
   */
  private static final int SOCKET_TIMEOUT = 20 * 1000;
  /**
   * 默认返回null串
   */
  private static String EMPTY_STR = "";

  private static SSLConnectionSocketFactory sslConnectionSocketFactory = null;
  /**
   * 连接池管理类
   */
  private static PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = null;
  /**
   * 管理Https连接的上下文类
   */
  private static SSLContextBuilder sslContextBuilder = null;

  static {
	try {
	  sslContextBuilder = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
		@Override
		public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
		  //忽略http校验
		  return true;
		}
	  });
	  sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), NoopHostnameVerifier.INSTANCE);
	  //注册两种请求形式
	  Registry<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory>create()
			  .register(_HTTP, new PlainConnectionSocketFactory())
			  .register(_HTTPS, sslConnectionSocketFactory).build();
	  poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(registryBuilder);
	  //最大连接数
	  poolingHttpClientConnectionManager.setMaxTotal(500);
	  //最大并发数
	  poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100);
	} catch (NoSuchAlgorithmException e) {
	  e.printStackTrace();
	} catch (KeyStoreException e) {
	  e.printStackTrace();
	} catch (KeyManagementException e) {
	  e.printStackTrace();
	}

  }

  /**
   * @Description: http初始化连接配置
   */
  private static RequestConfig getDefaultRequestConfig() {
	RequestConfig requestConfig = RequestConfig.custom()
			/*
			 * 从连接池中获取连接的超时时间,假设:连接池中已经使用的连接数等于setMaxTotal,新来的线程在等待1*1000
			 * 后超时,错误内容:org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
			 */
			.setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
			/*
			 * 这定义了通过网络与服务器建立连接的超时时间。
			 * Httpclient包中通过一个异步线程去创建与服务器的socket连接,这就是该socket连接的超时时间,
			 * 此处设置为2秒。假设:访问一个IP,192.168.10.100,这个IP不存在或者响应太慢,那么将会返回
			 * java.net.SocketTimeoutException: connect timed out
			 */
			.setConnectTimeout(CONNECT_TIMEOUT)
			/*
			 * 指的是连接上一个url,获取response的返回等待时间,假设:url程序中存在阻塞、或者response
			 * 返回的文件内容太大,在指定的时间内没有读完,则出现
			 * java.net.SocketTimeoutException: Read timed out
			 */
			.setSocketTimeout(SOCKET_TIMEOUT)
			.build();
	return requestConfig;
  }

  /**
   * @Description: http初始化keep-Alive配置
   */
  public static ConnectionKeepAliveStrategy getKeepAliveStrategy() {
	ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() {
	  @Override
	  public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
		HeaderElementIterator it = new BasicHeaderElementIterator
				(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
		while (it.hasNext()) {
		  HeaderElement he = it.nextElement();
		  String param = he.getName();
		  String value = he.getValue();
		  if (value != null && param.equalsIgnoreCase
				  ("timeout")) {
			return Long.parseLong(value) * 1000;
		  }
		}
		//如果没有约定,则默认定义时长为20s
		return 20 * 1000;
	  }
	};
	return myStrategy;
  }

  /**
   * @return
   * @Description: 从池子中获取获取httpclient连接
   */
  public static CloseableHttpClient getHttpClinet() {
	CloseableHttpClient httpClient = HttpClients.custom()
			//设置ssl工厂
			.setSSLSocketFactory(sslConnectionSocketFactory)
			//设置连接管理方式-连接池
			.setConnectionManager(poolingHttpClientConnectionManager)
			//设置http请求规则
			.setDefaultRequestConfig(getDefaultRequestConfig())
			//设置keep-Alive
			.setKeepAliveStrategy(getKeepAliveStrategy())
			.build();
	return httpClient;
  }

  /**
   * @param url
   * @param json
   * @return
   * @Description: post请求——JSON格式
   */
  public static String postJson(String url, String json, Map<String, String> headerMap) {

	HttpPost httpPost = new HttpPost(url);
	if (MapUtil.isNotEmpty(headerMap)) {
	  for (Map.Entry<String, String> entry : headerMap.entrySet()) {
		httpPost.addHeader(new BasicHeader(entry.getKey(), entry.getValue()));
	  }
	}
	//解决中文乱码问题
	StringEntity entity = new StringEntity(json, Consts.UTF_8);
	entity.setContentType("application/json;charset=UTF-8");
	httpPost.setEntity(entity);
	return getResult(httpPost);
  }

  /**
   * @param url
   * @return
   * @Description: post请求——form格式
   * form 为true时  可以传入StringEntity的参数
   */
  public static String postForm(String url, Map<String, String> headerMap, Map<String, String> params) {

	HttpPost httpPost = new HttpPost(url);
	if (MapUtil.isNotEmpty(headerMap)) {
	  for (Map.Entry<String, String> entry : headerMap.entrySet()) {
		httpPost.addHeader(new BasicHeader(entry.getKey(), entry.getValue()));
	  }
	}
	//拼装参数,设置编码格式
	if (MapUtil.isNotEmpty(params)) {
	  List<NameValuePair> paramList = new ArrayList<>();
	  for (Map.Entry<String, String> stringStringEntry : params.entrySet()) {
		paramList.add(new BasicNameValuePair(stringStringEntry.getKey(), stringStringEntry.getValue()));
	  }
	  UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(paramList, Consts.UTF_8);
	  httpPost.setEntity(urlEncodedFormEntity);
	}
	return getResult(httpPost);
  }

  /**
   * 发送http get请求
   *
   * @param url        请求的url
   * @param headersMap 请求头
   * @param params     请求的参数
   * @return
   */
  public static String getRequest(String url, Map<String, String> headersMap, Map<String, Object> params) {
	String apiUrl = url;
	if (null != params && params.size() > 0) {
	  StringBuffer param = new StringBuffer();
	  int i = 0;
	  for (String key : params.keySet()) {
		if (i == 0) {
		  param.append("?");
		} else {
		  param.append("&");
		}
		param.append(key).append("=").append(params.get(key));
		i++;
	  }
	  apiUrl += param;
	}
	HttpGet httpGet = new HttpGet(apiUrl);
	if (MapUtil.isNotEmpty(headersMap)) {
	  for (Map.Entry<String, String> entry : headersMap.entrySet()) {
		httpGet.addHeader(new BasicHeader(entry.getKey(), entry.getValue()));
	  }
	}
	return getResult(httpGet);
  }

  /**
   * @param request
   * @return
   * @Description: 通用版处理http请求
   */
  private static String getResult(HttpRequestBase request) {

	/**
	 * 获取httpClient
	 */
	CloseableHttpClient httpClient = null;
	try {
	  //获取httpClient
	  httpClient = getHttpClinet();
	} catch (Exception e) {
	  log.error("【新版http】获取httpClient失败:请求地址:{},异常信息:", request.getURI(), e);
	  throw new RuntimeException("获取httpClient失败");
	}
	/**
	 * 发起http请求,并处理响应结果
	 */
	String resultStr = null;
	CloseableHttpResponse httpResponse = null;
	try {
	  //发起http请求
	  httpResponse = httpClient.execute(request);
	  int statusCode = httpResponse.getStatusLine().getStatusCode();
	  //响应成功
	  if (statusCode == HttpStatus.SC_OK) {
		HttpEntity httpResponseEntity = httpResponse.getEntity();
		resultStr = EntityUtils.toString(httpResponseEntity,Consts.UTF_8);
		log.info("【新版http】请求正常,请求地址:{},响应结果:{}", request.getURI(), resultStr);
		return resultStr;
	  }
	  //响应失败,打印http异常信息
	  StringBuffer stringBuffer = new StringBuffer();
	  HeaderIterator headerIterator = httpResponse.headerIterator();
	  while (headerIterator.hasNext()) {
		stringBuffer.append("\t" + headerIterator.next());
	  }
	  log.info("【新版http】异常信息:请求地址:{},响应状态:{},请求返回结果:{}", request.getURI(), statusCode, stringBuffer);
	} catch (Exception e) {
	  log.error("【新版http】发生异常:请求地址:{},异常信息:", request.getURI(), e);
	  throw new RuntimeException("http请求失败");
	} finally {
	  //关闭httpResponse
	  if (httpResponse != null) {
		try {
		  httpResponse.close();
		} catch (IOException e) {
		  e.printStackTrace();
		}
	  }
	}
	return EMPTY_STR;
  }

  public static void main(String[] args) {
	String url = "https://www.baidu.com";
	String s = postForm(url, null, null);
//	String s = HttpUtils.getRequest(url);
	System.out.println(s);
  }


}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值