【Android应用开发技术:网络通信】Android HTTP编程

作者:郭孝星
微博:郭孝星的新浪微博
邮箱:[email protected]
博客:http://blog.csdn.net/allenwells
Github:https://github.com/guoxiaoxing

一 HTTP基础

HTTP是一个适用于分布式超媒体信息系统的应用层协议。

HTTP的主要特点如下所示:

  • 支持 C/S(客户端 / 服务器)模式。
  • 简单快速。客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用
    的有 GET、HEAD、POST。每种方法规定了客户与服务器联系的不同类型。因为
    HTTP 协议比较简单,HTTP 服务器的程序规模较小,因而其通信速度很快。
  • 灵活。HTTP 允许传输任意类型的数据对象。正在传输的类型由 Content-Type 加以
    标记。
  • 无连接。无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。
  • 无状态。HTTP 协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

1.1 HTTP地址

HTTP URL地址格式如下所示:

http:// host[":"port][abs_path]

http:表示要通过 HTTP 协议来定位网络资源的
host:表示合法的 Internet 主机域名或者 IP 地址
port:指定一个端口号,为空则使用默认端口 80
abs_path:指定请求资源的 URI(Uniform Resource Identifier,通用资源标志符,指 Web 上任意的可用资源)。

1.2 HTTP报文

HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的。

HTTP报文有两种:请求报文和响应报文。

1.2.1 HTTP请求报文

一个 HTTP 请求报文由请求行、请求报头、空行和请求数据 4 个部分组成,具体如下图所示:

【Android应用开发技术:网络通信】Android HTTP编程_第1张图片

1 请求行

请求行由请求方法字段、URI字段和HTTP协议版本字段组成,它们之间用空格分隔,如下所示:

Method Request-URI HTTP-Version CRLF

Method:表示请求方法
Request-URI:是一个统一资源标识符
HTTP-Version:表示请求的 HTTP 协议版本
CRLF:表示回车和换行(除了作为结尾的 CRLF 外,不允许出现单独的 CR 或 LF 字符)。

请求方法有以下几种:

  • GET 请求获取 Request-URI 所标识的资源
  • POST 在 Request-URI 所标识的资源后附加新的数据
  • HEAD 请求获取由 Request-URI 所标识的资源的响应消息报头
  • PUT 请求服务器存储一个资源,并用 Request-URI 作为其标识
  • DELETE 请求服务器删除 Request-URI 所标识的资源
  • TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断
  • CONNECT 保留将来使用
  • OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求

2 请求报头

见下方描述

3 请求数据

请求数据不在 GET 方法中使用,而是在 POST 方法中使用。POST 方法适用于需要客户填写表单的场合。与请求数据相关的、最常使用的请求头是 Content-Type 和 Content-Length。在接收和解释请求消息后,服务器会返回一个 HTTP 响应消息。

1.2.2 HTTP响应报文

HTTP响应报文也是由4个部分组成,分别是状态行、消息报头、空行和响应正文,如下所示:

【Android应用开发技术:网络通信】Android HTTP编程_第2张图片

1 状态行

状态行的格式如下所示:

HTTP-Version Status-Code Reason-Phrase CRLF

HTTP-Version 表示服务器 HTTP 协议的版本
Status-Code 表示服务器发回的响应状态代码
Reason-Phrase 表示状态代码的文本描述

状态代码由 3 位数字组成,第一个数字定义了响应的类别,且有 5 种可能取值,如下所示:

1xx 指示信息,表示请求已接受,继续处理
2xx 成功,表示请求已被成功接收、理解、接受
3xx 重定向,要完成请求必须进行进一步的操作
4xx 客户端错误,请求有语法错误或请求无法实现
5xx 服务器端错误,服务器未能实现合法的请求

常见的状态代码如下所示:

200 OK 客户端请求成功
400 Bad Request 客户端请求有语法错误,不能被服务器所理解
401 Unauthorized 请求未经授权
403 Forbidden 服务器收到请求,但是拒绝提供服务
404 Not Found 请求资源不存在,比如输入了错误的 URL
500 Internal Server Error 服务器发生不可预期的错误
503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后可能恢复正常

2 响应报头

见下方描述

3 空行

这行是空的。

4 响应正文

响应正文就是服务器返回的资源的内容。

关于消息报头

HTTP 消息由客户端到服务器的请求和服务器到客户端的响应组成。请求消息和响应消息都是由开始行(对于请求消息,开始行就是请求行 ;对于响应消息,开始行就是状态行)、消息报头(可选)、空行(只有 CRLF 的行)、消息正文(可选)4 部分组成。

报头由“头部字段名 / 值”对组成,每行一对,头部字段名和值用英文冒号“:”分隔,具体如下所示:

头部字段名 +":"+ 空格 + 值

