apache --- HttpClientUtils工具类

这篇文章详细介绍了如何在Java项目中使用ApacheHttpClient库进行HTTPGET和POST请求,包括配置连接池、设置请求参数、处理URL编码以及管理连接生命周期。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

maven依赖

<dependency>
     <groupId>org.apache.httpcomponents</groupId>
     <artifactId>httpclient</artifactId>
     <version>4.5.13</version>
</dependency>
package com.demo.utils;

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
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.utils.URIBuilder;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
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.entity.ContentType;
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.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Description: httpclient工具类
 */
@Slf4j
public class HttpClientUtils {
    private static final int MAX_TOTAL = 400;
    private static final int MAX_PER_ROUTE = 100;
    private static final int SOCKET_TIMEOUT = 30000;
    private static final int CONNECT_TIMEOUT = 10000;
    private static final int CONNECTION_REQUEST_TIMEOUT = 1000;
    private static final int CLOSE_IDLE_CONNECTIONS = 5;
    private static final int SCHEDULE_FIXED_RATE = 1;
    private static final int TIME_TO_LIVE = 60;

    private static final PoolingHttpClientConnectionManager CONNECTION_MANAGER;
    private static final RequestConfig REQUEST_CONFIG;
    private static final CloseableHttpClient HTTP_CLIENT;
    private static final ScheduledExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadScheduledExecutor();

