乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • 第1章 SpringMVC概述与DispatcherServlet

    • 本章导读:Spring MVC概述与DispatcherServlet
    • Spring MVC 是什么
    • MVC 设计模式
    • 前端控制器模式
    • DispatcherServlet
    • 核心组件协作
  • 第2章 控制器与请求映射

    • 本章导读:控制器与请求映射
    • Controller
    • RestController
    • RequestMapping
    • GetMapping
    • PostMapping
    • PutMapping
    • DeleteMapping
    • PathVariable
    • RESTful
    • 请求映射原理
  • 第3章 请求参数获取与转换

    • 本章导读:请求参数获取与转换
    • RequestParam
    • RequestBody
    • RequestHeader
    • CookieValue
    • Model
    • ModelAttribute
    • 数据绑定原理
    • 数据校验
  • 第4章 响应数据与视图解析

    • 本章导读:响应数据与视图解析
    • ResponseBody
    • ResponseEntity
    • ModelAndView
    • ViewResolver
    • HttpMessageConverter
    • forward与redirect
  • 第5章 拦截器过滤器与跨域

    • 本章导读:拦截器、过滤器与跨域
    • HandlerInterceptor
    • WebMvcConfigurer
    • CrossOrigin
    • 登录验证实战
  • 第6章 文件上传与异常处理

    • 本章导读:文件上传与异常处理
    • MultipartFile
    • 文件下载
    • ExceptionHandler
    • ControllerAdvice
    • RestControllerAdvice
    • ResponseStatus
  • 第7章 高级特性与最佳实践

    • 本章导读:高级特性与最佳实践
    • SessionAttributes
    • SessionAttribute
    • RedirectAttributes
    • MockMvc测试
    • 国际化
    • 最佳实践
  • 第8章 扩展与异步机制

    • 本章导读:扩展与异步机制
    • 异步请求处理
    • 自定义参数解析器
    • 内容协商

PostMapping

本章紧接 @GetMapping 的只读查询模式。在 RESTful 架构中,创建资源是另一个核心操作。@PostMapping 是 @RequestMapping(method = RequestMethod.POST) 的语义化简写,它声明一个方法只处理 HTTP POST 请求,用于在服务器上创建新资源。理解 @PostMapping,就掌握了 Spring MVC 处理资源创建的标准方式。


定义与作用

@PostMapping 是 Spring 4.3 引入的方法级组合注解,它的职责可以用一句话概括:声明一个方法只处理 HTTP POST 请求,用于在服务器上创建新资源。

@PostMapping 的源码定义:

@RequestMapping(method = RequestMethod.POST)
public @interface PostMapping {
    // 继承 @RequestMapping 的所有属性
}

它与 @RequestMapping(method = RequestMethod.POST) 完全等价。

POST 请求的语义

在 HTTP 协议中,POST 方法的语义是提交数据、创建资源,具有以下特征:

  • 非安全:会改变服务器状态(创建资源)
  • 非幂等:多次执行可能创建多个资源
  • 不可缓存:默认情况下 POST 响应不可缓存
  • 参数在请求体中:通过请求体(body)传递数据,适合传输大量或复杂数据

核心原理

POST 请求的处理流程

图解:POST 请求通常携带请求体,@RequestBody 配合 HttpMessageConverter 将 JSON 反序列化为 Java 对象,这是创建资源的标准模式。

@GetMapping vs @PostMapping 对比


适用位置与常用属性

@PostMapping 只能标注在方法上,继承 @RequestMapping 的所有属性:

属性类型作用示例
value / pathString[]URL 路径映射"/employees"
paramsString[]约束请求参数"preview=true"
headersString[]约束请求头"X-Api-Version=2"
consumesString[]约束请求 Content-Type"application/json"
producesString[]约束响应 Content-Type"application/json"

注意:@PostMapping 已经固定了 method = POST。consumes 属性在 POST 请求中非常常用,用于限制接受的请求体格式。


完整示例

场景

飞翔科技的员工管理系统需要支持创建新员工。HR 通过前端表单提交员工信息,后端使用 @PostMapping 接收并保存。

