Http学习笔记

来源:互联网 发布:打字软件免费下载 编辑:程序博客网 时间:2024/06/05 17:31

HTTP协议的主要特点可概括如下:
支持客户/服务器模式。
简单快速:协议简单、程序规模小
灵活:任意类型数据,Content-type标记

无状态

无连接

HTTP

(超文本传输协议)是一个基于请求与响应模式的、面向资源的、无状态的、应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连接的机制(Keep_alive

无状态:需要前面的信息,则它必须重传

格式:

http://host[“:”port][abs_path]

HTTP 请求和响应:

http请求由三部分组成,分别是:请求行、消息报头、请求正文

请求行:Method Request-URIHTTP-Version

消息报头:Header

请求正文:data

HTTP响应也是由三个部分组成,分别是:状态行、消息报头、响应正文

状态行:HTTP-Version Status-Code Reason-Phrase CRLF

e.g.HTTP/1.1200 OK

HTTP Header中的字段(消息报头)

HTTP消息报头包括普通报头、请求报头、响应报头、实体报头

Content-Length: 12           

/*请求的内容长度,即发送的数据data的长度,不包括头部header不在内的长度

*字符、数字、文字都是通过字节的方式进行传递的,然后服务器端重新组合成原始字符

*GBK编码,一个汉字占两个字节。
UTF-16
编码,通常汉字占两个字节。

 UTF-8编码是变长编码,通常汉字占三个字节。

Cache-Control: no-cache

/*指定请求和响应应该遵循的缓存机制

Public指示响应可被任何缓存区缓存。
  no-cache指示请求或响应消息不能缓存
  no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
   打开新窗口如果指定cache-control的值为private、no-cache、must-revalidate,那么打开新窗口访问时都会重新访问服务器。

Accept请求报头域用于指定客户端接受哪些类型的信息

e.g. Accept: text/plain, text/html

Content-type:Content-Type: application/x-www-form-urlencoded

请求的与实体对应的MIME信息;

网页中的表单使用POST方法提交时,数据内容的类型是application/x-www-form-urlencoded

当action为get时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串(name1=value1&name2=value2...),然后把这个字串append到url后面,用?分割,加载这个新的url。 当action为post时候,浏览器把form数据封装到http body中,然后发送到server。

HTTPGetPost

(1)  Http协议目标是使应用程序执行更快,Http的缓存通常只是应用于idempotent request 即查询请求,不更新服务端数据的请求。因此,一般只对Get请求做缓存,对Post请求不做缓存:

new HttpURLConnection().setUseCache(false);

Get请求可以获取静态页面,也可以把参数放到URL字符串后面

Post请求的参数不是放在URL字符串的后面,而是放到http请求的正文中

Get是从服务器上获取数据

Post是从服务器上传递数据

Get方式,服务器端用Request.QueryString获取变量的值

Post方式,服务器端用Request.Form获取提交的数据

两者提交数据的不同

(2)  HttpURLConnection Java原生解决Http请求和响应的类

Get请求:

设定Get请求的URL,其中包含请求和传递的参数

String url = “GET_URL”+”?data=”+ URLEncoder.encode(data, "utf-8");

Post请求:
与Get请求不同,Post请求的参数不放在URL中
而是通过OutputStream输出流传递给服务器,Post的数据放在Http的正文中,将HttpConnection的输出流设置为打开的状态,默认是false:
setDoOutput(true);
setDoInput(true);// 默认是true
 
 
 
需要注意的是:
 
①  对于Http请求参数的设置都要在new URL(url).openConnection()方法与connect()方法之间完成。
②        需要设置的参数有:
setRequestProperty(“Content-type”,” application/x-www-form-urlencoded”);
设置传送的内容类型,如果不设置此项,当web服务默认不是这种类型时候,可能抛出java.io.EOFException 异常
        addRequestProperty"User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0.1) Gecko/20100101 Firefox/10.0.1");
③        conn.getOutputStream()操作就有连接服务器的作用,相当于connect()方法,此时将之前的一些参数先传递给服务器;执行getOutputStream操作后,可以不用进行connect()操作。
输出流OutputStream os = conn.getOutputStream()执行write操作之后,执行
os.flush();//刷新数据流,将任何字节都写入潜在的流中
os.close();//关闭流对象,此刻不能再向里写入,原先写入的放在内存缓冲区中

④       实际的Http请求发送

Http是基于Tcp传输协议的,connect()方法实际上只是建立了客户端和服务器之间的一个Tcp连接,并没有实际的发送Http请求。

无论Get还是Post方式,Http的实际请求是在HttpURLConnection的getInputStream()这个方法执行的时候,才正式的发送出去;

⑤  在实际请求过程中,OutputStream操作一定要放在InputStream之前执行完成。getHeaderField()操作需要访问服务器,相当于执行InputStream操作,所以需要放在Out操作之后,如果顺序不正确,出现java.net.ProtocolException:Cannot write output after reading input.

异常。

⑥     Outputstream并不是网络流,是一个字符流,写入其中的content并不是立即发送到服务器,而是先存在内存中,OutputStream流关闭后,根据输入内容形成Http正文;

⑦     HttpURLConnection是基于HTTP协议的,底层是通过socket通信实现。如果不设置超时(timeout),在网络异常的情况下,可能会导致程序僵死而不继续往下执行。可以通过以下两个语句来设置相应的超时:

⑧     网页中的表单使用POST方法提交时,数据内容的类型是       application/x-www-form-urlencoded,这种类型会:

字符"a"-"z","A"-"Z","0"-"9",".","-","*",和"_" 都不会被编码;

将非文本内容转换成"%xy"的形式,xy是两位16进制的数值;

Get请求的URL:

String url = "http://requestb.in/10zw1gk1" +"?timestamp=" + timestamp+"signature="+signature+

"sig_kv="+sig_kv+"content="+URLEncoder.encode("汉字","utf-8");

发送请求到服务器之后,Http请求头:

GET/10zw1gk1?timestamp=1441269347640signature=35fcd0e7882de617517db5d6cc989f1f5809652b34d1667e818c27d5013bbc55sig_kv=1content=%E5%A5%BD%E5%90%83%E6%87%92%E5%81%9A

任何字符只要不是ASCII码数字,字母,或者标点符,它们都将被转换成字节形式,每个字节都写成这种形式:一个“%”后面跟着两位16进制的数值。空格是一个特殊情况,因为它们太平常了。它除了被编码成“%20”以外,还能编码为一个“+”

例如:上面Url中的content改为“汉字  +”

则:content=content=%E5%A5%BD%E5%90%83%E6%87%92%E5%81%9A++%2B

HttpURLConnection 返回值处理

同步与异步处理:

Synchronous:

Public Stringm1(int a,int b) {//a,b是具体的值

       Returna,b;

}//等待返回结果才能进行下一步

Public void m2(list a) {//a 是一个引用,一个指向存储list数据结构的内存的指针

       a.add(ss);

       a= b;

}//此时a指向的list是改变的,a只是一个引用,并不是具体的,所以a=b时,list不变

Int a;

Public void m3() {

       a=3;

}//a是全局变量,如果多个类同时调用该类的m3方法,则对a的操作时容易出现问题,这相当与操作同一块内存;可以用程序执行的“钥匙“或者进程之间执行顺序的”信号量“

Asynchronous

Public voidm4(Handler) {

……//程序执行该方法,不必理会什么返回的结果,可以去执行别的工作,Handler

//调用run实现新的线程去执行,什么时候返回,不知道,即不同步

}

Handler{

       Run();

}

利用回调函数处理返回值:

访问Http的方法:

post(finalString url, final String content,final Listener)

Listener类用来处理访问服务器的返回结果:

Listener是一个抽象方法,里面定义了方法;

在具体的调用post方法的地方具体的实现方法。

0 0