httpclient连接池释放异常和多余资源

本文介绍了一个用于监控HTTP请求的实用工具类,支持GET和POST请求,并具备异常链接监控功能。该工具使用了Apache HttpClient进行HTTP通信,提供了丰富的配置选项如连接池大小、超时设置等。

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

请求、异常链接监控代码如下:

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
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.conn.HttpClientConnectionManager;
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.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;


 public class HttpUtil {
        private final CloseableHttpClient httpclient;
        private static final int SIZE = 1024 * 1024;

        private static final Charset CHARSET_UTF8 = Charset.forName("UTF-8");

        private static class HttpUtilHolder {
            private static final HttpUtil INSTANCE = new HttpUtil();
        }

        public static HttpUtil getIntance() {
            return HttpUtilHolder.INSTANCE;
        }

        private HttpUtil() {
            PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
            // 将最大连接数增加到300
            cm.setMaxTotal(300);
            // 将每个路由基础的连接增加到100
            cm.setDefaultMaxPerRoute(100);
            // 链接超时setConnectTimeout ,读取超时setSocketTimeout
            RequestConfig defaultRequestConfig;
            defaultRequestConfig = RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(3000).build();

            httpclient = HttpClients.custom().setConnectionManager(cm)
                    .setDefaultRequestConfig(defaultRequestConfig)
                    .setRetryHandler(new DefaultHttpRequestRetryHandler())
                    .build();

            new IdleConnectionMonitorThread(cm).start();
        }

        /**
         * 编码默认UTF-8
         *
         * @param url
         * @return
         */
        public String get(String url) {
            return this.get(url, CHARSET_UTF8.toString());
        }

        /**
         * @param url
         * @param params 请求参数
         * @return
         * @throws Exception
         */
        public String get(String url, Map<String, Object> params) {
            if (params != null) {
                String paramStr = "";
                for (String key : params.keySet()) {
                    if (!paramStr.isEmpty()) {
                        paramStr += '&';
                    }
                    if (null == params.get(key)) {
                        paramStr += key + '=';
                    } else {
                        try {
                            paramStr += key + '=' + URLEncoder.encode(params.get(key) + "", CHARSET_UTF8.toString());
                        } catch (UnsupportedEncodingException e) {
                            logger.error("key=" + key + "," + params.get(key) + " 错误", e);
                        }
                    }
                }

                if (url.indexOf('?') > 0) {
                    url += '&' + paramStr;
                } else {
                    url += '?' + paramStr;
                }
            }
            return this.get(url, CHARSET_UTF8.toString());
        }

        /**
         * @param url
         * @param code
         * @return
         */
        public String get(String url, final String code) {
            String res = null;

            try {
                HttpGet httpget = new HttpGet(url);
                ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
                    @Override
                    public String handleResponse(final HttpResponse response) throws ClientProtocolException, IOException {
                        int status = response.getStatusLine().getStatusCode();
                        if (status >= 200 && status < 300) {
                            HttpEntity entity = response.getEntity();
                            return entity != null ? EntityUtils.toString(entity, code) : null;
                        } else {
                            throw new ClientProtocolException("Unexpected response status: " + status);
                        }
                    }

                };
                res = httpclient.execute(httpget, responseHandler);
                logApiStauts(true);
            } catch (Exception e) {
                logger.error("url:{}", url, e);
                logApiStauts(false);
            }
            return res;
        }

        public List<String> getList(String url) {
            List<String> res = null;
            try {
                HttpGet httpget = new HttpGet(url);
                ResponseHandler<List<String>> responseHandler = new ResponseHandler<List<String>>() {
                    @Override
                    public List<String> handleResponse(final HttpResponse response) throws ClientProtocolException,
                            IOException {
                        int status = response.getStatusLine().getStatusCode();
                        if (status >= 200 && status < 300) {
                            List<String> result = new ArrayList<String>();
                            HttpEntity entity = response.getEntity();
                            if (entity == null) {
                                return result;
                            }
                            BufferedReader in = new BufferedReader(new InputStreamReader(entity.getContent()), SIZE);
                            while (true) {
                                String line = in.readLine();
                                if (line == null) {
                                    break;
                                } else {
                                    result.add(line);
                                }
                            }
                            in.close();
                            return result;
                        } else {
                            throw new ClientProtocolException("Unexpected response status: " + status);
                        }
                    }

                };
                res = httpclient.execute(httpget, responseHandler);
                logApiStauts(true);
            } catch (Exception e) {
                logger.error(url, e);
                logApiStauts(false);
            }
            return res;
        }

        /**
         * @param url, params, code
         * @return java.lang.String
         */
        private String post(String url, List<NameValuePair> params, String code) {
            String res = null;
            CloseableHttpResponse response = null;
            try {
                HttpPost httpPost = new HttpPost(url);
                if (params != null) {
                    httpPost.setEntity(new UrlEncodedFormEntity(params, code));
                }
                response = httpclient.execute(httpPost);
                HttpEntity entity2 = response.getEntity();
                res = EntityUtils.toString(entity2, code);
                EntityUtils.consume(entity2);
                logApiStauts(true);
            } catch (Exception e) {
                logger.error(url, e);
                logApiStauts(false);
            } finally {
                if (response != null) {
                    try {
                        response.close();
                    } catch (IOException e) {
                    }
                }
            }
            return res;
        }

        /**
         * @param url, params, headers, code
         * @return java.lang.String
         */
        private String post(String url, List<NameValuePair> params, Map<String, String> headers, String code) {
            String res = null;
            CloseableHttpResponse response = null;
            try {
                HttpPost httpPost = new HttpPost(url);
                if (headers != null) {
                    for (Map.Entry<String, String> entry : headers.entrySet()) {
                        if (entry != null) {
                            httpPost.addHeader(entry.getKey(), entry.getValue());
                        }
                    }
                }
                if (params != null) {
                    httpPost.setEntity(new UrlEncodedFormEntity(params, code));
                }
                response = httpclient.execute(httpPost);
                HttpEntity entity2 = response.getEntity();
                res = EntityUtils.toString(entity2, code);
                EntityUtils.consume(entity2);
                logApiStauts(true);
            } catch (Exception e) {
                logger.error(url, e);
                logApiStauts(false);
            } finally {
                if (response != null) {
                    try {
                        response.close();
                    } catch (IOException e) {
                    }
                }
            }
            return res;
        }

        /**
         * 记录api调用状态
         *
         * @param isSuccess
         */
        private void logApiStauts(boolean isSuccess) {
            try {
                ApiMonitor monitor = ThreadLocalContext.getLocal();
                if (monitor == null) {
                    return;
                }
                LogUtils.appendApiPath(monitor, isSuccess);
            } catch (Exception e) {
                logger.error("记录api调用状态失败 e.message", e.getMessage(), e);
            } finally {
                ThreadLocalContext.clear();
            }
        }

        private static final String APPLICATION_JSON = "application/json";
        private static final String CONTENT_TYPE_TEXT_JSON = "text/json";

        public String postJSON(String url, String json, String code) {
            String res = null;
            CloseableHttpResponse response = null;
            try {
                HttpPost httpPost = new HttpPost(url);
                httpPost.addHeader(HTTP.CONTENT_TYPE, APPLICATION_JSON);

                StringEntity se = new StringEntity(json);
                se.setContentType(CONTENT_TYPE_TEXT_JSON);
                se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, APPLICATION_JSON));
                httpPost.setEntity(se);
                response = httpclient.execute(httpPost);
                HttpEntity entity2 = response.getEntity();
                res = EntityUtils.toString(entity2, code);
                EntityUtils.consume(entity2);
                logApiStauts(true);
            } catch (Exception e) {
                logger.error(url, e);
                logApiStauts(false);
            } finally {
                if (response != null) {
                    try {
                        response.close();
                    } catch (IOException e) {
                    }
                }
            }
            return res;
        }


        /**
         * 默认UTF-8
         *
         * @param url
         * @param params
         * @return
         */
        public String post(String url, Map<String, ?> params) {
            return this.post(url, params, null, CHARSET_UTF8.toString());
        }

        public String post(String url, Map<String, ?> params, Map<String, String> headers) {
            return this.post(url, params, headers, CHARSET_UTF8.toString());
        }

        /**
         * @param url
         * @param params
         * @param code
         * @return
         */
        public String post(String url, Map<String, ?> params, Map<String, String> headers, String code) {
            List<NameValuePair> nvps = null;
            if (params != null && params.size() > 0) {
                nvps = new ArrayList<>();
                for (Map.Entry<String, ?> entry : params.entrySet()) {
                    String value = entry.getValue() == null ? "" : entry.getValue().toString();
                    nvps.add(new BasicNameValuePair(entry.getKey(), value));
                }
            }
            return this.post(url, nvps, headers, code);
        }

        // 监控有异常的链接
        private static class IdleConnectionMonitorThread extends Thread {

            private final HttpClientConnectionManager connMgr;
            private volatile boolean shutdown;

            public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) {
                super();
                this.connMgr = connMgr;
            }

            @Override
            public void run() {
                try {
                    while (!shutdown) {
                        synchronized (this) {
                            wait(5000);
                            // 关闭失效的连接
                            connMgr.closeExpiredConnections();
                            // 可选的, 关闭30秒内不活动的连接
                            connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
                        }
                    }
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }

        public String postBody(String url, String body) {
            String res = null;
            try {
                HttpPost httppost = new HttpPost(url);
                if (StringUtils.isNotBlank(body)) {
                    httppost.setEntity(new StringEntity(body, CHARSET_UTF8));
                }
                CloseableHttpResponse response = httpclient.execute(httppost);
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    res = EntityUtils.toString(resEntity, CHARSET_UTF8);
                    EntityUtils.consume(resEntity);
                    logApiStauts(true);
                }
            } catch (Exception e) {
                logger.error(url, e);
                logApiStauts(false);
            }

            return res;
        }
    }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值