• HTTP/HTTPS请求(GET/POST)工具


    package com...util;

    import java.io.IOException;
    import java.nio.charset.Charset;
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.X509Certificate;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.TimeUnit;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpStatus;
    import org.apache.http.NameValuePair;
    import org.apache.http.client.HttpClient;
    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.config.Registry;
    import org.apache.http.config.RegistryBuilder;
    import org.apache.http.config.SocketConfig;
    import org.apache.http.conn.DnsResolver;
    import org.apache.http.conn.HttpConnectionFactory;
    import org.apache.http.conn.ManagedHttpClientConnection;
    import org.apache.http.conn.routing.HttpRoute;
    import org.apache.http.conn.socket.ConnectionSocketFactory;
    import org.apache.http.conn.socket.PlainConnectionSocketFactory;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.impl.DefaultConnectionReuseStrategy;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
    import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
    import org.apache.http.impl.client.HttpClientBuilder;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.impl.conn.DefaultHttpResponseParserFactory;
    import org.apache.http.impl.conn.ManagedHttpClientConnectionFactory;
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    import org.apache.http.impl.conn.SystemDefaultDnsResolver;
    import org.apache.http.impl.io.DefaultHttpRequestWriterFactory;
    import org.apache.http.message.BasicNameValuePair;
    import org.apache.http.util.EntityUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import com.alibaba.fastjson.JSONObject;


    /**
    * Description HTTP/HTTPS请求(GET/POST)工具
    *
    */
    public class HttpClientHelper {

    private static Logger log = LoggerFactory.getLogger(HttpClientHelper.class);

    private static PoolingHttpClientConnectionManager poolConnManager = null;

    private static CloseableHttpClient httpClient =null;

    public static synchronized CloseableHttpClient getHttpClient(){
    if(null==httpClient){
    //注册访问协议相关的Socket工厂
    Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
    .register("http",PlainConnectionSocketFactory.getSocketFactory())
    .register("https", SSLConnectionSocketFactory.getSystemSocketFactory()).build();

    //HttpConnection工厂:皮遏制写请求/解析响应处理器
    HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connectionFactory=new
    ManagedHttpClientConnectionFactory(DefaultHttpRequestWriterFactory.INSTANCE,
    DefaultHttpResponseParserFactory.INSTANCE);
    //DNS解析器
    DnsResolver dnsResolver=SystemDefaultDnsResolver.INSTANCE;

    //创建池化连接管理器
    poolConnManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry,connectionFactory,dnsResolver);
    //默认为Socket配置
    SocketConfig defaultSocketConfig=SocketConfig.custom().setTcpNoDelay(true).build();
    poolConnManager.setDefaultSocketConfig(defaultSocketConfig);

    // 设置整个连接池的最大连接数
    poolConnManager.setMaxTotal(1000);
    // 每个路由的默认最大连接,每个路由实际最大连接默认为DefaultMaxPerRoute控制,maxTotal是整个池子最大数
    // DefaultMaxPerRoute设置过小无法支持大并发(ConnectPoolTimeoutException: Timeout waiting for connect from pool) 路由是maxTotal的细分
    //每个路由最大连接数
    poolConnManager.setDefaultMaxPerRoute(1000);
    //在从连接池获取连接时,连接不活跃多长时间后需要一次验证,默认2S
    poolConnManager.setValidateAfterInactivity(5*1000);

    //默认请求配置
    RequestConfig requestConfig = RequestConfig.custom()
    //设置连接超时时间
    .setConnectTimeout(2*1000)
    //设置等待数据超时时间
    .setSocketTimeout(5*1000)
    //设置从连接池获取连接的等待超时时间
    .setConnectionRequestTimeout(2000)
    .build();

    HttpClientBuilder httpClientBuilder = HttpClients.custom();
    httpClientBuilder.setConnectionManager(poolConnManager)
    //设置连接池不是共享模式
    .setConnectionManagerShared(false)
    //定期回调空闲连接
    .evictIdleConnections(60, TimeUnit.SECONDS)
    //定期回收过期
    .evictExpiredConnections()
    //连接存活时间,如果不设置,根据长连接信息决定
    .setConnectionTimeToLive(60, TimeUnit.SECONDS)
    //设置默认请求配置
    .setDefaultRequestConfig(requestConfig)
    // 连接重试策略,是否能keepalive
    .setConnectionReuseStrategy(DefaultConnectionReuseStrategy.INSTANCE)
    //长连接配置,即获取长连接生产多少时间
    .setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)
    //设置重试次数,默认是3次;当前是禁用
    .setRetryHandler(new DefaultHttpRequestRetryHandler(0, false));

    httpClient = httpClientBuilder.build();

    //JVM停止或重启时,关闭连接池释放连接
    Runtime.getRuntime().addShutdownHook(new Thread(){
    public void run(){
    try{
    httpClient.close();
    }catch(IOException e){
    log.info(e.getMessage());
    }
    }
    });
    }
    return httpClient;
    }


    /**
    * 发送 GET 请求
    *
    * @param url
    * 接口URL
    * @param params
    * 接口参数
    * @param HeaderJson
    * 接口Header参数
    * @return
    */
    public static String doGet(String url, Map<String, Object> params, JSONObject HeaderJson) {
    long a=System.currentTimeMillis();
    String apiUrl = url;
    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;
    String result = null;
    CloseableHttpClient httpClient = getHttpClient();
    httpClient = (CloseableHttpClient) getHttpClients(apiUrl.startsWith("https://")); // https 验证 http地址可去掉
    CloseableHttpResponse response = null;
    HttpGet httpGet = null;

    try {
    httpGet = new HttpGet(apiUrl);

    //Header信息,可去掉
    System.out.println("HeaderJson--->:"+HeaderJson);
    httpGet.addHeader("id", HeaderJson.getString("id"));
    httpGet.addHeader("name", HeaderJson.getString("name"));
    httpGet.addHeader("sign", HeaderJson.getString("sign") );

    httpGet.setHeader("Content-Type", "application/json");
    response = httpClient.execute(httpGet);
    int status = response.getStatusLine().getStatusCode();

    if (status ==HttpStatus.SC_OK) {
    HttpEntity entity = response.getEntity();
    if (entity != null) {
    result = EntityUtils.toString(response.getEntity(), "UTF-8");
    }
    }else{
    //不推荐使用CloseableHttpResponse.close关闭连接,他将直接关闭Socket,导致长连接不能复用
    EntityUtils.consume(response.getEntity());
    }

    StringBuilder logsb=new StringBuilder();
    logsb.append(" ######################################################################## ");
    logsb.append("# 发送报文:"+getPlanText(params)+" ");
    logsb.append("# 响应代码:"+status+" ");
    logsb.append("# 响应报文:"+result+" ");
    logsb.append("# 耗时:"+(System.currentTimeMillis()-a)+" ");
    logsb.append("######################################################################## ");
    log.info(logsb.toString());

    return result;

    } catch (IOException e) {
    try {
    if(null !=response )
    EntityUtils.consume(response.getEntity());
    } catch (IOException e1) {
    log.error(e.getMessage(), e1);
    }
    log.error(e.getMessage(), e);
    }
    return result;
    }


    /**
    * 发送 POST 请求
    * @param url
    * 接口URL
    * @param params
    * 参数map
    * @return
    */
    public static String doPost(String url, Map<String, Object> params) {
    long a=System.currentTimeMillis();
    String result = null;
    HttpPost httpPost = new HttpPost(url);
    CloseableHttpClient httpClient = getHttpClient();
    httpClient = (CloseableHttpClient) getHttpClients(url.startsWith("https://")); // https 验证 http地址可去掉
    CloseableHttpResponse response = null;
    try {
    List<NameValuePair> pairList = new ArrayList<>(params.size());
    for (Map.Entry<String, Object> entry : params.entrySet()) {
    NameValuePair pair = new BasicNameValuePair(entry.getKey(),entry.getValue().toString());
    pairList.add(pair);
    }
    httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8")));
    response = httpClient.execute(httpPost);
    int status = response.getStatusLine().getStatusCode();
    if (status ==HttpStatus.SC_OK) {
    HttpEntity entity = response.getEntity();
    if (entity != null) {
    result = EntityUtils.toString(response.getEntity(), "UTF-8");
    }
    }else{
    //不推荐使用CloseableHttpResponse.close关闭连接,他将直接关闭Socket,导致长连接不能复用
    EntityUtils.consume(response.getEntity());
    }

    StringBuilder logsb=new StringBuilder();
    logsb.append(" ######################################################################## ");
    logsb.append("# 发送报文:"+getPlanText(params)+" ");
    logsb.append("# 响应代码:"+status+" ");
    logsb.append("# 响应报文:"+result+" ");
    logsb.append("# 耗时:"+(System.currentTimeMillis()-a)+" ");
    logsb.append("######################################################################## ");
    log.info(logsb.toString());

    return result;

    } catch (Exception e) {
    try {
    if(null !=response )
    EntityUtils.consume(response.getEntity());
    } catch (IOException e1) {
    log.error(e.getMessage(), e1);
    }
    log.error(e.getMessage(), e);
    }
    return result;
    }

    /**
    * 参数Map格式化
    * @param map
    * @return
    */
    public static String getPlanText(Map<String, Object> map) {
    StringBuilder sb=new StringBuilder();
    for(Map.Entry<String, Object> entry :map.entrySet()){
    sb.append(entry.getKey()).
    append("=").
    append(entry.getValue())
    .append("&");
    }
    if(sb.length()>0){
    sb.deleteCharAt(sb.length()-1);
    }
    return sb.toString();
    }



    private static HttpClient getHttpClients(boolean isHttps) {
    if (isHttps) {
    SSLContext sslContext = createIgnoreVerifySSL();
    Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
    .<ConnectionSocketFactory> create()
    .register("http", PlainConnectionSocketFactory.INSTANCE)
    .register("https",
    new SSLConnectionSocketFactory(sslContext)).build();
    PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(
    socketFactoryRegistry);
    return HttpClients.custom().setConnectionManager(connManager)
    .build();
    } else {
    return HttpClients.createDefault();
    }
    }

    private static SSLContext createIgnoreVerifySSL() {
    try {
    SSLContext sc = SSLContext.getInstance("SSL");
    X509TrustManager trustManager = new X509TrustManager() {
    @Override
    public void checkClientTrusted(
    X509Certificate[] x509Certificates, String paramString) {
    }

    @Override
    public void checkServerTrusted(
    X509Certificate[] x509Certificates, String paramString) {
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
    return null;
    }
    };
    sc.init(null, new TrustManager[] { trustManager }, null);
    return sc;
    } catch (KeyManagementException e) {
    throw new RuntimeException(e);
    } catch (NoSuchAlgorithmException e) {
    throw new RuntimeException(e);
    }
    }

    }

  • 相关阅读:
    Flink学习笔记
    Unable to connect to the server: x509: certificate signed by unknown authority
    network plugin is not ready: cni config uninitialized
    springBoot中文件上传功能Api
    老技术js实现iframe刷新
    JetBrains 里不为人知的秘密(16)Rider添加索引
    C++类的成员变量赋初值问题
    计算两个box的IOU
    C++ error: use of deleted function
    C++模板函数偏特化方法
  • 原文地址:https://www.cnblogs.com/lifan12589/p/13615329.html
Copyright © 2020-2023  润新知