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;
    }
相关推荐
大葱白菜1 分钟前
Java Set 集合详解:从基础语法到实战应用,彻底掌握去重与唯一性集合
java·后端
大葱白菜3 分钟前
Java Map 集合详解:从基础语法到实战应用,彻底掌握键值对数据结构
java·后端
添乱3 分钟前
「Java案例」判断是否是闰年的方法
java
FG.7 分钟前
Day22
java·面试
apihz7 分钟前
域名WHOIS信息查询免费API使用指南
android·开发语言·数据库·网络协议·tcp/ip
菜鸟的迷茫9 分钟前
Redis 缓存雪崩、穿透、击穿面试题深度解析与 Spring Boot 实战代码示例
java
珹洺20 分钟前
C++算法竞赛篇:DevC++ 如何进行debug调试
java·c++·算法
coding随想21 分钟前
掌控网页的魔法之书:JavaScript DOM的奇幻之旅
开发语言·javascript·ecmascript
SHUIPING_YANG27 分钟前
根据用户id自动切换表查询
java·服务器·数据库
爱吃烤鸡翅的酸菜鱼40 分钟前
IDEA高效开发:Database Navigator插件安装与核心使用指南
java·开发语言·数据库·编辑器·intellij-idea·database