HttpClient 4.0学习

本文详细介绍了如何使用HttpClient进行HTTP协议操作,包括简单的应用、API数据开发、HttpClient原理理解,以及具体应用流程,如登录验证、Session建立、表单分析和功能封装。通过实例代码演示了如何获取网页实体内容。

环境准备

无论是PC ,还是移动终端,传输的协议始终是HTTP 协议。

学习路线

1. 简单应用 HttpClient ,登录和不登录的方式, 截取数据

2. 通过 GAE 和 HttpClient 开发出对某个应用的标准 API 数据 (XML 格式 ) 。

3. 结合 HttpClient 和 HTTP 协议,了解 HttpClient 的基本实现原理

准备与 HttpClient 相关的 Jar 包:

# commons-logging-x.x.x.jar

# commons-codec-x.x.x.jar

# httpcore-x.x.x.jar

# httpclient-x.x.x.jar

 

概念术语

HTTP 消息:包括请求 (Request) 、回应 (Response)

消息的组成:消息头 (Header) 、消息实体 (Entity)

消息头的组成

通过 ieHttpHeader 截获了如下的头

请求的头:

GET /cn/ HTTP/1.1

Accept:

Accept-Language: zh-cn

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)

Host: www.huawei.com

Connection: Keep-Alive

Cookie: JSESSIONID=0000PtOOnIvtTar62-lClbyAO-m:12n56k2cu

响应的头:

HTTP/1.1 200 OK

Set-Cookie: MMwwwURL=235eb216f488bb88993cba88; path=

Date: Sat, 22 Aug 2009 03:21:59 GMT

Server: Apache

Accept-Ranges: bytes

Vary: Accept-Encoding

Content-Encoding: gzip

Content-Length: 7320

Keep-Alive: timeout=5, max=100

Connection: Keep-Alive

Content-Type: text/html

可知 , Header 有如下特点:

1. 除了第一行之外,其他的都是名 - 值对;请求和响应的区别是非常大的。尤其是第一行。第一行特别提取出 Method, 协议名等作为 HttpClient 的一个特征。

2. 名 - 值对的存在是为了让对方更清楚的了解发送方的意图, HttpClient 将其称为Header Fields 。在 HttpClient 中用 Header 类来表示。

消息实体 (Entity)

应该是指响应中回复的数据,指 MIME 的类型, Response 字段中有 Content-Type 就是用来描述 Entity 的类型 。

有以下 MIME 类型:

普通文本 .txt text/plain

RTF 文本 .rtf application/rtf

GIF 图形 .gif image/gif

JPEG 图形 .ipeg,.jpg image/jpeg

au 声音文件 .au audio/basic

MIDI 音乐文件 mid,.midi audio/midi,audio/x-midi

RealAudio 音乐文件 .ra, .ram audio/x-pn-realaudio

MPEG 文件 .mpg,.mpeg video/mpeg

AVI 文件 .avi video/x-msvideo

GZIP 文件 .gz application/x-gzip

TAR 文件 .tar application/x-tar

 

应用流程

第一:得到登录的页面

用 Get 方法去测试,查看以下结果:

1. 是否得到预期的页面?指一些数据,比如从 IE 上能显示的 HTML BODY

2. 是否得到 Sessions cookie ?

一般登录进去之后,才会有这样的 Sessions Cookie ,记得上一讲中的 Http Response Header 吗,里面的 Set Cookies ,可能就包含 Sessions Cookie 。如果此时没有 Set Cookies肯定说明此时 Session 没有建立。说明你还需要做一步工作,就是 " 建立 Sessions" 。 ( 引申一下, 即使存在 Set Cookie 这样的字段, 一定保证里面设置的就是 Session 吗? 也不一定, 保险的做法是,按照浏览器的习惯,从主页,再到登录页面,主页的目的只是为了获取必要的 Cookie 不要一步登天,当然,我们可以测试一下先,免得做不必要的登录主页,获取 Cookie 的操作 ) 。

如果,上面的 set cookie 你也有了,请求的 URL 也确认无误,但还是得不到预期的登录界面。很可能就是对方有个字段没有设置: User-Agent , 这个是指明你采用了哪个客户端向服务器发送请求,比如常用的有 IE 、 FF 、 Chrome ,设置主流的浏览器就成。

第二:建立 Session

