搞懂 Spring 四大请求注解:@GetMapping/@PostMapping/@PutMapping/@DeleteMapping,CRUD 接口再也不写错

SSM 架构中 @GetMapping、@PostMapping、@PutMapping、@DeleteMapping 的区别和使用场景


先整明白一个事:这些注解到底在干嘛?

你打开浏览器,在地址栏输入 www.baidu.com 敲回车——这其实就是发了一个 GET 请求

换句话说,你每次访问网页,本质都是在跟服务器"说话"。你说的话就叫"请求",服务器回你的东西叫"响应"。

那问题来了——你每次跟服务器"说话"的目的不一样

  • 有时候你只是想看看东西(比如刷微博)
  • 有时候你想发点东西(比如发条朋友圈)
  • 有时候你想改点东西(比如编辑个人资料)
  • 有时候你想删点东西(比如删掉一条评论)

这些不同的"目的",在 HTTP 协议里就叫请求方法(HTTP Method)

Spring 框架用几个注解帮我们把"这个方法处理哪种请求"这件事标记清楚,就是这几个:

注解对应 HTTP 方法一句话说清楚
@GetMappingGET——从服务器拿数据
@PostMappingPOST——往服务器提交新数据
@PutMappingPUT改(全量)——把服务器上某个数据整体替换
@PatchMappingPATCH改(部分)——只改服务器上某个数据的几个字段
@DeleteMappingDELETE——删除服务器上的数据

你看到了,这玩意跟数据库的 CRUD(增删改查)一模一样,基本上一一对应。


先看最本质的区别(别跳过)

很多人觉得 GET 和 POST “差不多”,写代码的时候随便用——千万别这么干

GET 的特点

  1. 参数拼在 URL 后面,人人都能看见

    https://xxx.com/search?keyword=iPhone&page=2
    

    那个 ?keyword=iPhone&page=2 就是 GET 传参的方式。

  2. 有长度限制——浏览器和服务器对 URL 长度都有限制(一般 2KB~8KB),所以你不能用 GET 传一篇小作文。

  3. 会被浏览器缓存、会被收藏夹保存、会留在历史记录里

  4. 幂等性:你请求一次和请求一百次,结果一样(只是查数据,不改数据)。

  5. 敏感数据绝对不能走 GET,因为 URL 明文暴露在地址栏。

POST 的特点

  1. 参数放在请求体(Request Body)里,URL 上干干净净

    https://xxx.com/login
    

    账号密码在 body 里,不会出现在地址栏。

  2. 没有长度限制,理论上你想传多大传多大。

  3. 不会被浏览器缓存,不会被收藏夹保存。

  4. 非幂等:你提交两次,就可能创建两条重复数据。

  5. 传敏感数据(密码、身份证号等)走 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
  • 项目赶进度,能跑就行

面试的时候按"标准答案"说,干活的时候看团队规范。


总结:一张表收尾

注解干什么参数位置浏览器地址栏能发吗会被缓存吗频率
@GetMappingURL 后面最高
@PostMappingBody 里不能不会很高
@PutMapping改(全量)Body 里不能不会较低
@PatchMapping改(部分)Body 里不能不会很低
@DeleteMappingURL 或 Body不能不会一般

最后一个比喻,帮你彻底记住

把服务器想象成一个仓库管理员

  • GET:你喊"管理员,把3号货架的东西给我看看"——管理员拿给你看,仓库没变化
  • POST:你喊"管理员,这个东西帮我存进货架"——仓库多了一件东西
  • PUT:你喊"管理员,3号货架上的东西全部换成这个"——原来那个被整体替换
  • PATCH:你喊"管理员,3号货架上那个盒子的标签帮我改一下"——只改标签,盒子不动
  • DELETE:你喊"管理员,把3号货架上的东西扔了"——仓库少了一件东西
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值