DeleteMapping
本章紧接
@PutMapping的资源更新模式。在 RESTful 架构中,删除资源是 CRUD 操作的最后一个环节。@DeleteMapping是@RequestMapping(method = RequestMethod.DELETE)的语义化简写,它声明一个方法只处理 HTTP DELETE 请求,用于删除服务器上的资源。理解@DeleteMapping,就掌握了 Spring MVC 处理资源删除的标准方式,以及 DELETE 的幂等性特征。
定义与作用
@DeleteMapping 是 Spring 4.3 引入的方法级组合注解,它的职责可以用一句话概括:声明一个方法只处理 HTTP DELETE 请求,用于删除服务器上的资源。
@DeleteMapping 的源码定义:
@RequestMapping(method = RequestMethod.DELETE)
public @interface DeleteMapping {
// 继承 @RequestMapping 的所有属性
}
它与 @RequestMapping(method = RequestMethod.DELETE) 完全等价。
DELETE 请求的语义
在 HTTP 协议中,DELETE 方法的语义是删除资源,具有以下特征:
- 非安全:会改变服务器状态(删除资源)
- 幂等:多次删除同一个资源,结果与删除一次相同(删除后再次删除仍是"已删除"状态)
- 无请求体:DELETE 请求通常没有请求体(虽然规范不禁止,但大多数服务器忽略 DELETE 请求体)
- URL 指向具体资源:删除操作针对特定资源,URL 应包含资源标识符
核心原理
DELETE 请求的处理流程
图解:DELETE 请求通常不需要返回资源数据(资源已被删除),标准做法是返回 204 No Content。
DELETE vs POST 对比
| 对比维度 | DELETE | POST(错误用于删除) |
|---|---|---|
| 语义 | 删除资源 | 提交数据(语义不匹配) |
| 幂等性 | 幂等 | 非幂等 |
| 安全性 | 非安全 | 非安全 |
| 可缓存 | 不可缓存 | 不可缓存 |
| URL 风格 | /employees/1001 | /deleteEmployee?id=1001 |
| 浏览器预加载 | 不会触发 | 可能意外触发 |
适用位置与常用属性
@DeleteMapping 只能标注在方法上,继承 @RequestMapping 的所有属性:
| 属性 | 类型 | 作用 | 示例 |
|---|---|---|---|
value / path | String[] | URL 路径映射 | "/{id}" |
params | String[] | 约束请求参数 | "force=true" |
headers | String[] | 约束请求头 | "X-Api-Version=2" |
produces | String[] | 约束响应 Content-Type | "application/json" |
注意:DELETE 请求通常没有请求体,因此 consumes 属性很少使用。
完整示例
场景
飞翔科技的员工管理系统需要支持删除离职员工档案。HR 确认员工离职后,通过 DELETE 请求永久删除该员工数据。
控制器代码
package com.feixiang.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/employees")
public class EmployeeController {
// 容器已注入该 Bean,本教程不展开 Service 实现
@Autowired
private EmployeeService employeeService;
// 删除单个员工
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void delete(@PathVariable Long id) {
employeeService.delete(id);
}
// 批量删除员工
@DeleteMapping("/batch")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteBatch(@RequestParam List<Long> ids) {
employeeService.deleteAll(ids);
}
}
HTTP 请求示例 1:删除单个员工
curl -X DELETE http://localhost:8080/employees/1001
实际响应(HTTP 204 No Content):
HTTP/1.1 204 No Content
Date: Sat, 15 Jun 2024 11:30:00 GMT
分析:
@DeleteMapping("/{id}")声明此方法只处理 DELETE 请求@PathVariable提取 URL 中的id=1001@ResponseStatus(HttpStatus.NO_CONTENT)设置响应状态码为 204- 204 响应没有响应体,表示操作成功但无内容返回
- 这是 DELETE 操作的标准 HTTP 实践
HTTP 请求示例 2:幂等性验证
# 第一次 DELETE
curl -X DELETE http://localhost:8080/employees/1001
# 响应:204 No Content
# 第二次 DELETE(相同的资源已被删除)
curl -X DELETE http://localhost:8080/employees/1001
# 响应:204 No Content(或 404 Not Found)
分析:
- 两次 DELETE 请求,服务器最终状态一致(员工 1001 不存在)
- 这是 DELETE 的幂等性特征
- 具体返回 204 还是 404 取决于实现:
- 严格幂等:返回 204("确保资源不存在")
- 严格 REST:返回 404("资源已不存在")
- 两种做法都可以接受,但项目内应统一规范
易错场景与面试考点
误区一:用 GET 请求做删除
错误写法:
@GetMapping("/delete/{id}")
public void delete(@PathVariable Long id) {
employeeService.delete(id);
}
纠正:这是极其危险的做法。GET 请求可能被浏览器预加载、搜索引擎爬虫抓取、代理服务器缓存,导致资源被意外删除。
// 正确做法
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void delete(@PathVariable Long id) {
employeeService.delete(id);
}
真实案例:某电商网站使用 GET /order/cancel?id=123 取消订单,结果被搜索引擎爬虫批量访问,导致大量订单被误取消。
误区二:DELETE 返回 200 并携带被删除资源的数据
错误写法:
@DeleteMapping("/{id}")
public Employee delete(@PathVariable Long id) {
Employee deleted = employeeService.findById(id);
employeeService.delete(id);
return deleted; // 返回已删除的资源
}
纠正:DELETE 操作的标准响应是 204 No Content(无响应体)或 200 OK(带空体)。返回被删除资源的数据不符合 RESTful 规范,且可能泄露敏感信息。
// 正确做法
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void delete(@PathVariable Long id) {
employeeService.delete(id);
}
面试高频:DELETE 的幂等性与安全删除
标准回答:
- DELETE 用于删除资源,具有幂等性:多次删除同一个资源,结果与删除一次相同
- DELETE 的 URL 应指向具体资源(
/employees/1001),而非集合 - DELETE 通常返回 204 No Content,不返回响应体
- 绝对不能用 GET 做删除,因为 GET 可能被浏览器预加载、爬虫抓取、代理缓存
- 幂等性使得 DELETE 可以安全重试,网络超时后自动重发不会导致副作用
小结
@DeleteMapping 是 Spring MVC 处理 HTTP DELETE 请求的语义化注解,用于删除服务器上的资源。DELETE 具有幂等性,是 RESTful API 设计中资源删除的标准方式。在实际开发中,必须严格遵守"GET 只读、DELETE 删除"的语义边界,避免用 GET 做删除导致的安全事故。
本章与全局的关系:本章讲解了资源删除的映射注解。下一章"PathVariable"将讲解 RESTful URL 的核心参数绑定机制——@PathVariable,它是实现 /employees/1001 这种资源定位风格的关键。