REST(Representational State Transfer,表现形式状态转换)是一种访问网络资源的格式。传统的资源描述方式通常如下:
- http://localhost/user/getById?id=1
- http://localhost/user/saveUser
而 REST 风格的描述则更简洁:
- http://localhost/user/1
- http://localhost/user
采用 REST 风格的优势包括:
- 隐藏资源访问的具体行为,使得从 URL 无法判断对资源的操作类型
- 简化书写,提高可读性
在 REST 风格中,通过行为动作来区分对资源的操作类型:
url | 含义 | 动作 |
---|---|---|
http://localhost/users | 查询全部用户信息 | GET(查询) |
http://localhost/users/1 | 查询指定用户信息 | GET(查询) |
http://localhost/users | 添加用户信息 | POST(新增/保存) |
http://localhost/users | 修改用户信息 | PUT(修改/更新) |
http://localhost/users/1 | 删除用户信息 | DELETE(删除) |
上述行为是一种约定,而非严格的规范,因此称为 REST 风格,而不是 REST 规范。在描述模块名称时,通常使用复数形式(即加 “s”),以表示这一类资源,而非单个资源,例如:users、books、accounts 等。
根据 REST 风格对资源进行访问的方式称为
RESTful
快速入门
REST 风格通常包含两个步骤:
- 设定 HTTP 请求动作(动词):通过
@RequestMapping
注解的 method 参数来指定。 - 设定请求参数(路径变量):通过
@PathVariable
注解来定义路径变量。
以下是使用 REST 风格的代码示例:
java">@Controller
public class UserController {@RequestMapping(value = "/users", method = RequestMethod.POST)@ResponseBodypublic String save() {System.out.println("user save ...");return "{'module': 'user save'}";}@RequestMapping(value = "/users/{id}", method = RequestMethod.DELETE)@ResponseBodypublic String delete(@PathVariable Integer id) {System.out.println("user delete ..." + id);return "{'module': 'user delete'}";}@RequestMapping(value = "/users", method = RequestMethod.PUT)@ResponseBodypublic String update(@RequestBody User user) {System.out.println("user update ..." + user);return "{'module': 'user update'}";}@RequestMapping(value = "/users/{id}", method = RequestMethod.GET)@ResponseBodypublic String getById(@PathVariable Integer id) {System.out.println("user getById ..." + id);return "{'module': 'user getById'}";}@RequestMapping(value = "/users", method = RequestMethod.GET)@ResponseBodypublic String getAll() {System.out.println("user getAll ...");return "{'module': 'user getAll'}";}
}
@RequestBody vs @RequestParam vs @PathVariable
-
区别
@RequestParam
:用于接收 url 地址传参或表单传参@RequestBody
:用于接收 JSON 数据@PathVariable
:用于接收路径参数,使用{参数名称}
描述路径参数
-
应用
- 后期开发中,发送请求参数超过 1 个时,以 JSON 格式为主,
@RequestBody
应用较广 - 若发送非 JSON 格式数据,选用
@RequestParam
接收请求参数 - 采用
RESTful
开发,当参数数量较少,例如1个,可采用@PathVariable
接收请求路径变量,通常用于传递 id 值
- 后期开发中,发送请求参数超过 1 个时,以 JSON 格式为主,
代码优化
从上面的 RESTful 风格代码中,可以看到一些冗余之处,例如每个方法都使用了 @ResponseBody
注解,并且每个方法的 @RequestMapping
都以 /users
为前缀。为了减少代码的重复性,可以将 @ResponseBody
和 @RequestMapping("/users")
注解统一放置在类定义上,并利用特定的动作注解替代方法中的 @RequestMapping
。
另外,使用 @RestController
注解可以将当前控制器类设置为 RESTful 风格,这个注解等同于 @Controller
和 @ResponseBody
的组合。因此,可以用 @RestController
来代替这两个注解,从而简化代码。
java">//@Controller
//@ResponseBody
@RestController
@RequestMapping("/users")
public class UserController {@PostMappingpublic String save() {System.out.println("user save ...");return "{'module': 'user save'}";}@DeleteMapping("/{id}")public String delete(@PathVariable Integer id) {System.out.println("user delete ..." + id);return "{'module': 'user delete'}";}@PutMappingpublic String update(@RequestBody User user) {System.out.println("user update ..." + user);return "{'module': 'user update'}";}@GetMapping("/{id}")public String getById(@PathVariable Integer id) {System.out.println("user getById ..." + id);return "{'module': 'user getById'}";}@GetMappingpublic String getAll() {System.out.println("user getAll ...");return "{'module': 'user getAll'}";}
}