org.apache.http.NoHttpResponseException

org.apache.http.NoHttpResponseException: 目标服务地址 failed to respond

​ 在使用Httpclient去使用get请求去调用其他服务的时候出的这个错,但是我直接使用浏览器访问是可以正常返回结果的,百度了很多都是说的传输层的tcp协议问题,在四次挥手的时候服务端已经主动断开连接了,客户端持有无效的连接去访问服务端,造成无响应,建议的是增加重试机制,我试了,没用!!!

​ 原来的工具类:说一下这里传进来的uri是完整的url,例如https://blog.csdn.net?name==xx&age=xx

 /**
     * 使用GET 方法发起http请求
     *
     * @param uri
     * @return
     * @throws IOException
     */
    public static String get(String uri) throws IOException {

        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        //创建客户端的时候设置默认的重试机制
        // DefaultHttpRequestRetryHandler的构造方法会默认重试3次,也可自己指定
        HttpClient httpClient = httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler()).build();
        HttpGet httpGet = new HttpGet(uri);
      
        /**
         * 设置超时,设置请求和传输超时时间
         */
        RequestConfig requestConfig = RequestConfig.custom().setRedirectsEnabled(true).setSocketTimeout(5000).setConnectTimeout(5000).build();

        httpGet.setConfig(requestConfig);
        HttpResponse response = null;
        response = httpClient.execute(httpGet);

        int code = response.getStatusLine().getStatusCode();
        if (code != 200) {
            log.warn("请求错误 错误码 {}", code);
        }

        return getContent(response.getEntity().getContent());
    }

    private static String getContent(InputStream is) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int i = -1;
        while ((i = is.read()) != -1) {
            baos.write(i);
        }
        is.close();
        return ba

​ 后面又想到get请求是不是参数不能这么放所以使用

 // 定义请求的参数
URI uri1 = new URIBuilder("http://www.baidu.com/s").setParameter("name", "xx").build();

这个并没有尝试,不过个人觉得不是这个问题,最终也是创建出一个URL对象知识不用手动的去拼接

​ 看了很多博客感觉都没说到点子上,后来看别人的工具类好像有个关流的操作,我的工具类里面并没有!!!,又想起之前的tcp协议是基于流的,有可能在返回数据的时候流出现了问题,但是httpclient对象没用close方法啊,看了一下这竟然是个接口,之前一直以为是类

​ 又想了一下那些文章说的四次挥手,那么我有可能就是没关流导致的连接问题,找到问题了!!!

​ httpclient创建方式有很多种,和使用的版本有关系差别不大,刚开始蒙圈了,其实好像没什么区别,写出来大家看一下

创建HttpClient对象

3.X:

HttpClient httpClient = new DefaultHttpClient();

4.3:

CloseableHttpClient httpClient = HttpClients.createDefault();

这个好像是4.3之后的版本

HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
HttpClient httpClient = httpClientBuilder.build();

我使用的是最后一种,查看了build()方法之后发现他返回的对象其实是一个CloseableHttpClient,可关闭的HttpClient,只不过用的接口接收,使用的多态,ok,现在明白了,只需要用实现类接收就可以调用close()方法了,不过需要注意关流需要在finally里面

​ 现在代码:

public static String get1(String uri) throws IOException {
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 创建Get请求
        HttpGet httpGet = new HttpGet(uri);
        // 响应模型
        CloseableHttpResponse response = null;
        // 配置信息
        RequestConfig requestConfig = RequestConfig.custom()
                // 设置连接超时时间(单位毫秒)
                .setConnectTimeout(5000)
                // 设置请求超时时间(单位毫秒)
                .setConnectionRequestTimeout(5000)
                // socket读写超时时间(单位毫秒)
                .setSocketTimeout(5000)
                // 设置是否允许重定向(默认为true)
                .setRedirectsEnabled(true).build();

        // 将上面的配置信息 运用到这个Get请求里
        httpGet.setConfig(requestConfig);

        String data = null;

        try {
            // 由客户端执行(发送)Get请求
            response = httpClient.execute(httpGet);

            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            if (response.getStatusLine()== 200) {
                data = EntityUtils.toString(responseEntity);
                System.out.println("响应内容长度为:" + responseEntity.getContentLength());
                System.out.println("响应内容为:" + data);
            }
        } catch (
                ClientProtocolException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return data;
    }



        }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return data;
    }

问题解决!!!

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值