Spring Boot 如何处理 Web 请求,核心就是掌握 Controller 相关注解。
Spring Boot 处理 HTTP 请求,本质上就是:浏览器/前端发请求,Spring Boot 根据注解找到对应 Java 方法,然后执行方法并返回结果。
1. 一个 HTTP 请求长什么样?
比如浏览器访问:
http://localhost:8080/user?id=1001
这就是一个 HTTP 请求。
它里面有几个关键信息:
请求地址:/user
请求方法:GET
请求参数:id=1001
Spring Boot 要做的事情就是:
看到 /user 这个地址
找到对应的 Java 方法
把 id=1001 传给方法
方法执行后返回结果
2. 最核心的 Controller 写法
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@GetMapping("/hello")
public String hello() {
return "Hello Spring Boot";
}
}
访问:
http://localhost:8080/hello
返回:
Hello Spring Boot
这里出现了两个重要注解:
@RestController
@GetMapping
3. @RestController:声明这是一个接口类
@RestController
public class UserController {
}
它的意思是:
这个类是一个专门处理 HTTP 请求的类。
从 Python 角度理解,类似 Flask 里面写接口的地方:
@app.route("/hello")
def hello():
return "hello"
在 Spring Boot 里面,要先写一个类:
@RestController
public class HelloController {
}
然后在类里面写具体接口方法。
4. @GetMapping:处理 GET 请求
GET 请求一般用于查询数据。
例如:
@GetMapping("/user")
public String getUser() {
return "查询用户信息";
}
访问:
http://localhost:8080/user
返回:
查询用户信息
可以理解为:
@GetMapping("/user")
表示:
当前端访问 /user,并且请求方式是 GET 时,就执行下面这个 Java 方法。
5. @RequestParam:获取 URL 参数
例如访问:
http://localhost:8080/user?id=1001
后端代码:
@GetMapping("/user")
public String getUser(@RequestParam Integer id) {
return "用户ID是:" + id;
}
这里:
@RequestParam Integer id
表示从 URL 里面取出 id 参数。
对应关系是:
/user?id=1001
↓
@RequestParam Integer id
返回结果:
用户ID是:1001
多个参数
访问:
http://localhost:8080/user?name=Tom&age=18
代码:
@GetMapping("/user")
public String getUser(@RequestParam String name,
@RequestParam Integer age) {
return "姓名:" + name + ",年龄:" + age;
}
返回:
姓名:Tom,年龄:18
参数名不一致时
比如前端传的是:
/user?username=Tom
后端变量想叫 name:
@GetMapping("/user")
public String getUser(@RequestParam("username") String name) {
return "姓名:" + name;
}
这里:
@RequestParam("username")
表示从 URL 里面找 username,然后赋值给 Java 变量 name。
6. @PathVariable:获取路径参数
有时候参数不是放在 ? 后面,而是直接放在路径里。
例如:
http://localhost:8080/user/1001
代码:
@GetMapping("/user/{id}")
public String getUser(@PathVariable Integer id) {
return "用户ID是:" + id;
}
这里:
/user/{id}
表示路径中有一个变量 id。
@PathVariable Integer id
表示把路径中的 id 取出来。
对应关系:
/user/1001
↓
@PathVariable Integer id
@RequestParam 和 @PathVariable 的区别
| 写法 | 示例 | 用途 |
|---|---|---|
@RequestParam |
/user?id=1001 |
查询条件 |
@PathVariable |
/user/1001 |
资源定位 |
简单理解:
@RequestParam 更像"附加条件"
@PathVariable 更像"地址的一部分"
比如:
查询第1001号用户:
/user/1001
查询年龄为18岁的用户:
/user?age=18
7. @PostMapping:处理 POST 请求
POST 请求一般用于新增数据 。
例如前端提交一个用户:
{
"name": "Tom",
"age": 18
}
后端需要用:
@PostMapping
@RequestBody
8. @RequestBody:接收 JSON 数据
先定义一个实体类:
package com.example.demo.entity;
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
}
然后写 Controller:
package com.example.demo.controller;
import com.example.demo.entity.User;
import org.springframework.web.bind.annotation.*;
@RestController
public class UserController {
@PostMapping("/user")
public String addUser(@RequestBody User user) {
return "新增用户:" + user.getName() + ",年龄:" + user.getAge();
}
}
前端发送 JSON:
{
"name": "Tom",
"age": 18
}
Spring Boot 会自动把 JSON 转成 Java 对象:
JSON 数据
↓
User 对象
↓
user.getName()
user.getAge()
9. @RequestBody 和 @RequestParam 的区别
| 注解 | 接收位置 | 常见请求 |
|---|---|---|
@RequestParam |
URL 参数 | GET |
@RequestBody |
请求体 JSON | POST / PUT |
例如:
URL 参数
/user?name=Tom&age=18
使用:
@RequestParam String name
@RequestParam Integer age
JSON 请求体
{
"name": "Tom",
"age": 18
}
使用:
@RequestBody User user
10. @PutMapping:处理修改请求
PUT 一般表示更新数据。
@PutMapping("/user/{id}")
public String updateUser(@PathVariable Integer id,
@RequestBody User user) {
return "修改用户:" + id + ",新名字:" + user.getName();
}
请求路径:
PUT /user/1001
请求体:
{
"name": "Jerry",
"age": 20
}
含义:
修改 id 为 1001 的用户
新数据是 JSON 里的内容
11. @DeleteMapping:处理删除请求
DELETE 一般用于删除数据。
@DeleteMapping("/user/{id}")
public String deleteUser(@PathVariable Integer id) {
return "删除用户:" + id;
}
请求:
DELETE /user/1001
返回:
删除用户:1001
12. @RequestMapping:通用路径映射
@RequestMapping 可以放在类上,也可以放在方法上。
最常见的是放在类上,统一加路径前缀。
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public String getUser(@PathVariable Integer id) {
return "查询用户:" + id;
}
@PostMapping
public String addUser(@RequestBody User user) {
return "新增用户:" + user.getName();
}
}
实际访问路径是:
GET /api/users/1001
POST /api/users
因为类上有:
@RequestMapping("/api/users")
方法上有:
@GetMapping("/{id}")
所以合起来就是:
/api/users/{id}
13. 常见 Web 请求注解总结
| 注解 | 作用 |
|---|---|
@RestController |
声明接口控制类 |
@RequestMapping |
设置公共请求路径 |
@GetMapping |
处理 GET 请求 |
@PostMapping |
处理 POST 请求 |
@PutMapping |
处理 PUT 请求 |
@DeleteMapping |
处理 DELETE 请求 |
@RequestParam |
获取 URL 参数 |
@PathVariable |
获取路径参数 |
@RequestBody |
获取 JSON 请求体 |
@RequestHeader |
获取请求头 |
@CookieValue |
获取 Cookie |
初学阶段重点掌握前 9 个就够了。
14. 完整示例:用户接口
User.java
package com.example.demo.entity;
public class User {
private Integer id;
private String name;
private Integer age;
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
}
UserController.java
package com.example.demo.controller;
import com.example.demo.entity.User;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
// 查询用户:GET /api/users/1001
@GetMapping("/{id}")
public String getUser(@PathVariable Integer id) {
return "查询用户,id = " + id;
}
// 条件查询:GET /api/users?name=Tom
@GetMapping
public String searchUser(@RequestParam String name) {
return "根据姓名查询用户:" + name;
}
// 新增用户:POST /api/users
@PostMapping
public String addUser(@RequestBody User user) {
return "新增用户:" + user.getName() + ",年龄:" + user.getAge();
}
// 修改用户:PUT /api/users/1001
@PutMapping("/{id}")
public String updateUser(@PathVariable Integer id,
@RequestBody User user) {
return "修改用户:" + id + ",新名字:" + user.getName();
}
// 删除用户:DELETE /api/users/1001
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable Integer id) {
return "删除用户:" + id;
}
}
15. 用 REST 风格理解接口
Spring Boot 常见接口一般会设计成 REST 风格:
| 操作 | 请求方法 | 路径 | 含义 |
|---|---|---|---|
| 查询单个用户 | GET | /api/users/1001 |
查询 id 为 1001 的用户 |
| 查询用户列表 | GET | /api/users?name=Tom |
按条件查询 |
| 新增用户 | POST | /api/users |
新增一个用户 |
| 修改用户 | PUT | /api/users/1001 |
修改 id 为 1001 的用户 |
| 删除用户 | DELETE | /api/users/1001 |
删除 id 为 1001 的用户 |
也就是说:
路径表示资源
HTTP 方法表示动作
比如:
/user/1001
表示用户资源。
GET /user/1001 查询
PUT /user/1001 修改
DELETE /user/1001 删除
16. Controller、Service 的基本分层
刚开始可以把逻辑都写在 Controller 里,但实际项目一般这样分层:
Controller:接收请求
Service:处理业务逻辑
Mapper / Repository:操作数据库
例如:
前端请求
↓
Controller
↓
Service
↓
数据库
最简单的分层例子:
UserService.java
package com.example.demo.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public String getUserById(Integer id) {
return "这是从 Service 查询到的用户,id = " + id;
}
}
UserController.java
package com.example.demo.controller;
import com.example.demo.service.UserService;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/{id}")
public String getUser(@PathVariable Integer id) {
return userService.getUserById(id);
}
}
这里的:
public UserController(UserService userService) {
this.userService = userService;
}
表示 Spring Boot 自动把 UserService 对象传进来。
17. 你先重点记这几个搭配
查询
@GetMapping("/user/{id}")
public String getUser(@PathVariable Integer id) {
return "用户ID:" + id;
}
条件查询
@GetMapping("/user")
public String getUserByName(@RequestParam String name) {
return "用户姓名:" + name;
}
新增
@PostMapping("/user")
public String addUser(@RequestBody User user) {
return "新增用户:" + user.getName();
}
修改
@PutMapping("/user/{id}")
public String updateUser(@PathVariable Integer id,
@RequestBody User user) {
return "修改用户:" + id;
}
删除
@DeleteMapping("/user/{id}")
public String deleteUser(@PathVariable Integer id) {
return "删除用户:" + id;
}
18. 最小理解闭环
Spring Boot 处理 Web 请求,核心流程是:
1. 用户访问 URL
2. Spring Boot 根据 @GetMapping / @PostMapping 找方法
3. 用 @RequestParam / @PathVariable / @RequestBody 接收参数
4. 方法执行
5. 返回字符串、对象或 JSON
最需要掌握的是这套组合:
@RestController
@RequestMapping
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@RequestParam
@PathVariable
@RequestBody
其中最重要的三个参数注解是:
@RequestParam:接收 ?name=Tom 这种参数
@PathVariable:接收 /user/1001 这种路径参数
@RequestBody:接收 JSON 请求体
学会这部分,就已经能写最基本的 Spring Boot 后端接口了。