SSM 架构中 @GetMapping、@PostMapping、@PutMapping、@DeleteMapping 的区别和使用场景
先整明白一个事:这些注解到底在干嘛?
你打开浏览器,在地址栏输入 www.baidu.com 敲回车——这其实就是发了一个 GET 请求。
换句话说,你每次访问网页,本质都是在跟服务器"说话"。你说的话就叫"请求",服务器回你的东西叫"响应"。
那问题来了——你每次跟服务器"说话"的目的不一样:
- 有时候你只是想看看东西(比如刷微博)
- 有时候你想发点东西(比如发条朋友圈)
- 有时候你想改点东西(比如编辑个人资料)
- 有时候你想删点东西(比如删掉一条评论)
这些不同的"目的",在 HTTP 协议里就叫请求方法(HTTP Method)。
Spring 框架用几个注解帮我们把"这个方法处理哪种请求"这件事标记清楚,就是这几个:
| 注解 | 对应 HTTP 方法 | 一句话说清楚 |
|---|---|---|
@GetMapping | GET | 查——从服务器拿数据 |
@PostMapping | POST | 增——往服务器提交新数据 |
@PutMapping | PUT | 改(全量)——把服务器上某个数据整体替换 |
@PatchMapping | PATCH | 改(部分)——只改服务器上某个数据的几个字段 |
@DeleteMapping | DELETE | 删——删除服务器上的数据 |
你看到了,这玩意跟数据库的 CRUD(增删改查)一模一样,基本上一一对应。
先看最本质的区别(别跳过)
很多人觉得 GET 和 POST “差不多”,写代码的时候随便用——千万别这么干。
GET 的特点
-
参数拼在 URL 后面,人人都能看见
https://xxx.com/search?keyword=iPhone&page=2那个
?keyword=iPhone&page=2就是 GET 传参的方式。 -
有长度限制——浏览器和服务器对 URL 长度都有限制(一般 2KB~8KB),所以你不能用 GET 传一篇小作文。
-
会被浏览器缓存、会被收藏夹保存、会留在历史记录里。
-
幂等性:你请求一次和请求一百次,结果一样(只是查数据,不改数据)。
-
敏感数据绝对不能走 GET,因为 URL 明文暴露在地址栏。
POST 的特点
-
参数放在请求体(Request Body)里,URL 上干干净净
https://xxx.com/login账号密码在 body 里,不会出现在地址栏。
-
没有长度限制,理论上你想传多大传多大。
-
不会被浏览器缓存,不会被收藏夹保存。
-
非幂等:你提交两次,就可能创建两条重复数据。
-
传敏感数据(密码、身份证号等)走 POST——虽然 body 也不是绝对安全(还得上 HTTPS),但至少不会在地址栏裸奔。
一句话口诀
GET 是明信片,POST 是信封。
明信片(GET)谁都能看见内容,但有字数限制;
信封(POST)外面看不到里面,能塞的东西也多。
但这不代表信封(POST)就绝对安全——真正保密还得靠 HTTPS(相当于给信封上了个锁)。
逐个讲透
1. @GetMapping —— 查数据用的
使用场景:
- 输入网址访问页面(比如首页
"/"或"/index") - 搜索、分页查询(
"/user/list?page=1") - 查看某条详情(
"/user/detail/5") - 任何"只是看看不改变服务器数据"的操作
代码示例:
@RestController
@RequestMapping("/user")
public class UserController {
// 场景1:查所有用户列表
@GetMapping("/list")
public List<User> list() {
return userService.findAll();
}
// 场景2:查某个用户详情,id 放在路径里
@GetMapping("/detail/{id}")
public User detail(@PathVariable Long id) {
return userService.findById(id);
}
// 场景3:分页查询,参数拼在 URL 后面
@GetMapping("/page")
public Page<User> page(@RequestParam int page,
@RequestParam int size) {
return userService.findPage(page, size);
}
}
访问方式:
- 浏览器直接输入地址
- 点击
<a>标签链接 window.location.href跳转- Ajax/axios 的
method: 'GET'
2. @PostMapping —— 新增数据用的
使用场景:
- 用户注册(新增一条用户记录)
- 发表评论、发帖、上传文件
- 登录验证(虽然不一定是新增数据,但传敏感信息必须用 POST)
- 任何"提交数据让服务器创建新资源"的操作
代码示例:
@RestController
@RequestMapping("/user")
public class UserController {
// 场景1:新增用户,前端把 JSON 数据放在 body 里传过来
@PostMapping("/add")
public Result add(@RequestBody User user) {
userService.save(user);
return Result.success("新增成功");
}
// 场景2:用户登录——虽然没新增数据,但传密码必须用 POST
@PostMapping("/login")
public Result login(@RequestBody LoginDTO dto) {
String token = userService.login(dto.getUsername(), dto.getPassword());
return Result.success(token);
}
// 场景3:批量导入
@PostMapping("/batchImport")
public Result batchImport(@RequestBody List<User> userList) {
userService.saveBatch(userList);
return Result.success();
}
}
访问方式:
- HTML 的
<form method="post">提交 - Ajax/axios 的
method: 'POST' - Postman/Apipost 等工具测试
注意: 你不能直接在浏览器地址栏发 POST 请求,地址栏只能发 GET。
3. @PutMapping —— 整体修改数据用的
使用场景:
- 编辑某个资源,把整条数据全部替换(用得相对少)
- 更新个人信息(如果前端把完整对象传过来)
- RESTful 风格的更新操作
代码示例:
@RestController
@RequestMapping("/user")
public class UserController {
// PUT 更新:要求前端把完整对象传过来,全部字段一起改
@PutMapping("/update/{id}")
public Result update(@PathVariable Long id,
@RequestBody User user) {
user.setId(id);
userService.updateById(user); // 整条记录全量替换
return Result.success("更新成功");
}
}
PUT 和 PATCH 的区别(很重要!)
打个比方:你有一份个人简历。
- PUT = 你把整份简历扔了,重新写一份全新的交上去
- PATCH = 你只把手机号那一栏涂掉改一下,其他不动
PUT 发过去的数据:
{
"username": "张三",
"age": 25,
"email": "zhangsan@qq.com", // 完整对象,没提到的字段会被清空/覆盖
"phone": "13800000000"
}
PATCH 发过去的数据:
{
"phone": "13800000001" // 只改手机号,其他字段不动
}
个人感觉国内很多项目偷懒,不管全量更新还是部分更新,统统用 POST 一把梭。你会发现很多公司代码里根本没有 PUT 和 PATCH,全是 POST。这算一种"行业潜规则",知道就行,面试的时候能说清楚 PUT/PATCH 的区别很重要。
4. @PatchMapping —— 部分修改数据用的
使用场景:
- 只改某个资源的某几个字段(比如只改手机号)
- 局部更新操作
代码示例:
@RestController
@RequestMapping("/user")
public class UserController {
// PATCH 部分更新:只传要改的字段
@PatchMapping("/update/{id}")
public Result patchUpdate(@PathVariable Long id,
@RequestBody Map<String, Object> fields) {
userService.updateFields(id, fields); // 只更新 map 里有值的字段
return Result.success("部分更新成功");
}
}
实际开发中 PATCH 用得最少,很多团队直接 POST 搞定。但要知道有这个东西。
5. @DeleteMapping —— 删除数据用的
使用场景:
- 删除某条记录(比如删帖、删评论)
- 批量删除
- 取消订单、注销账号
代码示例:
@RestController
@RequestMapping("/user")
public class UserController {
// 场景1:按 ID 删单个
@DeleteMapping("/delete/{id}")
public Result delete(@PathVariable Long id) {
userService.removeById(id);
return Result.success("删除成功");
}
// 场景2:批量删除,ID 列表放在 body 里传过来
@DeleteMapping("/batchDelete")
public Result batchDelete(@RequestBody List<Long> ids) {
userService.removeByIds(ids);
return Result.success("批量删除成功");
}
}
关于 DELETE 的一个小争议:
严格 RESTful 规范里,DELETE 不应该带 body,应该把参数放 URL 里。但批量删的时候 ID 太多,URL 放不下,所以很多人还是走 body。这属于"理论跟实践的差距",你自己看着办。
@RequestMapping 是它们的"爸爸"
这几个注解其实都是 @RequestMapping 的"快捷方式":
// 这两行完全等价
@GetMapping("/list")
@RequestMapping(value = "/list", method = RequestMethod.GET)
// 这两行也完全等价
@PostMapping("/add")
@RequestMapping(value = "/add", method = RequestMethod.POST)
所以:
@GetMapping=@RequestMapping(method = GET)的简写@PostMapping=@RequestMapping(method = POST)的简写@PutMapping=@RequestMapping(method = PUT)的简写@PatchMapping=@RequestMapping(method = PATCH)的简写@DeleteMapping=@RequestMapping(method = DELETE)的简写
为什么要有这些"简写"?因为 @RequestMapping 太啰嗦了,Spring 4.3 之后引入了这几个语义更明确的注解,一眼就知道这个接口是干嘛的。
实际开发中怎么选?一张图搞定
需求:只是看看/查数据 → 用 @GetMapping
需求:提交新数据(注册/发帖/上传) → 用 @PostMapping
需求:传敏感信息(登录密码) → 必须用 @PostMapping
需求:整体修改一条数据 → 用 @PutMapping(规范)或用 @PostMapping(偷懒)
需求:只改某几个字段 → 用 @PatchMapping(规范)或用 @PostMapping(偷懒)
需求:删除数据 → 用 @DeleteMapping
常见误区
误区一:GET 请求也能增删改数据?
技术上可行——你完全可以写一个 @GetMapping("/deleteUser") 然后在里面执行删除逻辑。但这严重违反规范,而且有安全隐患:
- 搜索引擎爬虫爬到你网站,顺着链接就帮你把数据全删了
- 用户把链接收藏了,每次打开收藏夹就莫名其妙删一条数据
- 浏览器预加载机制可能在你不知情的情况下触发请求
记住:GET 请求只能用来读数据,绝对不能写数据。
误区二:POST 比 GET 安全?
POST 只是不把参数暴露在 URL 上,但 body 里的数据如果不走 HTTPS,在传输过程中照样是明文,一样能被抓包看到。
POST = 数据不在地址栏裸奔 ≠ 数据加密了。加密靠 HTTPS,不靠 POST。
误区三:表单只能用 POST?
HTML 的 <form> 标签默认支持 GET 和 POST 两种:
<form method="get" action="/search"> <!-- GET 提交 -->
<form method="post" action="/login"> <!-- POST 提交 -->
而 PUT、PATCH、DELETE,HTML 表单原生不支持,需要通过 Ajax 或者在表单里加一个 _method 隐藏字段来模拟(Spring 的 HiddenHttpMethodFilter 就是这样干的)。
误区四:RESTful 风格必须严格用这五种方法?
理论上:"查增改删"分别对应 GET、POST、PUT、DELETE,很优雅。
实际上:很多公司的项目里,增删改全用 POST,只有查询用 GET。原因是:
- 前后端分离时,前端同学不想记这么多方法
- 某些老旧的网络代理/防火墙只放行 GET 和 POST
- 项目赶进度,能跑就行
面试的时候按"标准答案"说,干活的时候看团队规范。
总结:一张表收尾
| 注解 | 干什么 | 参数位置 | 浏览器地址栏能发吗 | 会被缓存吗 | 频率 |
|---|---|---|---|---|---|
@GetMapping | 查 | URL 后面 | 能 | 会 | 最高 |
@PostMapping | 增 | Body 里 | 不能 | 不会 | 很高 |
@PutMapping | 改(全量) | Body 里 | 不能 | 不会 | 较低 |
@PatchMapping | 改(部分) | Body 里 | 不能 | 不会 | 很低 |
@DeleteMapping | 删 | URL 或 Body | 不能 | 不会 | 一般 |
最后一个比喻,帮你彻底记住
把服务器想象成一个仓库管理员:
- GET:你喊"管理员,把3号货架的东西给我看看"——管理员拿给你看,仓库没变化
- POST:你喊"管理员,这个东西帮我存进货架"——仓库多了一件东西
- PUT:你喊"管理员,3号货架上的东西全部换成这个"——原来那个被整体替换
- PATCH:你喊"管理员,3号货架上那个盒子的标签帮我改一下"——只改标签,盒子不动
- DELETE:你喊"管理员,把3号货架上的东西扔了"——仓库少了一件东西

3781

被折叠的 条评论
为什么被折叠?



