1、REST简介
- REST(Representational State Transfer)是一种基于HTTP协议的网络应用程序的架构风格,它强调客户端和服务器之间的交互操作,通过对资源的表现形式 进行操作来实现对资源的管理。REST 风格的 API 设计具有简单、灵活、可扩展等特点,因此在 Web 开发中得到了广泛应用。
1.1、表示一个网络资源的两种方式:
- 传统方式:
查询id为1的用户信息:
http://localhost/user/getById?id=1
保存用户信息:
http://localhost/user/saveUser
相对于REST风格:传统方式一般是一个请求url对应一种操作,这样做不仅麻烦,也不安全,因为会程序的人读取了你的请求url地址,就可利用大概知道该url实现的是一个什么样的操作。
- REST风格描述形式:
查询id为1的用户信息:
http://localhost/user/1
查询id为1的用户信息:
http://localhost/user
相对于传统方式:请求地址变的简单了,并且光看请求URL并不是很能猜出来该URL的具体功能。
-
REST风格的优缺点:
- 1)优点:
- 隐藏资源的访问行为,无法通过地址得知对资源是何种操作
- 书写简化
- 2)缺点:一个相同的url地址即可以是新增也可以是修改或者查询,因此会出现 难以区分该请求具体是什么操作 。
- 1)优点:
-
为了解决该缺点,按照REST风格访问资源时使用行为动作区分对资源进行了何种操作:
1. 查询全部用户信息 GET(查询):
http://localhost/users
5. 查询指定用户信息 GET(查询):
http://localhost/users/1
6. 添加用户信息 POST(新增/保存)
http://localhost/users
7. 修改用户信息 PUT(修改/更新):
http://localhost/users
8. 删除用户信息 DELETE(删除):
http://localhost/users/1
- 请求的方式比较多,但是比较常用的就4种,分别是:
- GET:表示查询
- POST:表示新增
- PUT:表示修改
- DELETE:表示删除
2、REST风格入门
如果不使用REST快速开发,RES风格和传统的springmvc设计的区别主要在表现层controller
2.1 传统方式下的controller
@Controller
public class UserController {
//新增
@RequestMapping("/save")
@ResponseBody
public String save(@RequestBody User user) {
System.out.println("user save..."+user);
return "{'module':'user save'}";
}
//删除
@RequestMapping("/delete")
@ResponseBody
public String delete(Integer id) {
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
//修改
@RequestMapping("/update")
@ResponseBody
public String update(@RequestBody User user) {
System.out.println("user update..." + user);
return "{'module':'user update'}";
}
//查询(带参)
@RequestMapping("/getById")
@ResponseBody
public String getById(Integer id) {
System.out.println("user getById..." + id);
return "{'module':'user getById'}";
}
//查询
@RequestMapping("/findAll")
@ResponseBody
public String getAll() {
System.out.println("user getAll...");
return "{'module':'user getAll'}";
}
}
- 主要使用到的注解:
-
- @Controller:@Controller是Spring框架中的一个注解,用于标识一个类为控制器。控制器负责接收请求并将请求转发给相应的处理程序进行处理,然后将处理结果返回给客户端。使用@Controller注解的类通常会配合其他注解一起使用,如@RequestMapping、@ResponseBody等。(设置该类为spring管理的bean)
- 2)@RequestMapping:设置当前控制器方法请求访问路径
- 3)@ResponseBody:设置当前控制器返回值作为响应体,写在类上,该类的所有方法都有该注解功能。
-
名称 | @Controller |
---|---|
类型 | 类注解 |
位置 | SpringMVC控制器类定义上方 |
作用 | 设定SpringMVC的核心控制器bean(相当于@Component) |
名称 | @RequestMapping |
---|---|
类型 | 类注解或方法注解 |
位置 | SpringMVC控制器类或方法定义上方 |
作用 | 设置当前控制器方法请求访问路径 |
相关属性 | value(默认),请求访问路径 |
名称 | @ResponseBody |
---|---|
类型 | 方法\类注解 |
位置 | SpringMVC控制器方法定义上方和控制类上 |
作用 | 设置当前控制器返回值作为响应体,写在类上,该类的所有方法都有该注解功能 |
相关属性 | pattern:指定日期时间格式字符串 |
2.2 REST风格下的controller
@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'}";
}
//设置当前请求方法为DELETE,表示REST风格中的删除操作
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id) {
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
//设置当前请求方法为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'}";
}
//设置当前请求方法为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'}";
}
//设置当前请求方法为GET,表示REST风格中的查询操作
@RequestMapping(value = "/users" ,method = RequestMethod.GET)
@ResponseBody
public String getAll() {
System.out.println("user getAll...");
return "{'module':'user getAll'}";
}
}
- 使用到的注解: @PathVariable:绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应
名称 | @PathVariable |
---|---|
类型 | 形参注解 |
位置 | SpringMVC控制器方法形参定义前面 |
作用 | 绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应 |
- 关于接收参数,我们学过三个注解@RequestBody、@RequestParam、@PathVariable ,这三个注解之间的区别和应用分别是什么?
区别:
- @RequestParam用于接收url地址传参或表单传参
- @RequestBody用于接收json数据
- @PathVariable用于接收路径参数,使用{参数名称}描述路径参数
应用:
- 后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广
- 如果发送非json格式数据,选用@RequestParam接收请求参数
- 采用RESTful进行开发,当参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量,通常用于传递id值
2.2.1 REST风格下的controller–传递路径参数
@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'}";
}
}
前端发送请求的时候使用:
http://localhost/users/1
路径中的1就是我们想要传递的参数。
后端获取参数,需要做如下修改:
修改@RequestMapping的value属性,将其中修改为/users/{id},目的是和路径匹配
在方法的形参前添加@PathVariable注解.
@Controller
public class UserController {
//设置当前请求方法为DELETE,表示REST风格中的删除操作
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id) {
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
}
- 问题:
-
1)如果方法形参的名称和路径{}中的值不一致,该怎么办?
-
2)如果有多个参数需要传递该如何编写?
-
前端发送请求的时候使用:
http://localhost/users/1/tom ,
路径中的1和tom就是我们想要传递的两个参数。
后端获取参数,需要做如下修改:
@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'}";
}
}
2.2.2 REST风格下的controller–总结
- (1)设定Http请求动作(动词)
@RequestMapping(value=“设置访问路径(一般为实体类名(如users …)”,method = RequestMethod.POST|GET|PUT|DELETE) - (2)设定请求参数(路径变量):路径变量应该和参数变量相同,如果不同需要使用@PathVariable(“参数名(要和路径参数一样)”)
@RequestMapping(value=“/users/{id}”,method = RequestMethod.DELETE)
@ReponseBody
public String delete(@PathVariable Integer id){
}
2、RESTful快速开发
- 观察上面的入门案例,会发现三个比较明显的问题:
- 1)每个方法的@RequestMapping注解中都定义了访问路径/books,重复性太高。
解决1:
- 1)每个方法的@RequestMapping注解中都定义了访问路径/books,重复性太高。
将@RequestMapping提到类上面,用来定义所有方法共同的访问路径。
- 2)每个方法的@RequestMapping注解中都要使用method属性定义请求方式,重复性太高。
解决2:
使用@GetMapping @PostMapping @PutMapping @DeleteMapping代替
- 3)每个方法响应json都需要加上@ResponseBody注解,重复性太高。
解决3:
1.将ResponseBody提到类上面,让所有的方法都有@ResponseBody的功能
2.使用@RestController注解替换@Controller与@ResponseBody注解,简化书写
2.1、RESTful快速开发–controller
@RestController //@Controller + ReponseBody
@RequestMapping("/books")
public class UserController {
//设置当前请求方法为POST,表示REST风格中的添加操作
//@RequestMapping(value = "/users",method = RequestMethod.POST)
//@ResponseBody
@PostMapping
public String save() {
System.out.println("user save...");
return "{'module':'user save'}";
}
//设置当前请求方法为DELETE,表示REST风格中的删除操作
//@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
//@ResponseBody
@DeleteMapping("/{id}")
public String delete(@PathVariable Integer id) {
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
//设置当前请求方法为PUT,表示REST风格中的修改操作
//@RequestMapping(value = "/users",method = RequestMethod.PUT)
//@ResponseBody
@PutMapping
public String update(@RequestBody User user) {
System.out.println("user update..." + user);
return "{'module':'user update'}";
}
//设置当前请求方法为GET,表示REST风格中的查询操作
//@RequestMapping(value = "/users/{id}" ,method = RequestMethod.GET)
//@ResponseBody
@GetMapping("/{id}")
public String getById(@PathVariable Integer id){
System.out.println("user getById..."+id);
return "{'module':'user getById'}";
}
//设置当前请求方法为GET,表示REST风格中的查询操作
//@RequestMapping(value = "/users" ,method = RequestMethod.GET)
//@ResponseBody
@GetMapping
public String getAll() {
System.out.println("user getAll...");
return "{'module':'user getAll'}";
}
}
名称 | @RestController |
---|---|
类型 | 类注解 |
位置 | 基于SpringMVC的RESTful开发控制器类定义上方 |
作用 | 设置当前控制器类为RESTful风格,等同于@Controller与@ResponseBody两个注解组合功能 |
- 请求:
- get:查询
- put:修改
- post:新增
- delete:删除
名称 | @GetMapping @PostMapping @PutMapping @DeleteMapping |
---|---|
类型 | 方法注解 |
位置 | 基于SpringMVC的RESTful开发控制器方法定义上方 |
作用 | 设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作,例如@GetMapping对应GET请求 |
相关属性 | value(默认):请求访问路径 |