HttpClient研究学习总结

转载:https://www.cnblogs.com/10158wsj/p/6767209.html

HttpClient研究学习总结

Http协议非常的重要,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且也方便了开发人员测试接口(基于Http协议的),即提高了开发的效率,也方便提高代码的健壮性。因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会更加深入。

一、Http简介

      HttpClient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。HttpClient已经应用在很多的项目中,比如Apache Jakarta上很著名的另外两个开源项目Cactus和HTMLUnit都使用了HttpClient。 

      HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。 
HTTP协议的主要特点可概括如下: 
1.支持客户/服务器模式。 
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。 
由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。 
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。 
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。 
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

二、使用方法

使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可。

首先需要导入HttpClientjar包,具体可以到官网下载,下载地址: http://hc.apache.org/downloads.cgi

commons-codec-1.7.jar,commons-logging-1.1.1.jar,httpclient-4.2.2.jar,httpcore-4.2.2.jar

1. 创建HttpClient对象,最新版的httpClient使用实现类的是closeableHTTPClient,以前的default作废了。

2. 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。

3. 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。

4. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。

5. 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。

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

三、使用实例

3.1.HttpClient提交表单模拟用户登录

 

复制代码

 1 package service;
 2 import java.io.IOException;
 3 import java.io.UnsupportedEncodingException;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 import org.apache.http.HttpEntity;
 7 import org.apache.http.NameValuePair;
 8 import org.apache.http.client.ClientProtocolException;
 9 import org.apache.http.client.entity.UrlEncodedFormEntity;
10 import org.apache.http.client.methods.CloseableHttpResponse;
11 import org.apache.http.client.methods.HttpPost;
12 import org.apache.http.impl.client.CloseableHttpClient;
13 import org.apache.http.impl.client.HttpClients;
14 import org.apache.http.message.BasicNameValuePair;
15 import org.apache.http.util.EntityUtils;
16 
17 public class ServiceHttpImpl implements ServiceHttp {
18     /**
19      * post方式提交表单,模拟用户登录请求
20      */
21     public void Login(String username, String password) {
22         //1.创建默认的httpclient实例
23         CloseableHttpClient httpclient = HttpClients.createDefault();
24         String url = "http://localhost:8080/httpcillent/HttpCilentTest1?username="
25                 + username + "&password=" + password;
26         //2.创建httpPost
27         HttpPost httpPost = new HttpPost(url);
28         //3.创建参数队列
29         List<NameValuePair> list = new ArrayList<NameValuePair>();
30         list.add(new BasicNameValuePair("username", username));
31         list.add(new BasicNameValuePair("password", password));
32         /**
33          * UrlEncodedFormEntity这个类是用来把输入数据编码成合适的内容  
34          *两个键值对,被UrlEncodedFormEntity实例编码后变为如下内容:
35          * key1=value1&key2=value2的形式
36          */
37         UrlEncodedFormEntity entity;
38         CloseableHttpResponse response=null;
39         try {
40             entity=new UrlEncodedFormEntity(list,"utf-8");
41             httpPost.setEntity(entity);//带上参数执行
42             System.out.println("执行请求:"+httpPost.getURI());
43             try {
44                 response=httpclient.execute(httpPost);//响应结果 
45                 HttpEntity httpEntity=response.getEntity();
46                 if(httpEntity!=null){
47                     System.out.println("-----------------");
48                     System.out.println(EntityUtils.toString(httpEntity));
49                     System.out.println("-----------------");
50                 }
51             } catch (ClientProtocolException e) {
52                 e.printStackTrace();
53             } catch (IOException e) {
54                 e.printStackTrace();
55             }
56         } catch (UnsupportedEncodingException e) {
57             e.printStackTrace();
58         }finally{
59             ServiceHttpImpl.CloseableHttpClient(httpclient);
60             ServiceHttpImpl.CloseableHttpResponse(response);
61         }
62     }
63     
64     private static void CloseableHttpResponse(CloseableHttpResponse httpResponse) {
65         if (httpResponse != null) {
66             try {
67                 httpResponse.close();
68             } catch (IOException e) {
69                 e.printStackTrace();
70             }
71         }
72     }
73 
74     private static void CloseableHttpClient(CloseableHttpClient client) {
75         if (client != null) {
76             try {
77                 client.close();
78             } catch (IOException e) {
79                 e.printStackTrace();
80             }
81         }
82     }
84     
85 }

复制代码

4.2 HTTP实体的使用

因为一个实体既可以代表二进制内容又可以代表字符内容,它也支持字符编码(支持后者也就是字符内容)。实体是当使用封闭内容执行请求,或当请求已经成功执行,或当响应体结果发功到客户端时创建的。

