由HttpClient_3 升级到 HttpClient_4.3.x

 

前言

由于HttpClient 4.x.x 是从原包的分支出来独立成包的,以后原来那个包的httpclient 不会再升级,所以以后我们是用httpclient 新分支。而且 4.x 与之前的 3.1 包结构以及接口都有较大变化,不仅如此,在4.3.x 相对于 4.2及以前版本又废弃了很多方法。故对于要升级到httpclient_4.3.x的资料和文档之类的都需要对应版本,非对应的版本可能引入其他漏洞

4.3.x  官方参考资料如下:

HttpClient 官方下载路径 http://hc.apache.org/downloads.cgi

HttpClient 官方资料 http://hc.apache.org/httpcomponents-client-4.3.x/index.html

HttpClient api http://hc.apache.org/httpcomponents-client-4.3.x/httpclient/apidocs/index.html

HttpClient Tutorial http://hc.apache.org/httpcomponents-client-4.3.x/tutorial/html/index.html

1      什么是HttpClient

1.1       简介

HttpClient 不是一个浏览器。它是一个客户端的HTTP通信实现库。HttpClient的目的是发送和接收HTTP报文。

HttpClient 提供的主要功能

1)实现了所有 HTTP 的方法(GET,POST,PUT,HEAD等)

2)支持自动转向

3)支持 HTTPS 协议

4)支持代理服务器等

1.2       httpClient的使用步骤

l  创建 HttpClient 的实例

l  创建某种连接方法的实例,在这里是 GetMethod。在 GetMethod 的构造函数中传入待连接的地址

l  调用第一步中创建好的实例的 execute 方法来执行第二步中创建好的 method 实例

l  response

l  释放连接。无论执行方法是否成功,都必须释放连接

l 对得到后的内容进行处理

2      基础

2.1      执行请求

HttpClient 最重要的功能是执行Http方法。执行一个HTTP方法涉及一个或多个HTTP请求/HTTP响应信息的交流,通常由HttpClient的内部来处理。用户提供一个要执行的请求对象, HttpClient发送请求到目标服务器,期望服务器返回对应的响应对象,或者当执行不成功时抛出异常。

 

2.1.1       HttpClient_3

使用httpClient 3 执行get post 请求的执行过程,并得到响应结果的过程示例如下,由程序可知httpClient的响应结果可以多次读取:

        //创建一个url作为请求路径
        //String url = protocol + "://" + ip + ":" + port + request.getRequestURI();
        String url = "http://10.137.152.171:5764";
        //创建一个默认的HttpClient 实例
        HttpClient client = new HttpClient();
        //创建一个请求方法,这里写了post和get 两种方式
        //HttpMethod method = new PostMethod(url);
        HttpMethod method = new GetMethod(url);
        try
        {
            //得到返回响应码,返回的值为200 表示响应成功
            int statusCode = client.executeMethod(method);
            if (200 == statusCode)
            {
                //返回响应结果,HttpClient 的三种常用返回响应结果的方法
                byte[] bytes = method.getResponseBody();
                String str = method.getResponseBodyAsString();
                InputStream in = method.getResponseBodyAsStream();
            }
        }
        catch (HttpException e)
        { //<...>
        }

 

2.1.2       HttpClient_4.3.x

使用httpClient 4.3.x 执行get post 请求的执行过程,并得到响应结果的过程示例如下, httpClient的响应内容只可以读取一次,若是需要多次读取,需要先储存起来,以免数据丢失。

httpClient 提供了直接读取消息实体的类EntityUtils.toString(),但该类使用有一定的限制,一般不建议使用,推荐使用HttpEntity#getContent() HttpEntity#writeTo(OutputStream)

