for循环中调用CloseableHttpClient代码未执行完毕就自动停止

问题背景:我在一个for循环中需要每次循环时调用高德地图的api进行计算2点之间的距离。有300条数据,试了很多次大概在80多条或100多条时,for循环就自动停止了不继续循环了。

以下是刚开始有BUG的http工具类中的get请求方法的代码:

复制代码
    /**
     * 带参数的get请求
     *
     * @param url
     * @param param
     * @return String
     */
    public static String doGet(String url, Map<String, String> param) {
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();

        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();
            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);
            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            } else {
                log.info("带参doGet请求异常:"+response.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

有log.info日志,我知道了for循环不继续执行的原因,是因为循环的某次请求调用高德地图API发生了401错误,而这个http请求一直不关闭,导致for循环就一直卡在这里不继续执行。虽然我这个http工具类的doGet()方法为了防止http请求失败,而做了return处理。但是经测试发现一旦http请求异常,返回代码不是200时,并不会直接return跳出doGet()方法。

出现这个问题的原因:http请求失败时,请求连接并没有及时释放

解决办法:无论http请求成功还是失败,都应该在请求完成后及时释放连接资源。即添加如下代码

复制代码
httpGet.releaseConnection();

那么修改后的代码为:

复制代码
/**
     * 带参数的get请求
     *
     * @param url
     * @param param
     * @return String
     */
    public static String doGet(String url, Map<String, String> param) {
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();

        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();
            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);
            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            } else {
                log.info("带参doGet请求异常:"+response.getStatusLine().getStatusCode());
            }
            //释放链接资源,不然频繁调用该接口时,如果某次调用失败会卡住,影响下次调用
            httpGet.releaseConnection();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }
相关推荐
一只游鱼几秒前
maven简介与安装
java·maven
会飞的小新2 分钟前
C 标准库之 <errno.h> 详解与深度解析
c语言·开发语言
KIKIiiiiiiii24 分钟前
微信个人号开发中如何高效实现API二次开发
java·前端·python·微信
胡八一30 分钟前
30 分钟上手 exp4j:在 Java 中安全、灵活地计算数学表达式
java·开发语言·安全
郝学胜-神的一滴1 小时前
Linux 进程控制块(PCB)解析:深入理解进程管理机制
linux·服务器·开发语言
后端小张1 小时前
【鸿蒙开发手册】重生之我要学习鸿蒙HarmonyOS开发
开发语言·学习·华为·架构·harmonyos·鸿蒙·鸿蒙系统
胖咕噜的稞达鸭1 小时前
AVL树手撕,超详细图文详解
c语言·开发语言·数据结构·c++·算法·visual studio
张较瘦_1 小时前
环境搭建 | [入门级]VSCode(Cursor|Trae|Qoder)搭建Java(Springboot3)企业开发环境全流程
java·ide·vscode
007php0071 小时前
百度面试题解析:synchronized、volatile、JMM内存模型、JVM运行时区域及堆和方法区(三)
java·开发语言·jvm·缓存·面试·golang·php
YSRM1 小时前
Leetcode+Java+图论II
java·leetcode·图论