要从实体中读取内容,可以通过HttpEntity#getContent()方法从输入流中获取,这会返回一个java.io.InputStream对象,或者提供一个输出流到HttpEntity#writeTo(OutputStream)方法中,这会一次返回所有写入到给定流中的内容。

当实体通过一个收到的报文获取时,HttpEntity#getContentType()方法和HttpEntity#getContentLength()方法可以用来读取通用的元数据,如Content-Type和Content-Length头部信息(如果它们是可用的)。因为头部信息Content-Type可以包含对文本MIME类型的字符编码,比如text/plain或text/html,HttpEntity#getContentEncoding()方法用来读取这个信息。如果头部信息不可用,那么就返回长度-1,而对于内容类型返回NULL。如果头部信息Content-Type是可用的,那么就会返回一个Header对象。当为一个传出报文创建实体时,这个元数据不得不通过实体创建器来提供。

4.3发送post请求

复制代码

public void testPost() {  
        // 创建默认的httpClient实例.    
        CloseableHttpClient httpclient = HttpClients.createDefault();  
        // 创建httppost    
        HttpPost httppost = new HttpPost("http://localhost:8080/");  
        // 创建参数队列    
        List<NameValuePair> list = new ArrayList<NameValuePair>();  
        list.add(new BasicNameValuePair("admin", "我心自在"));  
        UrlEncodedFormEntity uefEntity;  
        try {  
            uefEntity = new UrlEncodedFormEntity(list, "UTF-8");  
            httppost.setEntity(uefEntity);  
            System.out.println("executing request " + httppost.getURI());  
            CloseableHttpResponse response = httpclient.execute(httppost);  
            try {  
                HttpEntity entity = response.getEntity();  
                if (entity != null) {  
                    System.out.println("--------------------------------------");  
                    System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8"));  
                    System.out.println("--------------------------------------");  
                }  
            } finally {  
                response.close();  
            }  
        } catch (ClientProtocolException e) {  
            e.printStackTrace();  
        } catch (UnsupportedEncodingException e1) {  
            e1.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            // 关闭连接,释放资源    
            try {  
                httpclient.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  

复制代码

测试结果如下:

4.3发送get请求

复制代码

 public void testGet() {  
        CloseableHttpClient httpclient = HttpClients.createDefault();  
        try {  
            // 创建httpget.    
            HttpGet httpget = new HttpGet("http://www.baidu.com/");  
            System.out.println("executing request " + httpget.getURI());  
            // 执行get请求.    
            CloseableHttpResponse response = httpclient.execute(httpget);  
            try {  
                // 获取响应实体    
                HttpEntity entity = response.getEntity();  
                System.out.println("--------------------------------------");  
                // 打印响应状态    
                System.out.println(response.getStatusLine());  
                if (entity != null) {  
                    // 打印响应内容长度    
                    System.out.println("Response content length: " + entity.getContentLength());  
                    // 打印响应内容    
                    System.out.println("Response content: " + EntityUtils.toString(entity));  
                }  
                System.out.println("------------------------------------");  
            } finally {  
                response.close();  
            }  
        } catch (ClientProtocolException e) {  
            e.printStackTrace();  
        } catch (ParseException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            // 关闭连接,释放资源    
            try {  
                httpclient.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    } 

复制代码

 测试结果如下:

总结httpGet和httpPost的区别和联系:

       HttpClient常用HttpGet和HttpPost这两个类,分别对应Get方式和Post方式。

       HttpPost方法提交HTTP POST请求,需要使用HttpPost类的setEntity方法设置请求参数。参数则必须用NameValuePair[]数组存储。

       get方式:以URL字串本身传递数据参数,在服务器端可以从'QUERY_STRING'这个变量中直接读取,效率较高,但缺乏安全性,也无法来处理复杂的数据。

       post方式:就传输方式讲参数会被打包在数据包中传输,从CONTENT_LENGTH这个环境变量中读取,便于传送较大一些的数据,同时因为不暴露数据在浏览器的地址栏中,安全性相对较高,但这样的处理效率会受到影响。

 表单提交中的post和get方法的区别:

1.get是从服务器上查询/获取数据,post是向服务器传输数据。

2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。

3. 对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。

4. get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB。

5. get安全性非常低,传输数据可见,post安全性较高,传输数据不可见,但通过抓包工具post传递中的参数也可以看到,所以理论上也不是安全的。

6. get是Form的默认方法。

 

分类: HttpClient研究学习总结

好文要顶 关注我 收藏该文  

我心自在
关注 - 2
粉丝 - 25

+加关注

0

0

« 上一篇:深入浅出学习HTTP协议
» 下一篇:servlet研究学习总结--OutputStream和PrintWriter的区别

    </div>
    <div class="postDesc">posted @ <span id="post-date">2017-04-26 11:24</span> <a href="https://www.cnblogs.com/10158wsj/">我心自在</a> 阅读(<span id="post_view_count">3753</span>) 评论(<span id="post_comment_count">2</span>)  <a href="https://i.cnblogs.com/EditPosts.aspx?postid=6767209" rel="nofollow">编辑</a> <a href="#" onclick="AddToWz(6767209);return false;">收藏</a></div>
</div>
<script type="text/javascript">var allowComments=true,cb_blogId=351149,cb_entryId=6767209,cb_blogApp=currentBlogApp,cb_blogUserGuid='9fe8f740-5e29-e711-9fc1-ac853d9f53cc',cb_entryCreatedDate='2017/4/26 11:24:00';loadViewCount(cb_entryId);var cb_postType=1;</script>

 

评论列表

 

    <div class="feedbackItem">
        <div class="feedbackListSubtitle">
            <div class="feedbackManage">
                &nbsp;&nbsp;<span class="comment_actions"></span>
            </div>
            <a href="#3967206" class="layer">#1楼</a><a name="3967206" id="comment_anchor_3967206"></a>  <span class="comment_date">2018-05-04 14:48</span> <a id="a_comment_author_3967206" href="https://www.cnblogs.com/xiaolong1996/" target="_blank">Bug开发工程师</a> <a href="http://msg.cnblogs.com/send/Bug%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
        </div>
        <div class="feedbackCon">
            <div id="comment_body_3967206" class="blog_comment_body">httpclient-4.2.2.jar 包版本太低,在第一步创建默认httpclient实例时系统报错,无法导入jar包,将版本号改为4.5后错误消失,希望大家不要再掉在这个坑里</div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(3967206,'Digg',this)">支持(0)</a><a href="javascript:void(0);" class="comment_bury" onclick="return voteComment(3967206,'Bury',this)">反对(0)</a></div><span id="comment_3967206_avatar" style="display:none;">http://pic.cnblogs.com/face/1333410/20180901100633.png</span>
        </div>
    </div>

    <div class="feedbackItem">
        <div class="feedbackListSubtitle">
            <div class="feedbackManage">
                &nbsp;&nbsp;<span class="comment_actions"></span>
            </div>
            <a href="#3967718" class="layer">#2楼</a><a name="3967718" id="comment_anchor_3967718"></a><span id="comment-maxId" style="display:none;">3967718</span><span id="comment-maxDate" style="display:none;">2018/5/5 8:53:50</span>  <span class="comment_date">2018-05-05 08:53</span> <a id="a_comment_author_3967718" href="https://www.cnblogs.com/xiaolong1996/" target="_blank">Bug开发工程师</a> <a href="http://msg.cnblogs.com/send/Bug%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
        </div>
        <div class="feedbackCon">
            <div id="comment_body_3967718" class="blog_comment_body">httpcore-4.2.2.jar 包版本也低了,程序运行的时候会报ClassNotFount异常,将jar包版本改为4.4.1 就好了</div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(3967718,'Digg',this)">支持(0)</a><a href="javascript:void(0);" class="comment_bury" onclick="return voteComment(3967718,'Bury',this)">反对(0)</a></div><span id="comment_3967718_avatar" style="display:none;">http://pic.cnblogs.com/face/1333410/20180901100633.png</span>
        </div>
    </div>
<div id="comments_pager_bottom"></div></div><script type="text/javascript">var commentManager = new blogCommentManager();commentManager.renderComments(0);</script>

刷新评论刷新页面返回顶部

注册用户登录后才能发表评论,请 登录 或 注册,访问网站首页。

【推荐】超50万VC++源码: 大型组态工控、电力仿真CAD与GIS源码库!
【活动】华为云12.12会员节 云产品1折起 满额送Mate20 点击抢购
【推荐】服务器100%基准CPU性能,1核1G首年168元,限时特惠!

腾讯云1129

 

最新新闻
·  11月手游报告:中国iOS收入同比增3% 下载量跌28.8%
·  千万人排队退押金 钱多就赢的逻辑害惨了共享单车
·  5.4万人被“罗振宇们”推进深渊的165天
·  暴雪回应百人自愿离开:只是给想走的员工更好的选择
·  今年社交榜单上最大的黑马,为什么说音遇了不起
» 更多新闻...

</div><!--end: forFlow -->
</div><!--end: mainContent 主体内容容器-->

<div id="sideBar">
    <div id="sideBarMain">

公告

昵称:我心自在
园龄:1年8个月
粉丝:25
关注:2

+加关注

        <div id="blog-calendar" style=""><table id="blogCalendar" class="Cal" cellspacing="0" cellpadding="0" title="Calendar">
<tbody><tr><td colspan="7"><table class="CalTitle" cellspacing="0">
    <tbody><tr><td class="CalNextPrev"><a href="javascript:void(0);" onclick="loadBlogCalendar('2018/11/01');return false;">&lt;</a></td><td align="center">2018年12月</td><td class="CalNextPrev" align="right"><a href="javascript:void(0);" onclick="loadBlogCalendar('2019/01/01');return false;">&gt;</a></td></tr>
</tbody></table></td></tr><tr><th class="CalDayHeader" align="center" abbr="日" scope="col">日</th><th class="CalDayHeader" align="center" abbr="一" scope="col">一</th><th class="CalDayHeader" align="center" abbr="二" scope="col">二</th><th class="CalDayHeader" align="center" abbr="三" scope="col">三</th><th class="CalDayHeader" align="center" abbr="四" scope="col">四</th><th class="CalDayHeader" align="center" abbr="五" scope="col">五</th><th class="CalDayHeader" align="center" abbr="六" scope="col">六</th></tr><tr><td class="CalOtherMonthDay" align="center">25</td><td class="CalOtherMonthDay" align="center">26</td><td class="CalOtherMonthDay" align="center">27</td><td class="CalOtherMonthDay" align="center">28</td><td class="CalOtherMonthDay" align="center">29</td><td class="CalOtherMonthDay" align="center">30</td><td class="CalWeekendDay" align="center">1</td></tr><tr><td class="CalWeekendDay" align="center">2</td><td align="center">3</td><td align="center">4</td><td align="center">5</td><td align="center">6</td><td align="center">7</td><td class="CalWeekendDay" align="center">8</td></tr><tr><td class="CalWeekendDay" align="center">9</td><td align="center">10</td><td align="center">11</td><td align="center">12</td><td align="center">13</td><td align="center"><a href="http://www.cnblogs.com/10158wsj/archive/2018/12/14.html"><u>14</u></a></td><td class="CalWeekendDay" align="center">15</td></tr><tr><td class="CalWeekendDay" align="center">16</td><td align="center">17</td><td align="center">18</td><td align="center">19</td><td align="center">20</td><td align="center">21</td><td class="CalWeekendDay" align="center">22</td></tr><tr><td class="CalWeekendDay" align="center">23</td><td align="center">24</td><td align="center">25</td><td class="CalTodayDay" align="center">26</td><td align="center">27</td><td align="center">28</td><td class="CalWeekendDay" align="center">29</td></tr><tr><td class="CalWeekendDay" align="center">30</td><td align="center">31</td><td class="CalOtherMonthDay" align="center">1</td><td class="CalOtherMonthDay" align="center">2</td><td class="CalOtherMonthDay" align="center">3</td><td class="CalOtherMonthDay" align="center">4</td><td class="CalOtherMonthDay" align="center">5</td></tr>

 

 

        <div id="leftcontentcontainer">
            <div id="blog-sidecolumn"><div id="sidebar_search" class="sidebar-block">

搜索

 

 

 

常用链接

随笔分类

 

 

 

随笔档案

 

最新评论

 

<div id="RecentCommentsBlock"><ul>
    <li class="recent_comment_title"><a href="https://www.cnblogs.com/10158wsj/p/8338367.html#4141249">1. Re:Java多线程优化方法及使用方式</a></li>
    <li class="recent_comment_body">学习到了,谢谢</li>
    <li class="recent_comment_author">--のの</li>
    <li class="recent_comment_title"><a href="https://www.cnblogs.com/10158wsj/p/6769213.html#4048350">2. Re:servlet研究学习总结--OutputStream和PrintWriter的区别</a></li>
    <li class="recent_comment_body">学习了!</li>
    <li class="recent_comment_author">--sunseeker</li>
    <li class="recent_comment_title"><a href="https://www.cnblogs.com/10158wsj/p/6782124.html#4009926">3. Re:Java常用的八种排序算法与代码实现</a></li>
    <li class="recent_comment_body">选择排序稳定性到底是稳定还是不稳定,表格跟上面一处地方不一致</li>
    <li class="recent_comment_author">--打包爱</li>
    <li class="recent_comment_title"><a href="https://www.cnblogs.com/10158wsj/p/6782124.html#4009895">4. Re:Java常用的八种排序算法与代码实现</a></li>
    <li class="recent_comment_body">希尔排序例子 32 43 23 13 5 <br>不是将 32 23 5 直接构成一组了吗</li>
    <li class="recent_comment_author">--打包爱</li>
    <li class="recent_comment_title"><a href="https://www.cnblogs.com/10158wsj/p/6782124.html#3990363">5. Re:Java常用的八种排序算法与代码实现</a></li>
    <li class="recent_comment_body">@一生爱你哦 insertNum;//是要插入的数...</li>
    <li class="recent_comment_author">--MartinBockZhu</li>

 

阅读排行榜

评论排行榜

推荐排行榜

 

    </div><!--end: sideBarMain -->
</div><!--end: sideBar 侧边栏容器 -->
<div class="clear"></div>
</div>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值