Spring Boot学习笔记 07

0x01 SpringMVC 常用注解

@GetMapping等价于单独使用Get方法的**@RequestMapping**,比如下面代码:

1
2
3
4
5
@RequestMapping(value = "/queryStudentById2",method = RequestMethod.GET)
//该注解通过在查询数据的时候使用 -> 查询
public Object queryStudentById2() {
return "Ony GET Method";
}

可以写成:

1
2
3
4
5
@GetMapping(value = "/queryStudentById2") //相当于上一句话,只接收GET请求,如果请求方式不对会报405错误
//该注解通过在查询数据的时候使用 -> 查询
public Object queryStudentById2() {
return "Ony GET Method";
}

相当于上一句话,只接收GET请求,如果请求方式不对会报405错误。

同理的还有**@PostMapping**,比如下面的代码:

1
2
3
4
5
@RequestMapping(value = "/insert",method = RequestMethod.POST)
//该注解通常在新增数据的时候使用 -> 新增
public Object insert() {
return "Insert success";
}

则可以写成:

1
2
3
4
5
@PostMapping(value = "/insert") 
//该注解通常在新增数据的时候使用 -> 新增
public Object insert() {
return "Insert success";
}

除此之外还有**@DeleteMapping** ,@PutMapping:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//    @RequestMapping(value = "/delete",method = RequestMethod.DELETE)
@DeleteMapping(value = "/delete")//相当于上一句话
//该注解通常在删除数据的时候使用 -> 删除
public Object delete() {
return "delete Student";
}


// @RequestMapping(value = "/update",method = RequestMethod.PUT)
@PutMapping(value = "/update") //相当于上一句话
//该注解通常在修改数据的时候使用 -> 更新
public Object update() {
return "update student info1";
}

这样极大的简化了我们的代码。

0x02 RESTFul

REST(英文:Representational State Transfer,简称 REST) 一种互联网软件架构设计的风格,但它并不是标准,它只是提出了一组客户端和服务器 交互时的架构理念和设计原则,基于这种理念和原则设计的接口可以更简洁,更有层次,REST 这个词,是 Roy Thomas Fielding 在他 2000 年的博士论文中提出的。 任何的技术都可以实现这种理念,如果一个架构符合 REST 原则,就称它为 RESTFul 架 构

Spring boot 开发 RESTFul 主要是几个注解实现
(1) @PathVariable :获取 url 中的数据 ,该注解是实现 RESTFul 最主要的一个注解
(2) @PostMapping :接收和处理 Post 方式的请求
(3) @DeleteMapping :接收 delete 方式的请求,可以使用 GetMapping 代替
(4) @PutMapping :接收 put 方式的请求,可以用 PostMapping 代替
(5) @GetMapping :接收 get 方式的请求

RESTFul风格的代码好处有:
➢ 传递参数变简单了
➢ 服务提供者对外只提供了一个接口服务,而不是传统的 CRUD 四个接口

下面我们看代码,来实现RESTFul:

1
2
3
4
5
6
7
8
9
10
//    @RequestMapping(value = "/student/detail/{id}/{age}")
@GetMapping(value = "/student/detail/{id}/{age}")
public Object student1(@PathVariable("id") Integer id,
@PathVariable("age") Integer age) {
Map<String,Object> retMap = new HashMap<>();

retMap.put("id",id);
retMap.put("age",age);
return retMap;
}

我们在路径里面添加了**{id}{age}这两个变量,然后在下方通过注释@PathVariable来调用参数在路径中获取的值,传给变量id和age,然后就能在方法中使用所获取的值了。
这样我们在浏览器输入
http://localhost:8080/student/0101/28 **
就能把010128这两个值传入方法中进行调用。

和之前的写法进行对比:

1
2
3
4
5
6
7
@RequestMapping(value = "/student")
public Object student(Integer id,Integer age) {
Student student = new Student();
student.setId(id);
student.setAge(age);
return student;
}

通过这种方法的url写法为**http://localhost:8080/student?id=0101&age=28 **
显然前者更具有观赏性和实用性(而且更安全)。

但是这种方式也会出现冲突,因为在路径的填写时,并不能知道哪个是id哪个是age,所以我们在设计的时候,通常在RESTful风格中方法的请求方式会按增删改查的请求方式来区分,比如如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@RequestMapping(value = "/student/detail/{id}/{age}")
public Object student1(@PathVariable("id") Integer id,
@PathVariable("age") Integer age) {
Map<String,Object> retMap = new HashMap<>();

retMap.put("id",id);
retMap.put("age",age);
return retMap;
}

@RequestMapping(value = "/student/detail/{id}/{status}")
public Object student2(@PathVariable("id") Integer id,
@PathVariable("status") Integer status) {
Map<String,Object> retMap = new HashMap<>();

retMap.put("id",id);
retMap.put("status",status);
return retMap;
}

Student1和Student2方法调用路径时会报错,原因是发生冲突,因为路径传进来的时候无法区分最后是{age}还是{status},那怎么办呢?

方法一:
我们只需要在设计的时候避免这种情况发生,比如可以改成如下代码:

1
2
3
4
5
6
7
8
9
10

@RequestMapping(value = "/student/{id}/detail/{city}")
public Object student3(@PathVariable("id") Integer id,
@PathVariable("city") Integer city) {
Map<String,Object> retMap = new HashMap<>();

retMap.put("id",id);
retMap.put("city",city);
return retMap;
}

这样就能避免两种方法调用的路径相同而发生冲突了!

方法二:
还有一种方法就是通过改变注释来避免相同注释的冲突:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//    @RequestMapping(value = "/student/detail/{id}/{age}")
@GetMapping(value = "/student/detail/{id}/{age}")
public Object student1(@PathVariable("id") Integer id,
@PathVariable("age") Integer age) {
Map<String,Object> retMap = new HashMap<>();

retMap.put("id",id);
retMap.put("age",age);
return retMap;
}

// @RequestMapping(value = "/student/detail/{id}/{status}")
@DeleteMapping(value = "/student/detail/{id}/{status}")
public Object student2(@PathVariable("id") Integer id,
@PathVariable("status") Integer status) {
Map<String,Object> retMap = new HashMap<>();

retMap.put("id",id);
retMap.put("status",status);
return retMap;
}

从代码中我们发现,虽然路径是一样的,但是注释不一样,把原来的@RequestMapping换成了@GetMapping和@DeleteMapping,所以当路径一样时,Get方法和Delete方法所请求的路径是不一样的,这样也能避免冲突,但是相比于方法一还是不够好。