控制器代码

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;

    // 创建新员工
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public Employee create(@RequestBody Employee employee) {
        return employeeService.save(employee);
    }

    // 批量创建员工
    @PostMapping("/batch")
    public List<Employee> createBatch(@RequestBody List<Employee> employees) {
        return employeeService.saveAll(employees);
    }
}

HTTP 请求示例 1:创建单个员工

curl -X POST http://localhost:8080/employees \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "name": "王强",
    "department": "技术部",
    "position": "初级工程师",
    "email": "wangqiang@feixiang.com",
    "phone": "13800138003"
  }'

实际响应(HTTP 201 Created):

{
  "id": 1003,
  "name": "王强",
  "department": "技术部",
  "position": "初级工程师",
  "email": "wangqiang@feixiang.com",
  "phone": "13800138003",
  "createdAt": "2024-06-15T10:30:00"
}

分析:

  • @PostMapping 声明此方法只处理 POST 请求
  • @RequestBody 将请求体 JSON 反序列化为 Employee 对象
  • @ResponseStatus(HttpStatus.CREATED) 设置响应状态码为 201(资源创建成功)
  • Service 保存后返回带 id 和 createdAt 的完整对象

HTTP 请求示例 2:错误的 GET 请求

curl -X GET http://localhost:8080/employees \
  -H "Accept: application/json"

实际响应(HTTP 405 Method Not Allowed):

{
  "timestamp": "2024-06-15T10:35:00",
  "status": 405,
  "error": "Method Not Allowed",
  "message": "Request method 'GET' not supported",
  "path": "/employees"
}

分析:

  • /employees 的 POST 映射和 GET 映射是独立的 HandlerMapping 条目
  • GET 请求命中 listAll()(如果有 @GetMapping),但此处示例中如果只有 @PostMapping,则返回 405
  • 这体现了 RESTful 设计中"同一 URL,不同方法,不同语义"的原则

易错场景与面试考点

误区一:用 POST 做全量更新

错误写法:

@PostMapping("/{id}")
public Employee update(@PathVariable Long id,
                       @RequestBody Employee employee) {
    return employeeService.update(id, employee);
}

纠正:全量更新应该使用 @PutMapping,POST 只用于创建。HTTP 方法的语义是 RESTful API 设计的核心:

// 正确做法
@PutMapping("/{id}")
public Employee update(@PathVariable Long id,
                       @RequestBody Employee employee) {
    return employeeService.update(id, employee);
}

误区二:POST 请求忘记设置 Content-Type

错误请求:

curl -X POST http://localhost:8080/employees \
  -d '{"name":"王强"}'
# 未设置 Content-Type,默认 application/x-www-form-urlencoded

纠正:发送 JSON 数据时必须显式设置 Content-Type: application/json,否则 Spring MVC 无法正确反序列化:

curl -X POST http://localhost:8080/employees \
  -H "Content-Type: application/json" \
  -d '{"name":"王强"}'

如果 Controller 标注了 consumes = "application/json",未设置 Content-Type 的请求会直接返回 415 Unsupported Media Type。

面试高频:GET 与 POST 的区别

标准回答:

  • GET 用于读取资源,POST 用于创建资源
  • GET 参数在 URL 中(查询字符串),POST 参数在请求体中
  • GET 是安全和幂等的,POST 不是
  • GET 可缓存,POST 默认不可缓存
  • GET 有 URL 长度限制(约 2048 字符),POST 没有
  • 敏感数据必须用 POST(避免暴露在 URL 中)

小结

@PostMapping 是 Spring MVC 处理 HTTP POST 请求的语义化注解,用于在服务器上创建新资源。它是 @RequestMapping(method = RequestMethod.POST) 的简写形式,通常与 @RequestBody 配合使用,将请求体 JSON 反序列化为 Java 对象。

本章与全局的关系:本章讲解了资源创建的映射注解。下一章"PutMapping"将讲解用于全量更新的 @PutMapping,以及 PUT 与 POST 的核心区别。

上一页
GetMapping
下一页
PutMapping