浅谈Http

在Android开发中最经常见到的与服务器交互的方式就是通过Http请求了。我还是按照自己的理解来说明Http请求究竟是个什么东西。尽量不去堆砌名词,用最简单的语言就像科普一样给描述出来。

首先,Http是一种网络协议,协议这种东西就是约定好用来通信的嘛。通信协议无非就是通信双方对信息传输的约定,比如我要传个1,给你个高电平,传个0,就给你个低电平。尽管Http是应用层协议,它也是一种信息传输的约定,无非是比着0或1的编码更抽象罢了。我们要理解Http协议,首先要明白我们能用Http协议做什么,然后是哪些东西是Http这一层做的事。其实我一直觉的真正不容易懂的是http协议这一层到底包括哪些东西,什么get,post,head方法,无非就是一个规则,当我们知道http是什么之后,这些规则都简单的一笔。。。(我只写自己的理解,语言也没那么严密,感性认知,不喜勿喷)

其实就像手机一样,我们可以用手机打电话,发短信,只要知道对方的号码,会拨号,或者编辑,然后打电话要打开拨号的软件,发短信要打开短信软件进行编辑。可以把Http协议的接口就抽象为一个手机,至于怎么发出去的,怎么听到声音的,怎么连接上的,这些不用我们管,在http这一层也无需理解。这样来看http,其实也就很简单了。既然我们用http来进行客户端和服务器的交互,就自然可以想到,我们是和服务器进行交换数据的。比如我要注册,必然要把注册的账号告诉服务器,让它存起来,它验证后觉得,符合注册要求,然后返回一个信息,说成功了,然后客户端再进行其他的操作。这样的信息交互无非就四种嘛,增删改查。

同时我们来看http协议的各种请求,最常用的就是get方法和post方法了,为什么这两个最常用?因为get是对应数据的查,C/S模式下这种查不难理解吧,比如新闻客户端,一个页面那么多条新闻肯定要从服务器查询啊。每次刷新的时候去查一下服务器,然后服务器把结果取出来呈现在客户端界面上。post就对应是改数据的方法,客户端一般采集数据,更新服务端数据就用post方法。我觉得这样讲get和post的方法比说什么带不带body,格式什么的好理解吧。自然你想嘛,如果我要查,用get方法,只要知道路径,要查的字段就可以了,我自然就可以查到了,所需要的信息比较少,所以直接把参数放在url中就足够了。要用post,改数据,总要知道你要改的字段是什么,改可能牵涉一次改多个字段,比如改一篇文章,整片替换,那我都放url不是爆炸了。。。所以post一般以表单的形式提交,所以post要放参数,有数据body也就是这个原因了。就这么简单,我不知道为什么那些讲http请求的为什么老是搬书,上来就是定义,每次学一个新东西都很费劲。我觉得有这个理解,后面每一块是干嘛的其实很好理解的。

get和post方法最大的区别也就在这儿了,get是向服务端查询数据的,post对应修改更新数据的。至于什么url长度限制,什么有没有body,这些是这种传输方式的规定而已,也就是相当于语法级别的。下面来看具体的语法层面的:

方法描述

HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