    static {
    	// 每个版本不一样,请根据具体版本进行设置
        // 忽略https证书
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
                .build();
        // 设置连接的生存时间为TIME_TO_LIVE秒
        CONNECTION_MANAGER = new PoolingHttpClientConnectionManager(registry,
                null, null, null, TIME_TO_LIVE, TimeUnit.SECONDS);
        // 设置整个连接池最大连接数
        CONNECTION_MANAGER.setMaxTotal(MAX_TOTAL);
        // 路由是对maxTotal的细分
        CONNECTION_MANAGER.setDefaultMaxPerRoute(MAX_PER_ROUTE);

        REQUEST_CONFIG = RequestConfig.custom()
                // 返回数据的超时时间,单位:毫秒
                .setSocketTimeout(SOCKET_TIMEOUT)
                // 连接上服务器的超时时间,单位:毫秒
                .setConnectTimeout(CONNECT_TIMEOUT)
                // 从连接池中获取连接的超时时间,单位:毫秒
                .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
                .build();

        HTTP_CLIENT = HttpClients.custom()
                .setConnectionManager(CONNECTION_MANAGER)
                .setDefaultRequestConfig(REQUEST_CONFIG)
                // 配置连接池管理器定期清理过期和空闲连接   与 EXECUTOR_SERVICE二选一
                // 以下配置在高版本才有,低版本无此方法;高版本使用此配置,低版本使用EXECUTOR_SERVICE
                // .evictExpiredConnections()
                // .evictIdleConnections(CLOSE_IDLE_CONNECTIONS, TimeUnit.SECONDS)
                .build();

        // 每分钟执行1次,定时清理无效链接
        EXECUTOR_SERVICE.scheduleAtFixedRate(() -> {
            try {
                // 关闭异常连接
                CONNECTION_MANAGER.closeExpiredConnections();
            } catch (Exception e) {
                log.error("==>HttpPool关闭异常连接失败", e);
            }
            try {
                // 关闭5s空闲的连接
                CONNECTION_MANAGER.closeIdleConnections(CLOSE_IDLE_CONNECTIONS, TimeUnit.SECONDS);
            } catch (Exception e) {
                log.error("==>HttpPool关闭5s空闲的连接失败", e);
            }

            log.info("==>HttpPool清理无效链接成功");
        }, SCHEDULE_FIXED_RATE, SCHEDULE_FIXED_RATE, TimeUnit.MINUTES);

        // 注册关闭钩子,程序结束时释放资源
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            log.info("==>Application is shutting down, free up resources...");
            log.info("==>closing scheduled executor service...");
            try {
                // 关闭线程池,不再接收新任务
                EXECUTOR_SERVICE.shutdown();
                // 等待已经提交的任务完成
                if (!EXECUTOR_SERVICE.awaitTermination(SCHEDULE_FIXED_RATE, TimeUnit.MINUTES)) {
                    // 取消当前未完成的任务
                    EXECUTOR_SERVICE.shutdownNow();
                    log.warn("==>Pool did not terminate after {} minutes", SCHEDULE_FIXED_RATE);
                }
            } catch (InterruptedException ie) {
                // (Re-)Cancel if current thread also interrupted
                EXECUTOR_SERVICE.shutdownNow();
                // Preserve interrupt status
                Thread.currentThread().interrupt();
                log.warn("==>Interrupted while waiting for pool to terminate", ie);
            }

            log.info("==>closing http client...");
            try {
                if (HTTP_CLIENT != null) {
                    HTTP_CLIENT.close();
                }
            } catch (IOException e) {
                log.warn("==>closing http client error", e);
            }
            log.info("==>free up resources end。");
        }));
    }

    public static String doGet(String url, Map<String, String> params, Map<String, String> headers) {
        try {
            URIBuilder builder = new URIBuilder(url);
            if (MapUtils.isNotEmpty(params)) {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    builder.addParameter(entry.getKey(), entry.getValue());
                }
            }

            HttpGet httpGet = new HttpGet(builder.build());
            if (MapUtils.isNotEmpty(headers)) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpGet.setHeader(entry.getKey(), entry.getValue());
                }
            }
            httpGet.setHeader("Content-Type", ContentType.APPLICATION_JSON.toString());

            try (CloseableHttpResponse response = HTTP_CLIENT.execute(httpGet)) {
                String responseContent = StringUtils.EMPTY;
                if (response.getEntity() != null) {
                    responseContent = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
                }
                log.info("==>HttpPool doGet请求成功,url:{},response:{}", url, responseContent);
                return responseContent;
            }
        } catch (Exception e) {
            log.error("==>HttpPool doGet请求失败,url:{}", url, e);
            return null;
        }
    }

    public static String doPostForm(String url, Map<String, String> params, Map<String, String> headers) {
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");

            if (MapUtils.isNotEmpty(params)) {
                List<NameValuePair> paramList = Lists.newArrayList();
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    paramList.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
                httpPost.setEntity(new UrlEncodedFormEntity(paramList, StandardCharsets.UTF_8));
            }

            if (MapUtils.isNotEmpty(headers)) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.setHeader(entry.getKey(), entry.getValue());
                }
            }

            try (CloseableHttpResponse response = HTTP_CLIENT.execute(httpPost)) {
                String responseContent = StringUtils.EMPTY;
                if (response.getEntity() != null) {
                    responseContent = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
                }
                log.info("==>HttpPool doPostForm请求成功,url:{},response:{}", url, responseContent);
                return responseContent;
            }
        } catch (Exception e) {
            log.error("==>HttpPool doPostForm请求失败,url:{}", url, e);
            return null;
        }
    }

    public static String doPostJson(String url, String paramJson, Map<String, String> headers) {
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", ContentType.APPLICATION_JSON.toString());

            if (MapUtils.isNotEmpty(headers)) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.setHeader(entry.getKey(), entry.getValue());
                }
            }

            if (StringUtils.isNotBlank(paramJson)) {
                httpPost.setEntity(new StringEntity(paramJson, ContentType.APPLICATION_JSON));
            }

            try (CloseableHttpResponse response = HTTP_CLIENT.execute(httpPost)) {
                String responseContent = StringUtils.EMPTY;
                if (response.getEntity() != null) {
                    responseContent = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
                }
                log.info("==>HttpPool doPostJson请求成功,url:{},response:{}", url, responseContent);
                return responseContent;
            }
        } catch (Exception e) {
            log.error("==>HttpPool doPostJson请求失败,url:{}", url, e);
            return null;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值