这是在第一步失败的情况下需要的工作。通常的情况是,从主页去 Get 一把,从而得到Cookie 。下次 Login 请求的时候,将这些 Cookie 带进去。

HttpClient 提供了一套自动机制帮我们发送 Cookie , Cookie Store ,把 Response 中的Cookie 放置其中,并在发送的时候,帮我们发过去 ( 如果没有发送过去,检查 Cookie Store是否为同一个 ) 。

如果依然没有发送过去,这个时候就要检测 Cookie Scope , 比如:

A cookie for host "jakarta.apache.org" will not be sent to host "tomcat.apache.org". A cookie for domain ".apache.org" will be sent to both

注意, BT 的来了:

A cookie for host "apache.org", without the leading dot, will not be sent to "jakarta.apache.org".

如果还不行 ... 崩溃 ... 先别看了,以后再去这里寻求帮助好了

第三:分析表单

分析的方式是通过浏览器来的。建议过配置文件去灵活转化,不必进行复杂的表单解析工作。

OK ,可以按照 Browser 的习惯处理 HttpClient 的应用:

1. 得到必要的 Cookie 包括 Session id , 这个时候,我们还是用主页登录比较好。此时如果主页没有可用的信息,则我们只需要处理 Response 中的 Cookie 字段就好了。

2. 找到访问的路径。设置必要的参数对和必要的 URL( 包括表单项目 ) 。

      

功能封装

这里主要对一些 HttpClient 的基本功能实现封装, 封装成自己的 API ,供后续应用进行调用。下例可以将指定 URL 的内容获取过来。

处理 Entity 的实例:

Java代码   收藏代码
  1. import java.io.BufferedReader;  
  2. import java.io.IOException;  
  3. import java.io.InputStream;  
  4. import java.io.InputStreamReader;  
  5.   
  6. import org.apache.http.HttpEntity;  
  7. import org.apache.http.HttpResponse;  
  8. import org.apache.http.client.HttpClient;  
  9. import org.apache.http.client.methods.HttpGet;  
  10. import org.apache.http.impl.client.DefaultHttpClient;  
  11.   
  12. public class ClientConnectionRelease {  
  13.   
  14.     /** 
  15.      * 处理一个实体 
  16.      *  
  17.      * @param entity 
  18.      */  
  19.     private static StringBuffer processEntity(HttpEntity entity) {  
  20.   
  21.     StringBuffer sb = new StringBuffer();  
  22.     InputStreamReader iReader = null;  
  23.     try {  
  24.         // 从消息实体中获取输入流对象  
  25.         InputStream inputStream = entity.getContent();  
  26.         iReader = new InputStreamReader(inputStream);  
  27.         BufferedReader reader = new BufferedReader(iReader);  
  28.         String line = null;  
  29.         // 用reader.ready()是不行的,这是用来判断此流是否已准备好被读取  
  30.         while ((line = reader.readLine()) != null) {  
  31.         sb.append(line + "\r\n");  
  32.         }  
  33.     } catch (Exception ex) {  
  34.         ex.printStackTrace();  
  35.     } finally {  
  36.         try {  
  37.         iReader.close();  
  38.         } catch (IOException e) {  
  39.         e.printStackTrace();  
  40.         }  
  41.     }  
  42.     return sb;  
  43.   
  44.     }  
  45.   
  46.     /** 
  47.      * main方法 
  48.      *  
  49.      * @param args 
  50.      * @throws Exception 
  51.      */  
  52.     public final static void main(String[] args) throws Exception {  
  53.   
  54.     // 创建HttpClient实例  
  55.     HttpClient httpclient = new DefaultHttpClient();  
  56.     // 创建Get方法实例  
  57.     HttpGet httpget = new HttpGet("http://www.baidu.com/");  
  58.     // HttpClient执行Get方法实例后得到响应  
  59.     HttpResponse response = httpclient.execute(httpget);  
  60.     // 从响应中获取消息实体,如果有的话  
  61.     HttpEntity entity = response.getEntity();  
  62.     // 处理消息实体中的内容  
  63.     try {  
  64.         StringBuffer sb = processEntity(entity);  
  65.         System.out.println(sb);  
  66.     } catch (RuntimeException ex) {  
  67.         // 终止执行请求  
  68.         httpget.abort();  
  69.         throw ex;  
  70.     }  
  71.     // 释放连接  
  72.     httpclient.getConnectionManager().shutdown();  
  73.     }  
  74. }   
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值