方法描述
get从服务器获取指定资源,第一个参数之前有一个“?”,其他参数格式为:参数名=参数值,参数之间通过“&”连接
post修改服务器资源操作,常用来向服务器传递数据(URL指定要更改的资源的地址,body已key和value对应的形式指定要更新哪个字段,更新后的值是什么)
put向服务器写入资源的方法,让服务器用请求主体部分来创建一个用请求URL命名的新文档。(也就是body部分是资源,URL部分是资源地址,然后用这个请求在服务器上添加这个资源)
delete删除请求URL所指定的资源,(参数都放在URL中,因为是删除,所有用不着body,一个URL足够指定要删除的目标资源

一般移动开发用的着的也就这四个了,其他的不再列举,理解一个,其他的也就都理解了。

http提供这几个方法给我们用,为了灵活性考虑,这些方法必然可以有各种各样的配置来应对各种不同的需求,不然http协议早就被淘汰了。比如有人想用json字符串传递参数和返回,有人想数据压缩传输,这些自然是应该被满足的。因为是约定,你怎样传输的,数据是什么格式,肯定要有个地方来说明。

报文结构

请求报文

http中这些配置的说明都集中在头部,就是header,header里面包含了各种对本次http请求的配置,而一般http类的框架,多采用build模式来构建一个http请求,也正是因为http 请求的这么多配置,用build模式就比较方便,xxxBuilder.xx().xx().build。类似这种,就是一个个在配置相关的参数。其实这些配置无非是最后填在http协议的报文里面,作为一种标识,我们先来看http请求报文的结构。

image

请求行:请求行由方法字段、URL 字段 和HTTP 协议版本字段 3 个部分组成,他们之间使用空格隔开。

请求头部:请求头部由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:

  • User-Agent:产生请求的客户端的信息,比如浏览器版本,操作系统,这个我们用不着,不用管;
      
  • Date:发送请求的时间

  • Accept:客户端可识别的响应内容类型列表;星号 “ * ” 用于按范围将类型分组,用 “ / ” 指示可接受全部类型,用“ type/* ”指示可接受 type 类型的所有子类型;

  • Accept-Language:客户端可接受的自然语言;

  • Accept-Encoding:客户端可接受的编码压缩格式;

  • Accept-Charset:可接受的应答的字符集;
      

  • Content-Type:传输数据的类型

  • Host:请求的主机名,允许多个域名同处一个IP 地址,即虚拟主机;

  • connection:连接方式(close 或 keepalive);

  • Cookie:存储于客户端扩展字段,向同一域名的服务端发送属于该域的cookie;

    上面这些东西都是约定的东西,两边通信用的,这些我们有需要就配置,没需要就不用管。

空行:最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头,这是通信编码里常用的方法,就是一个约定,看到空行就表示请求头结束;

请求body:有些方法里有body,有些方法没有,原因就是需要不需要,仔细看都能理解;
   

方法Request Has BodyResponse Has BodySafe
GETNoYesYes
PUTYesYesNo
DELETENoYesNo
POSTYesYesNo

上面的表格就是http对应增删改查的四种方法是否有body,是否是数据安全的说明。(http还有其他的方法,在此不再列举,Android开发一般用不到)此处的数据安全是指是否对服务端数据有影响,不是指传输过程中的安全性。也很好理解只有get方法对应查数据不会影响原数据,属于只读操作所以get操作对数据来说是安全的。其他的增删改,都会影响,有写数据的操作,所以是对服务端数据不安全的。对于哪个请求有body,哪个没有body应该也很好理解,增和改,都要有自己的数据内容上传,此处是有body设计更合理,而删和查,只需知道具体位置,具体字段即可,所以无需再用请求body,所以设计为无请求body。

响应报文

整个http请求的报文结构也就是这样了,其实响应报文和请求报文并没有太大的区别:

响应报文的第一行叫状态行,这里面最重要的也就是状态码了。比如200,404等。这个状态码标志着这次请求是一个什么样的结果,就好像打电话,有正常接通,有暂时不在服务区,有您拨打的电话已停机等,这个状态码就是这么个意思,下面是状态码的具体定义:

状态码由三位数字组成,第一位数字表示响应的类型,常用的状态码有五大类如下所示:

  • 1xx:表示服务器已接收了客户端请求,客户端可继续发送请求;

  • 2xx:表示服务器已成功接收到请求并进行处理;

  • 3xx:表示服务器要求客户端重定向;

  • 4xx:表示客户端的请求有非法内容;

  • 5xx:表示服务器未能正常处理客户端的请求而出现意外错误;
      

状态码描述文本有如下取值:

  • 200 OK: 表示客户端请求成功;

  • 400 Bad Request: 表示客户端请求有语法错误,不能被服务器所理解;

  • 401 Unauthonzed: 表示请求未经授权,该状态代码必须与 WWW-Authenticate 报头域一起使用;

  • 403 Forbidden: 表示服务器收到请求,但是拒绝提供服务,通常会在响应正文中给出不提供服务的原因;

  • 404 Not Found: 请求的资源不存在,例如,输入了错误的URL;

  • 500 Internal Server Error: 表示服务器发生不可预期的错误,导致无法完成客户端的请求

  • 503 Service Unavailable: 表示服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常;

剩下的部分响应报文和请求报文结构基本一样,剩下头部,和body,头部表示此次返回的一些配置,和请求配置一样,比如是否要长链接,哪种格式的数据返回等,body部分也就是数据部分就是具体返回的实际数据体了,我们发起请求想要的到的结果也就是这部分内容了。把约定的数据格式转换成我们想要的格式也就ok了,现在用的最多的也就是json转Java对象了,在AndroidStudio中又个插件JsonFormat,直接把返回的body体的Json字符串生成类,用Gson解析生成对象就可以了,非常方便,不属于本篇内容,有兴趣的可以自行google。

到此关于http的这篇博客也就结束了,我并没有写关于什么一次http的请求的整个过程,当然并不是这些不重要,而是对Android开发者来说,了解我们用http能做什么,http给我们提供了什么样的接口更重要。一般网络请求,我们都会用框架,先对http从一个协议的角度去观察,从需求到设计,我们并不太需要关心实现,当然理解底层也是很有必要的,但是第一步直接就讲什么请求过程,对Android开发并没有什么实质上的帮助,而直接看报文格式,讲明白什么是get方法,为什么它没有头部,为什么post有头部,它们的差异化表现在哪,为什么是这样,这些对我们来说更为重要。至少我们能知道有时我们为什么用get而不用post,header添加的字段到底是什么意思,这些东西才更能让人接受。(完)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值