本帖最后由 chenquanyi626 于 2017-11-21 16:08 编辑
1 REST概述
1.1 REST是什么
REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。 目前在三种主流的Web服务实现方案中,因为REST模式的Web服务与复杂的SOAP和XML-RPC对比来讲明显的更加简洁,越来越多的web服务开始采用REST风格设计和实现。例如,Amazon.com提供接近REST风格的Web服务进行图书查找;雅虎提供的Web服务也是REST风格的。 表述性状态转移是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是RESTful。需要注意的是,REST是设计风格而不是标准。REST通常基于使用HTTP,URI,和XML(标准通用标记语言下的一个子集)以及HTML(标准通用标记语言下的一个应用)这些现有的广泛流行的协议和标准。 REST 定义了一组体系架构原则,您可以根据这些原则设计以系统资源为中心的 Web 服务,包括使用不同语言编写的客户端如何通过 HTTP 处理和传输资源状态。 如果考虑使用它的 Web 服务的数量,REST 近年来已经成为最主要的 Web 服务设计模式。 事实上,REST 对 Web 的影响非常大,由于其使用相当方便,已经普遍地取代了基于 SOAP 和 WSDL 的接口设计。
1.2 RESTful是什么
一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。 RESTful对应的中文是REST式的。RESTful Web Service 是一种常见的REST的应用,是遵守了REST风格的web服务。Rest式的web服务是一种ROA(面向资源的架构)。
1.3 REST 架构的主要原则
REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。 Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由任何可用服务器回答,这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。 在服务器端,应用程序状态和功能可以分为各种资源。每个资源都使用 URI (Universal Resource Identifier) 得到一个唯一的地址。所有资源都共享统一的接口,以便在客户端和服务器之间传输状态。使用的是标准的 HTTP 方法,比如 GET、PUT、POST 和 DELETE。Hypermedia 是应用程序状态的引擎,资源表示通过超链接互联。
1.4 URI和URL 统一资源标识符(Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串。 URL(Uniform Resource Locator)统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。
1.5 HTTP无状态性HTTP无状态协议,是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。无状态性使得客户端和服务器端不必保存对方的详细信息,服务只需要处理当前Request,而不必了解Request的历史。从而可以更容易地释放资源。让服务器充分利用Pool技术来提高稳定性和性能。
1.6 资源操作的用法之前的操作: http://127.0.0.1/user/save POST 新增用户 http://127.0.0.1/user/update POST 修改用户信息 http://127.0.0.1/user/delete GET/POST 删除用户信息
RESTful用法:
1.7 REST接口定义
1.8 REST接口设计最佳实践
1.8.1 REST接口设计
URL的组成: --网络协议(http、 https)--服务器地址--接口名称--参数列表 URL定义限定 --不要使用大写字母--使用中间线 - 代替下划线 _--参数列表应该被encode过
1.8.2.REST设计之http请求响应设计规则
Content body 仅仅用来数据传输,数据要做到拿来就可用的原则,不需要“拆箱”的过程。用来描述数据或者请求元数据放到Header 中,例如:X-Result-Fields
1.8.3响应示例
错误: [Java] 纯文本查看 复制代码 1.{ "status": 200,
2. "data" :{ "firstName": "Brett",
3. "lastName":"McLaughlin"
4. }
5.}
正确: [AppleScript] 纯文本查看 复制代码 1. Response Headers:
2. Status : 200,
3. Response Body:
4. { "firstName": "Brett",
5. "lastName":"McLaughlin"
6. }
1.8.4.指定响应的属性字段无状态服务器应该允许客户端对数据按需提取。在请求头使用X-Result-Fields指定数据返回的字段集合。 例如:trade有trade_id,trade_name,trade_at 三个属性,客户端只需其中的trade_id与trade_name属性,那么请求头可以是:
Request Headers: 1. X-Result-Fields:trade_id,trade_name;
2 http响应状态码
HTTP状态码(HTTP Status Code)是用以表示网页 服务器HTTP响应状态的3位数字代码。它由 RFC 2616 规范定义的,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774、RFC 4918等规范扩展。
3 SpringMVC实现RESTful服务 在4.0后的版本中,spring 支持一下方式创建 REST 资源:
1. 控制器可以处理所有的 HTTP 方法,包含几个主要的 REST 方法:GET、POST、PUT、DELETE、 PATCH;
2. 借助 @PathVariable 注解,控制器能够处理参数化的 URL(将变量输入作为 URL 的一部分);
3. 借助 spring 的视图解析器,资源能够以多种方式进行表述
4. 可以使用 ContentNegotiatingViewResolver 来选择最适合客户端的表述;
5. 借助 @ResponseBody 注解和各种 HttpMethodConverter 实现,能够替换基于视图的渲染方式;
6. 类似地,@RequestBody 注解以及 HttpMethodConverter 实现可以将传入的 HTTP 数据转化为传 入控制器处理方法的 Java 对象;
7. 借助 RestTemplate ,spring 应用能够方便地使用 REST 资源。
3.1 查询资源
[JavaScript] 纯文本查看 复制代码 1.package com.cqy.ssm.usermanager.controller;
2.import java.util.List;
3.import org.springframework.beans.factory.annotation.Autowired;
4.import org.springframework.http.HttpStatus;
5.import org.springframework.http.ResponseEntity;
6.import org.springframework.stereotype.Controller;
7.import org.springframework.util.StringUtils;
8.import org.springframework.web.bind.annotation.PathVariable;
9.import org.springframework.web.bind.annotation.RequestMapping;
10.import org.springframework.web.bind.annotation.RequestMethod;
11.import org.springframework.web.bind.annotation.RequestParam;
12.
13.import com.cqy.ssm.usermanager.pojo.User;
14.import com.cqy.ssm.usermanager.service.UserService;
15.
16.@Controller
17.@RequestMapping("rest/user")
18.public class UserRestfulController {
19. @Autowired
20. public UserService userService;
21.
22. @RequestMapping(value = "{id}", method = RequestMethod.GET)
23. public ResponseEntity<User> queryUserById(@PathVariable("id") Long id) {
24. try {
25. if (id.longValue() < 1) {
26. // 400
27. return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
28. }
29. User user = userService.queryUserById(id);
30. if (user == null) {
31. // 资源不在 状态响应码404
32. return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
33. }
34. // 200
35. // return ResponseEntity.status(HttpStatus.OK).body(null);
36. return ResponseEntity.ok(null);
37.
38. } catch (Exception e) {
39. e.printStackTrace();
40. }
41. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(
42. null);
43. }
44.}
3.2.新增资源
[Java] 纯文本查看 复制代码 1.package com.cqy.ssm.usermanager.controller;
2.
3.import java.util.List;
4.
5.import org.springframework.beans.factory.annotation.Autowired;
6.import org.springframework.http.HttpStatus;
7.import org.springframework.http.ResponseEntity;
8.import org.springframework.stereotype.Controller;
9.import org.springframework.util.StringUtils;
10.import org.springframework.web.bind.annotation.PathVariable;
11.import org.springframework.web.bind.annotation.RequestMapping;
12.import org.springframework.web.bind.annotation.RequestMethod;
13.import org.springframework.web.bind.annotation.RequestParam;
14.
15.import com.cqy.ssm.usermanager.pojo.User;
16.import com.cqy.ssm.usermanager.service.UserService;
17.
18.@Controller
19.@RequestMapping("rest/user")
20.public class UserRestfulController {
21. @Autowired
22. public UserService userService;
23.
24. @RequestMapping(method = RequestMethod.POST)
25. public ResponseEntity<Void> saveUser(User user) {
26. try {
27. if (user == null || StringUtils.isEmpty(user.getUserName())) {
28. // 400
29. return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
30. }
31.
32. Boolean flag = userService.saveVIPUser(user);
33. if (flag) {
34. return ResponseEntity.status(HttpStatus.CREATED).build();
35. }
36. } catch (Exception e) {
37. e.printStackTrace();
38. }
39.
40. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
41.
42. }
43.}
测试:
|