String url = "http://10.137.152.171:7548";
        // 创建默认的HttpClient 实例
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 创建一个请求方法,这里提供了get和post两种方式
        //        HttpGet httpget = new HttpGet(url);
        //        HttpPost httppost = new HttpPost(url);
        HttpUriRequest request = new HttpPost(url);
        // 创建一个响应对象
        CloseableHttpResponse response = null;
        try
        {
            //执行请求得到响应结果
            response = httpclient.execute(request);
            //得到返回响应码,返回的值为200 表示响应成功
            int statusCode = response.getStatusLine().getStatusCode();
            //得到响应消息实体
            HttpEntity entity = response.getEntity();
            //得到响应消息内容
            //InputStream in = entity.getContent();
            if (entity != null)
            {
                //打印响应内容长度
                System.out.println(entity.getContentLength());
                //打印响应内容
                System.out.println(EntityUtils.toString(entity));
            }
            //确保它被完全消耗
            EntityUtils.consume(entity);
        }
        catch (IOException e)
        { //<...>}
        finally
        {//要释放响应流
                response.close();
        }  


2.2      设置请求头(具体请参见API)

在发送Http请求的时候,需要设置请求头。

2.2.1       HttpClient_3

HttpClient_3 设置请求头有两种方式,由API可知,HttpMethod#addRequestHeader()默认会将指定头添加到末尾,不会覆盖先前的值,如果出现多个值,会造成头识别报错。HttpMethod#setRequestHeader() 重新设置指定的头文件,会覆盖之前的值

2.2.2       HttpClient_4.3.x

HttpClient_4 设置请求头有两种方式, HttpGet HttpPost 等请求设置方法相同。由API可知,HttpGet#addHeader()默认会将指定头添加到末尾,不会覆盖先前的值。HttpGet#setHeader() 重新设置指定的头文件,会覆盖相同名字的值

2.3      添加参数

HttpClient 提供了一个实用的方法所有的Http请求有一个包含方法名,请求URIHTTP协议版本的请求行。HttpClient 支持在HTTP/1.1 规范中定义的所有HTTP方法:GETHEADPOSTPUTDELETETRACE OPTIONS,用一些特殊的类来表示每一个方法:HttpGetHttpPostHttpHeadHttpPutHttpDeleteHttpTrance HttpOptions

 

HTTP 请求URI 的包含协议、主机名、可选的端口、资源的路径、可选的查询和可选的片段。

HTTP请求格式告诉我们,有两种方式可以为request 提供参数:request-line 方式与 request-body 方式。这里只做Get Post 请求添加参数的介绍。request-body 方式只适用于Post 请求。

2.3.1       HttpClient_3

request-line 方式是指在请求行上通过URI 直接提供参数。

HttpClient_3 可以使用该函数getQueryString()直接添加参数,GetMethod 一般使用该方法,HttpClient_4 无此函数

 

PostMethod 添加参数addParameter()还有如下方法

 

2.3.2       HttpClient_4.3.x

request-line 方式是指在请求行上通过URI 直接提供参数。

1)  在生成request 对象时提供带参数的URI,如:

HttpUriRequest request1 = new HttpGet("http://localhost/index.html?param1=value1¶m2=value2");
            

         

 

 

2)  HttpClient 提供URIBuilder 来创建和修改URI(这是针对4.3的,之前版本不使用该方法)

 

URI uri = new URIBuilder()
            .setScheme("http")
            .setHost("www.google.com")
            .setPath("/search")
            .setParameter("param1", "value1")
            .setParameter("param2", "value2")
            .build();

 

Request-body 是在request-body中提供参数,此方式只能用于POST请求

1)使用UrlEncodedFormEntity

        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        formparams.add(new BasicNameValuePair("param1", "value1"));
        formparams.add(new BasicNameValuePair("param2", "value2"));
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
        HttpPost httppost = new HttpPost("http://localhost/handler.do");
        httppost.setEntity(entity);        
        System.out.println(httppost.getURI());


运行结果:http://localhost/handler.do? param1=value1&param2=value2

2)除了传统的application/x-www-form-urlencoded 表单,经常用到的是上传文件用的表单,这种表单类型为multipart/form-data . HttpClient MultipartEntityBuilder类与之对应

HttpEntity reqEntity = MultipartEntityBuilder.create()
                    .addPart("bin", bin)
                    .addPart("comment", comment)
                    .build();
httppost.setEntity(reqEntity);


示例如下:

        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpPost httppost = new HttpPost("http://localhost:8080");
            FileBody bin = new FileBody(new File(args[0]));
            StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN);

            HttpEntity reqEntity = MultipartEntityBuilder.create()
                    .addPart("bin", bin)
                    .addPart("comment", comment)
                    .build();
            httppost.setEntity(reqEntity);
            System.out.println("executing request " + httppost.getRequestLine());
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                System.out.println(response.getStatusLine());
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    System.out.println("Response content length: " + resEntity.getContentLength());
                }
                EntityUtils.consume(resEntity);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }



 

2.4      设置连接超时

设置HttpClient 连接服务器的时间

2.4.1       HttpClient_3

HttpClient client = new HttpClient();        client.getHttpConnectionManager().getParams().setConnectionTimeout(connTimeout);        client.getHttpConnectionManager().getParams().setSoTimeout(readTimeout);

2.4.2       HttpClient_4.3.x

实现代码

CloseableHttpClient httpclient = HttpClients.createDefault();
RequestConfig requestConfig = RequestConfig.custom()
        .setSocketTimeout(1000)
        .setConnectTimeout(1000)
        .build();
HttpGet httpget1 = new HttpGet("http://localhost");
httpget1.setConfig(requestConfig);


RequestConfig requestConfig = RequestConfig.custom()
        .setConnectTimeout(30000)
        .setSocketTimeout(30000)
        .build();
CloseableHttpClient client = HttpClients.custom()
        .setDefaultRequestConfig(requestConfig)
        .build();


 

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值