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;
    }
相关推荐
KevinGuo4574 分钟前
Selenium3自动化测试实战——基于python语言
开发语言·python·selenium
夏幻灵5 分钟前
写给初次用IDEA的新人
java·ide·intellij-idea
jgyzl18 分钟前
2026.1.2 Tomcat保姆级使用教程
java·tomcat
Tony Bai19 分钟前
Go 考古:Go 官方如何决定支持你的 CPU 和 OS?
开发语言·后端·golang
知无不研30 分钟前
.练习- Java字符串之String类创建字符串之使用equals和==判断字符串是否相等
java·开发语言
IT英语写作研习社34 分钟前
一句话解释Java 8 流streams 和函数式接口、λ表达式的关系
java
Slow菜鸟37 分钟前
Java基础 | JWT登录场景化最优方案(一)
java·开发语言
weixin_4573402143 分钟前
lora监督微调(SFT)
开发语言·python
_200_1 小时前
Lua 运算符
开发语言·junit·lua
UP_Continue1 小时前
C++11--引言折叠与完美转发
开发语言·c++