1.1 什么是REST
REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移。 它首次出现在2000年Roy Fielding的博士论文中,Roy Fielding是HTTP规范的主要编写者之一。 他在论文中提到:“我这篇文章的写作目的,就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构。REST指的是一组架构约束条件和原则。” 如果一个架构符合REST的约束条件和原则,我们就称它为RESTful架构。
使用RESTful架构的优点:
为了提高系统的可伸缩性,降低应用之间的耦合度,便于架构分布式处理程序。
1.2 理解RESTful
要理解RESTful架构,需要理解Representational State Transfer这个词组到底是什么意思,它的每一个词都有些什么涵义。 下面我们结合REST原则,围绕资源展开讨论,从资源的定义、获取、表述、关联、状态变迁等角度。
· 资源与URI
· 统一资源接口
· 资源的表述
· 资源的链接
· 状态的转移
1.2.1 资源与URI
REST全称是表述性状态转移,那究竟指的是什么的表述? 其实指的就是资源。任何事物,只要有被引用到的必要,它就是一个资源。资源可以是实体(例如手机号码),也可以只是一个抽象概念(例如价值) 。下面是一些资源的例子:
某用户的手机号码
某用户的个人信息
最多用户订购的GPRS套餐
两个产品之间的依赖关系
某用户可以办理的优惠套餐
某手机号码的潜在价值
要让一个资源可以被识别,需要有个唯一标识,在Web中这个唯一标识就是URI(Uniform Resource Identifier)。 URI既可以看成是资源的地址,也可以看成是资源的名称。如果某些信息没有使用URI来表示,那它就不能算是一个资源, 只能算是资源的一些信息而已。
1.2.2 资源的表述
客户端通过HTTP方法可以获取资源,是吧? 不,确切的说,客户端获取的只是资源的表述而已。 资源在外界的具体呈现,可以有多种表述(或成为表现、表示)形式,在客户端和服务端之间传送的也是资源的表述,而不是资源本身。 例如文本资源可以采用html、xml、json等格式,图片可以使用PNG或JPG展现出来。 资源的表述包括数据和描述数据的元数据,例如,HTTP头“Content-Type” 就是这样一个元数据属性。
那么客户端如何知道服务端提供哪种表述形式呢?
答案是可以通过HTTP内容协商,客户端可以通过Accept头请求一种特定格式的表述,服务端则通过Content-Type告诉客户端资源的表述形式。
1.2.3 统一资源接口
rest主要对以下两方面做了统一规范:
URL的风格
URI设计上的一些技巧:
· 使用 / 来表示资源的层级关系 localhost:8080/appName/userList/id/name
· 使用 ? 用来过滤资源
· , 或 ; 可以用来表示同级资源的关系
资源的操作
接口应该使用标准的HTTP方法如GET,PUT, DELETE和POST,并遵循这些方法的语义。
新增 (CREATE) 针对数据来说,不安全且不幂等
查询 (READ) 安全且幂等
更新 (UPDATE) 不安全但幂等
删除 (DELETE) 不安全但幂等
在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等性是分布式系统设计中十分重要的概念
是返回资源,将资源的状态从服务器转移到客户端。而PUT则恰恰相反,将资源的状态从客户端转移到服务端。POST和DELETE也正好相反,POST负责创建资源,而DELETE则负责删除资源。
举例:电商项目中遇到的问题
如何防范 POST 重复提交 使用幂等
HTTP POST操作既不是安全的,也不是幂等的(至少在HTTP规范里没有保证)。当我们因为反复刷新浏览器导致多次提交表单,多次发出同样的POST请求,导致远端服务器重复创建出了资源。
所以,对于电商应用来说,第一对应的后端幂等性,第二服务器端收到必须302跳转到另外一个页面,这样即使用户刷新页面,也不会重复提交表单。
1.3 Spring对RESTful的支持
Spring MVC对RESTful应用提供了以下支持
1、利用@RequestMapping 指定要处理请求的URI模板和HTTP请求的动作类型
2、利用@PathVariable将URI请求模板中的变量映射到处理方法参数上
3、利用Ajax,在客户端发出PUT、DELETE动作的请求
1.3.1 RequestMapping的一般应用格式。
在RESTful应用中在Controller层
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
@RequestMapping(value = "/{id}", method = RequestMethod.POST)
这个需要Ajax请求,所有返回的是个json
@ResponseBody
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
例如:客户端发送PUT,DELETE请求
可以采用Ajax方式发送PUT和DELETE请求
1.3.2 @PathVariable
的URL是参数化的URL,可以使用URL的部分值作为请求参数。
@PathVariable注解则让这个功能成为现实。
它的作用在于将URL中的占位符的值传到所注解的变量上。
例如:localhost:8080/appName/7369
|
1.3.3 静态资源访问处理
采用RESTful架构后,需要将web.xml中控制器拦截的请求(url-parrten中)设置为 /,这样会将css,js等静态资源进行拦截,发送404错误。
解决方法:
--配置<mvc:resources/>
请求URI" location="资源位置" />
--配置<mvc:default-servlet-handler/>
<mvc:default-servlet-handler/>
例如:
|