REST风格
- REST简介
- 优点
- 行为动作区分操作
- 总结
- 注意事项
- RESTful
- RESTful实现
- 思路分析
- 代码实现
- 新增功能
- 删除功能
- 修改功能
- 查询功能
- 总结
- 快速开发—RESTful优化
- 优化方案
REST简介
- REST(Representational State Transfer),表现性状态转换,它是一种软件架构风格
表示网络资源的两种方式:
- 传统风格资源描述形式
http://localhost/user/getById?id=1 查询id为1的用户信息
http://localhost/user/saveUser 保存用户信息
- REST风格资源描述形式
优点
- 隐藏资源的访问行为,无法通过地址得知对资源是何种操作
- 书写简化
- 原因
- 传统方式一般是一个请求url对应一种操作,操作繁琐且不安全,在了解程序的人的眼中可能会通过url解读出相对于的操作
行为动作区分操作
按照REST风格访问资源时使用请求方式区分对资源进行了何种操作
- http://localhost/users 查询全部用户信息 GET(查询)
- http://localhost/users/1 查询指定用户信息 GET(查询)
- http://localhost/users 添加用户信息 POST(新增/保存)
- http://localhost/users 修改用户信息 PUT(修改/更新)
- http://localhost/users/1 删除用户信息 DELETE(删除)
总结
通常使用四种请求方式:
- 发送GET请求是用来做查询
- 发送POST请求是用来做新增
- 发送PUT请求是用来做修改
- 发送DELETE请求是用来做删除
注意事项
- 上述行为是约定方式,约定不是规范,可以打破,所以称REST风格,而不是REST规范。虽然不是规范,但现在基本都用rest风格。
- REST提供了对应的架构方式,按照这种架构设计项目可以降低开发的复杂性,提高系统的可伸缩性
- REST中规定GET/POST/PUT/DELETE针对的是查询/新增/修改/删除,但是我们如果非要用GET请求做删除,这点在程序上运行是可以实现的
- 但是如果绝大多数人都遵循这种风格,你写的代码让别人读起来就有点莫名其妙了。
- 描述模块的名称通常使用复数,也就是加s的格式描述,表示此类资源,而非单个资源,例如:users、books、accounts…
RESTful
根据REST风格对资源进行访问称为RESTful
RESTful实现
思路分析
需求:将之前的增删改查替换成RESTful的开发方式。
1.之前不同的请求有不同的路径,现在要将其修改为统一的请求路径
修改前: 新增: /save ,修改: /update,删除 /delete…
修改后: 增删改查: /users
2.根据GET查询、POST新增、PUT修改、DELETE删除对方法的请求方式进行限定
3.发送请求的过程中如何设置请求参数?
代码实现
主要通过 @RequestMapping的method属性,@PathVariable实现
新增功能
原方法
@Controller
public class UserController {
@RequestMapping("/save")
@ResponseBody
public String save(@RequestBody User user) {
System.out.println("user save..."+user);
return "{'module':'user save'}";
}
}
RESTful实现后
@Controller
public class UserController {
//设置当前请求方法为POST,表示REST风格中的添加操作
@RequestMapping(value = "/users",method = RequestMethod.POST)
@ResponseBody
public String save() {
System.out.println("user save...");
return "{'module':'user save'}";
}
}
删除功能
原方法
@Controller
public class UserController {
@RequestMapping("/delete")
@ResponseBody
public String delete(Integer id) {
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
}
RESTful实现后(有缺陷)
@Controller
public class UserController {
//设置当前请求方法为DELETE,表示REST风格中的删除操作
@RequestMapping(value = "/users",method = RequestMethod.DELETE)
@ResponseBody
public String delete(Integer id) {
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
}
缺陷:未携带需删除数据项的id
RESTful实现后(优化后 --通过@PathVariable)
@PathVariable译作可变路径,作用是声明这个参数来自于路径
@Controller
public class UserController {
//设置当前请求方法为DELETE,表示REST风格中的删除操作
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
//@PathVariable声明此参数来自于路径。使参数和@RequestMapping中路径中的参数绑定。如果名称不一样,需要起别名再绑定
public String delete(@PathVariable Integer id) {
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
}
1.当形参名和路径中{}中的值不一致时,需要起别名2.需要传递多个参数时,路径后加斜杠新增参数
@Controllerpublic class UserController {
//设置当前请求方法为DELETE,表示REST风格中的删除操作
@RequestMapping(value = "/users/{id}/{name}",method = >RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id,@PathVariable String name) >{
System.out.println("user delete..." + id+","+name);
return "{'module':'user delete'}";
}
}
修改功能
原方法
@Controller
public class UserController {
@RequestMapping("/update")
@ResponseBody
public String update(@RequestBody User user) {
System.out.println("user update..." + user);
return "{'module':'user update'}";
}
}
RESTful实现后
@Controller
public class UserController {
//设置当前请求方法为PUT,表示REST风格中的修改操作
@RequestMapping(value = "/users",method = RequestMethod.PUT)
@ResponseBody
public String update(@RequestBody User user) {
System.out.println("user update..." + user);
return "{'module':'user update'}";
}
}
查询功能
根据ID查询
原方法
@Controller
public class UserController {
@RequestMapping("/getById")
@ResponseBody
public String getById(Integer id) {
System.out.println("user getById..." + id);
return "{'module':'user getById'}";
}
}
RESTful实现后
@Controller
public class UserController {
//设置当前请求方法为GET,表示REST风格中的查询操作
@RequestMapping(value = "/users/{id}" ,method = RequestMethod.GET)
@ResponseBody
public String getById(@PathVariable Integer id){
System.out.println("user getById..."+id);
return "{'module':'user getById'}";
}
}
查询所有
原方法
@Controller
public class UserController {
@RequestMapping("/findAll")
@ResponseBody
public String getAll() {
System.out.println("user getAll...");
return "{'module':'user getAll'}";
}
}
RESTful实现后
@Controller
public class UserController {
//设置当前请求方法为GET,表示REST风格中的查询操作
@RequestMapping(value = "/users" ,method = RequestMethod.GET)
@ResponseBody
public String getAll() {
System.out.println("user getAll...");
return "{'module':'user getAll'}";
}
}
总结
(1)设定Http请求动作(动词)
@RequestMapping(value=“”,method = RequestMethod.POST|GET|PUT|DELETE)
(2)设定请求参数(路径变量)
@RequestMapping(value=“/users/{id}”,method = RequestMethod.DELETE)
@ReponseBody
public String delete(@PathVariable Integer id){
}
快速开发—RESTful优化
上述RESTful风格开发中的缺陷:
问题1:每个方法的@RequestMapping注解中都定义了访问路径/books,重复性太高。
问题2:每个方法的@RequestMapping注解中都要使用method属性定义请求方式,重复性太高。
问题3:每个方法响应json都需要加上@ResponseBody注解,重复性太高。
优化方案
- @RestController合并@Controller和@ResponseBody
- @GetMapping @PostMapping @PutMapping @DeleteMapping代替@RequestMapping(免除method的重复)
优化后各功能代码
@RestController //@Controller + ReponseBody
@RequestMapping("/books")
public class BookController {
//@RequestMapping(method = RequestMethod.POST)
@PostMapping
public String save(@RequestBody Book book){
System.out.println("book save..." + book);
return "{'module':'book save'}";
}
//@RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
@DeleteMapping("/{id}")
public String delete(@PathVariable Integer id){
System.out.println("book delete..." + id);
return "{'module':'book delete'}";
}
//@RequestMapping(method = RequestMethod.PUT)
@PutMapping
public String update(@RequestBody Book book){
System.out.println("book update..." + book);
return "{'module':'book update'}";
}
//@RequestMapping(value = "/{id}",method = RequestMethod.GET)
@GetMapping("/{id}")
public String getById(@PathVariable Integer id){
System.out.println("book getById..." + id);
return "{'module':'book getById'}";
}
//@RequestMapping(method = RequestMethod.GET)
@GetMapping
public String getAll(){
System.out.println("book getAll...");
return "{'module':'book getAll'}";
}
}
注解
名称 | @RestController |
类型 | 类注解 |
位置 | 基于SpringMVC的RESTful开发控制器类定义上方 |
作用 | 设置当前控制器类为RESTful风格,等同于@Controller与@ResponseBody两个注解组合功能 |
名称 | @GetMapping @PostMapping @PutMapping @DeleteMapping |
类型 | 方法注解 |
位置 | 基于SpringMVC的RESTful开发控制器方法定义上方 |
作用 | 设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作,例如@GetMapping对应GET请求 |
相关属性 | value(默认):请求访问路径 |