# HTTP协议与HttpClient
所谓的协议都是“标准”,就像人们交流沟通时使用普通话一样,这是一种规范、一个标准,否则,人们的交流沟通就会出现阻塞、障碍,那么,网络之间的通讯也需要这样一种标准,这就是一种协议,HTTP协议是就是浏览器与服务器之间对话的这样一种标准。
HTTP协议是“超文本传输协议”(超文本传输的意思是:不局限于文本,还可以是音频、视频),可以用四个字总结其概要:“有求必应”,即:有请求必有应答。它处于应用层,是基于传输层的TCP协议进行通信,它是通用的(现在互联网用的最多的就是HTTP协议,例如访问网站,手机上的应用程序)、无状态(无状态的意思就是:当请求应答完成后,浏览器与服务器之间连结的状态就断开了,这样的优势就是可以节省网络资源,缺点是服务器无法主动去连结浏览器)的协议。
HTTP协议与Android之间的关系:用户使用某一个应用程序时,会向服务器去请求数据,那么手机上的应用程序就扮演了浏览器的角色。即:用户操作应用程序,然后由应用程序向服务器请求数据(应用程序开启一个新线程去请求数据),服务器作出响应将处理后的数据打包返回到应用程序,然后再由应用程序反馈给用户。
一个简单的纯粹的信息展示类的应用程序(例如:新闻客户端、微博等),无非就是四项技术加在一起:简单的UI,简单的线程,简单的网络以及简单的数据存储。
# 一.HttpClient的使用步骤
HttpClient是由Apache基金会开发的一套开源类库,属于HttpComponents的一部分,它是HTTP/1.1协议下的一种实现,由于它是开源的,Android也是开源的,所以Android就将这一类库整合到了Android里面,所以在Android应用程序中无需引用类库,直接使用就行。
TIP
1.生成代表客户端的HttpClient对象;
2.生成代表请求的HttpGet对象;
3.发送请求,获得服务器返回的HttpResponse对象;
4.检查响应状态是否正常;
5.获取响应对象当中的数据;
# 二.HTTP请求头与响应头
请求头与响应头其实就是一系列的文本数据,里面包含的内容统统都是键值对,每一个键值对都有一个含义。
请求头Request Headers详解(这是一个get方式的请求头):
WARNING
Host: baidu.com === Host
就是本次请求访问主机地址
Cache-control:no-cache === Cache-control
设置网页缓存的使用方法
Pragma:no-cache === Pragma
同Cache-control
一样,都是设置网页缓存的使用方法
Accept: text/html,xxxxxx…… === Accept
:浏览器可以接受的数据类型,告诉服务器我可以接受的数据类型是什么
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36 === User-Agent
主要表示客户端类型,也就是说我现在正在使用什么样的客户端访问服务器
Accept-Encoding: gzip, deflate === Accept-Encoding
表示浏览器能够解码的数据编码方式,也就是说服务器在向客户端响应发送数据时的数据的格式,例如传送一个较大的文件时可以先在服务器端进行压缩,然后再发送,而在客户端则必须能够解码这样的数据格式才能够得到这样的响应,然后解压缩出来,这样可以节省占用网络资源传输的时间,增加传输效率。
Accept-Language: zh-CN,zh;q=0.8 === Accept-Language
表示浏览器期望接受的语言种类。
响应头Response Headers详解
TIP
Content-Encoding: gzip, deflate, sdch ===服务器端返回给客户端的数据的压缩格式
Content-Length: 0 ===服务器端返回数据量的大小(返回内容包含多少个字节的长度)
Content-Type ===服务器端返回数据的类型,例如音频、视频、文本
Last-Modifined ===客户端所访问的资源最后一次修改的时间
Date:Tue, 01 Mar 2016 13:27:23 GMT ===返回数据的时间
Server:nginx/1.8.0 ===服务器端的类型
三.综上,代码案例:
public class MainActivity extends Activity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.clickButton);
ButtonClickListenner buttonClickListenner = new ButtonClickListenner();
button.setOnClickListener(buttonClickListenner);
}
class ButtonClickListenner implements OnClickListener{
@Override
public void onClick(View arg0) {
// 在这里铭记一个原则:在主线程当中不能访问网络(这是在Android4.0以后加入的概念)
WorkerThread workerThread = new WorkerThread();
workerThread.start();
}
}
class WorkerThread extends Thread{
@Override
public void run(){
//第一步,创建HttpClient对象
HttpClient httpClient = new DefaultHttpClient();
//第二步,创建代表请求的对象,参数是访问的服务器的地址
HttpGet httpget = new HttpGet("http://www.marschen.com/data1.html");
//有了请求对象,在此就可以获取请求头的内容,但是目前是在代码中请求服务器的,因此需要自己去设置请求头
//如果是在浏览器上请求访问的,那么这个请求头是浏览器放进去的
//在做安全认证时,一般有两种认证数据的方式,一种是通过post将认证数据提交至服务器,还有一种就是将认证数据放在请求头中。
httpget.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36");
Header[] requestHeaders = httpget.getAllHeaders();
for (Header header : requestHeaders) {
String headerName = header.getName();
String headerValue = header.getValue();
Log.d("HTTP01", "requestHeaders----Name:"+headerName+",Value:"+headerValue);
}
//第三步,执行请求,获取发还的相应对象
try {
HttpResponse httpResponse = httpClient.execute(httpget);
//在此可以获取响应头的内容
Header[] responseHeaders = httpResponse.getAllHeaders();
for (Header header : responseHeaders) {
String headerName = header.getName();
String headerValue = header.getValue();
Log.d("HTTP01", "responseHeaders----Name:"+headerName+",Value:"+headerValue);
}
//第四步,检查响应状态是否正常(检查状态码的值是否等于200)
int statusCode = httpResponse.getStatusLine().getStatusCode();
if(200 == statusCode){//正常
//第五步,从相应对象当中取出数据
HttpEntity entity = httpResponse.getEntity();
InputStream inStream = entity.getContent();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inStream));
String str = bufferedReader.readLine();
Log.d("HTTP", "从服务器取得的数据是:"+str);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
在AndroidManifest.xml
文件中加入代码:
<uses-permission android:name="android.permission.INTERNET"/>
这句代码就是为该程序申请了权限,就是在安装应用程序时系统会提示:提醒用户这个程序是要访问网络的,如果同意则执行安装,不同意则不安装该程序。一般情况下,用户根本不看这个提示。