REST(Representational State Transfer),表现性状态转换,它是一种软件架构风格
表示网络资源的两种方式:
http://localhost/user/getById?id=1 查询id为1的用户信息
http://localhost/user/saveUser 保存用户信息
http://localhost/user/1
http://localhost/user
按照REST风格访问资源时使用请求方式区分对资源进行了何种操作
通常使用四种请求方式:
注意事项
- 上述行为是约定方式,约定不是规范,可以打破,所以称REST风格,而不是REST规范。虽然不是规范,但现在基本都用rest风格。
- REST提供了对应的架构方式,按照这种架构设计项目可以降低开发的复杂性,提高系统的可伸缩性
- REST中规定GET/POST/PUT/DELETE针对的是查询/新增/修改/删除,但是我们如果非要用GET请求做删除,这点在程序上运行是可以实现的
- 但是如果绝大多数人都遵循这种风格,你写的代码让别人读起来就有点莫名其妙了。
- 描述模块的名称通常使用复数,也就是加s的格式描述,表示此类资源,而非单个资源,例如:users、books、accounts…
根据REST风格对资源进行访问称为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.需要传递多个参数时,路径后加斜杠新增参数@Controller public 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风格开发中的缺陷:
问题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(默认):请求访问路径 |