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;
    }
相关推荐
xun_xin6666 分钟前
如何解决Qt与OpenCV编译器不匹配问题
开发语言·qt·opencv
代码雕刻家8 分钟前
C语言中fgets函数详解
c语言·开发语言
雨中飘荡的记忆13 分钟前
拼团系统设计与实现
java·spring boot
青云交13 分钟前
Java 大视界 -- Java 大数据在智能医疗影像数据标注与疾病辅助诊断模型训练中的应用
java·大数据·多模态融合·医疗影像标注·辅助诊断·临床 ai·dicom 处理
雨中飘荡的记忆14 分钟前
Step Builder模式实战
java·设计模式
悦来客栈的老板15 分钟前
AST反混淆实战|reese84_jsvmp反编译前的优化处理
java·前端·javascript·数据库·算法
悟空码字18 分钟前
SpringBoot实现日志系统,Bug现形记
java·spring boot·后端
iナナ18 分钟前
Java自定义协议的发布订阅式消息队列(二)
java·开发语言·jvm·学习·spring·消息队列
狂奔小菜鸡18 分钟前
Day24 | Java泛型通配符与边界解析
java·后端·java ee
IMPYLH21 分钟前
Lua 的 tostring 函数
开发语言·笔记·junit·单元测试·lua