HttpClient 4.0学习

环境准备

无论是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 的实例:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

public class ClientConnectionRelease {

    /**
     * 处理一个实体
     * 
     * @param entity
     */
    private static StringBuffer processEntity(HttpEntity entity) {

	StringBuffer sb = new StringBuffer();
	InputStreamReader iReader = null;
	try {
	    // 从消息实体中获取输入流对象
	    InputStream inputStream = entity.getContent();
	    iReader = new InputStreamReader(inputStream);
	    BufferedReader reader = new BufferedReader(iReader);
	    String line = null;
	    // 用reader.ready()是不行的,这是用来判断此流是否已准备好被读取
	    while ((line = reader.readLine()) != null) {
		sb.append(line + "\r\n");
	    }
	} catch (Exception ex) {
	    ex.printStackTrace();
	} finally {
	    try {
		iReader.close();
	    } catch (IOException e) {
		e.printStackTrace();
	    }
	}
	return sb;

    }

    /**
     * main方法
     * 
     * @param args
     * @throws Exception
     */
    public final static void main(String[] args) throws Exception {

	// 创建HttpClient实例
	HttpClient httpclient = new DefaultHttpClient();
	// 创建Get方法实例
	HttpGet httpget = new HttpGet("http://www.baidu.com/");
	// HttpClient执行Get方法实例后得到响应
	HttpResponse response = httpclient.execute(httpget);
	// 从响应中获取消息实体,如果有的话
	HttpEntity entity = response.getEntity();
	// 处理消息实体中的内容
	try {
	    StringBuffer sb = processEntity(entity);
	    System.out.println(sb);
	} catch (RuntimeException ex) {
	    // 终止执行请求
	    httpget.abort();
	    throw ex;
	}
	// 释放连接
	httpclient.getConnectionManager().shutdown();
    }
}
 

 

HttpClient相关jar包见附件!  

猜你喜欢

转载自comss.iteye.com/blog/516490