消息报头共有4种类型,如下所示:

  • 普通报头 :即可用于请求,也可用于响应,不用于被传输的实体,只用于传输消息,是作为一个整体而不是特定资源与事务相关联。比如,Date 普通报头表示消息产生的日期和时间 ;Connection 普通报头允许发送指定连接的选项,例如指定连接是连续,或者指定 close 选项,通知服务器,在响应完成后,关闭连接。
  • 请求报头 :允许客户端传递关于自身的信息和希望的响应形式。请求报头通知服务器有关客户端请求的信息,典型的请求报头有如下几种:
    User-Agent:包含产生请求的操作系统、浏览器类型等信息。
    Accept:客户端可识别的内容类型列表,用于指定客户端接受哪些类型的信息。
    Host:请求的主机名,允许多个域名同处一个 IP 地址,即虚拟主机。
  • 响应报头:服务器用于传递自身信息的响应。典型的响应报头有如下两种。
    Location :用于重定向接收者到一个新的位置。Location 响应报头常用在更换域名的时候。
    Server :包含了服务器用来处理请求的系统信息,与 User-Agent 请求报头是相对应的。
  • 实体报头 :定义被传送资源的信息。既可用于请求,也可用于响应。请求和响应消‰息都可以传送一个实体。典型的实体报头如下。
    Content-Encoding :被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码。因而要获得 Content-Type 报头中所引用的媒体类型,必须采用相应的解码机制。
    Content-Language :描述了资源所用的自然语言。没有设置该选项则认为实体内容提供给所有的语言阅读。
    Content-Length:用于指明实体正文的长度,以字节方式存储的十进制数字来表示。
    Last-Modified:用于指示资源的最后修改日期和时间。
     

二 HTTP编程

2.1 HttpClient

HttpClient是Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且支持 HTTP 协议最新的版本和建议。

HttpClient实现的功能有:

  • 实现了所有HTTP的方法(GET、POST、PUT和HEAD等)
  • 支持自动转向
  • 支持HTTPS协议
  • 支持代理服务器

HttpClient的使用步骤如下所示:

  1. 创建 HttpClient 的实例。
  2. 创建某种连接方法的实例,对于 get 方法是 GetMethod,而对于 post 方法是
    PostMethod。
  3. 调用步骤 1 中创建好的实例的 execute 方法来执行步骤 2 中创建好的 method
    实例。
  4. 读 response。
  5. 释放连接。
  6. 对得到的内容进行处理。

HttpClient中最常用的方法是GET方法和POST方法。

GET方法要求服务器将URL定位的资源放在响应报文的数据部分,回送给客户端。
使用 GET 方法时,请求参数和对应的值附加在 URL 后面,利用一个问号(“?”)代表 URL的结尾与请求参数的开始。

具体代码如下所示:

// 通过 GET 方法获取页面信息
// 参数为对应页面的 URL
public static InputStream getInputStreamFromUrl(String url) {
// 定义输出流变量
InputStream content = null;
try {
// 取得默认的 HttpClient 实例
HttpClient httpclient = new DefaultHttpClient();
// 连接到服务器
HttpResponse response = httpclient.execute(
// 创建 HttpGet 实例
new HttpGet(url));
// 获取数据内容
content = response.getEntity().getContent();
} catch (Exception e) {
}
// 以 InputStream 形式返回页面信息
return content;
}

面的 GET 方法是以 InputStream 的形式返回页面的信息,很多情况下需要String Builder、 String 等字符串的格式。下面的方法把 InputStream 格式转为 StringBuilder 和 String格式。转换方法如下所示:

// 将 InputStream 格式转化为 StringBuilder 格式
private StringBuilder inputStreamToStringBuilder (InputStream is) {
// 定义空字符串
String line = "";
// 定义 StringBuilder 的实例 total
StringBuilder total = new StringBuilder();
// 定义 BufferedReader,载入 InputStreamReader
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
// readLine 是一个阻塞的方法,当没有断开连接的时候就会一直等待,直到有数据返回
// 返回 null 表示读到数据流最末尾
while ((line = rd.readLine()) != null) {
total.append(line);
}
// 以 StringBuilder 形式返回数据内容
return total;
}
// 将 InputStream 格式数据流转换为 String 类型
private String inputStreamToString(InputStream is) {
// 定义空字符串
String s = "";
String line = "";
// 定义 BufferedReader,载入 InputStreamReader
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
// 读取到字符串中
while ((line = rd.readLine()) != null) {
s += line;
}
// 以字符串方式返回信息
return s;
}

POST方法要求被请求服务器接收附在请求后面的数据,常用于提交表单。

当客户端给服务器提供信息较多时可以使用 POST 方法。POST 方法将请求参数封装在 HTTP 请求数据中,以名称值的形式出现,可以传输大量数据。代码如下所示:

public void postData() {
// 创建一个新的 HttpClient Post 头
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http:// www.google.com");
try {
// 添加数据
List nameValuePairs = new ArrayList(2);
nameValuePairs.add(new BasicNameValuePair("id", "12345"));
nameValuePairs.add(new BasicNameValuePair("stringdata", "myString"));
// 使用 utf-8 格式对数据进行编码
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs ,"UTF-8"));
// 执行 HTTP Post 请求
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
}

2.2 URLConnection

在介绍URLConnection之前,我们先来介绍以下URL。

URL(Uniform Resource Locator)代表统一资源定位符,Internet 上的每个资源都具有一个唯一的名称标识,通常称为 URL 地址,这种地址可以是本地磁盘,也可以是局域网上的某一台计算机,更多的是 Internet 上的站点,因此 URL 是指向互联网“资源”的指针。

下面我们再来说说URLConnection。

URLConnection则代表了应用程序和URL之间的通信链接,通URLConnection 类的实例可以读取和写入此URL应用的资源。

你可能感兴趣的:(安卓技术,-,应用开发)