Spring Boot GET/POST/PUT/DELETE 请求映射:@GetMapping 等组合注解
Spring Boot GET/POST/PUT/DELETE 请求映射GetMapping 等组合注解一、引言在 RESTful API 开发中HTTP 方法与资源操作的映射是核心设计原则GET 用于查询、POST 用于创建、PUT 用于全量更新、DELETE 用于删除。Spring Boot 4.3 引入GetMapping、PostMapping等组合注解简化了传统RequestMapping(method ...)的冗余写法让代码更直观、可读性更强。本文将深入解析这些注解的用法、原理及实战场景帮助开发者快速掌握 Spring Boot 请求映射的核心技巧。二、技术背景2.1 RESTful API 与 HTTP 方法RESTful API 基于 HTTP 协议设计通过不同方法表达资源操作语义GET获取资源幂等、安全如查询用户列表。POST创建资源非幂等如新增用户。PUT全量更新资源幂等如替换用户所有字段。DELETE删除资源幂等如删除指定用户。2.2 Spring MVC 注解演进传统 Spring MVC 使用RequestMapping定义映射需显式指定method属性RequestMapping(value/users,methodRequestMethod.GET)// 冗长Spring 4.3 为简化开发推出组合注解将RequestMapping与方法绑定GetMappingRequestMapping(method RequestMethod.GET)PostMappingRequestMapping(method RequestMethod.POST)PutMappingRequestMapping(method RequestMethod.PUT)DeleteMappingRequestMapping(method RequestMethod.DELETE)三、应用使用场景注解核心场景特点GetMapping查询资源单条/列表、条件过滤幂等、安全不修改资源PostMapping创建资源、提交表单、复杂查询非幂等多次调用可能创建多个资源PutMapping全量更新资源需传递所有字段幂等多次调用结果一致DeleteMapping删除资源单个/批量幂等多次删除同一资源结果一致四、不同场景下详细代码实现4.1 项目基础配置依赖pom.xml仅需spring-boot-starter-web内置 Jackson 处理 JSON。实体类User.javapackagecom.example.demo.entity;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importjavax.validation.constraints.NotBlank;importjavax.validation.constraints.NotNull;DataNoArgsConstructorAllArgsConstructorpublicclassUser{privateLongid;NotBlank(message用户名不能为空)privateStringusername;NotBlank(message邮箱不能为空)privateStringemail;NotNull(message年龄不能为空)privateIntegerage;}4.2 GetMapping查询资源场景1查询所有用户RestControllerRequestMapping(/api/users)publicclassUserController{privatefinalListUserusersnewArrayList();// 模拟数据库// 初始化测试数据publicUserController(){users.add(newUser(1L,zhangsan,zhangsanexample.com,20));users.add(newUser(2L,lisi,lisiexample.com,22));}// 查询所有用户GetMappingpublicListUsergetAllUsers(){returnusers;}}场景2查询单个用户路径变量// 根据 ID 查询用户路径变量GetMapping(/{id})publicUsergetUserById(PathVariableLongid){returnusers.stream().filter(u-u.getId().equals(id)).findFirst().orElseThrow(()-newRuntimeException(用户不存在));}场景3条件查询请求参数// 按年龄范围查询请求参数GetMapping(/search)publicListUsersearchUsers(RequestParam(requiredfalse)IntegerminAge,RequestParam(requiredfalse)IntegermaxAge){returnusers.stream().filter(u-minAgenull||u.getAge()minAge).filter(u-maxAgenull||u.getAge()maxAge).collect(Collectors.toList());}4.3 PostMapping创建资源场景1创建单个用户JSON 请求体// 创建用户接收 JSON 请求体PostMappingpublicUsercreateUser(ValidRequestBodyUseruser){// Valid 触发参数校验user.setId((long)(users.size()1));// 模拟 ID 自增users.add(user);returnuser;// 返回创建的用户含 ID}场景2批量创建用户// 批量创建用户数组请求体PostMapping(/batch)publicListUserbatchCreateUsers(ValidRequestBodyListUseruserList){userList.forEach(u-{u.setId((long)(users.size()1));users.add(u);});returnuserList;}4.4 PutMapping全量更新资源场景全量更新用户信息需传递所有字段// 全量更新用户需传递所有字段否则未传字段会被置为 nullPutMapping(/{id})publicUserupdateUser(PathVariableLongid,ValidRequestBodyUseruser){UserexistingUserusers.stream().filter(u-u.getId().equals(id)).findFirst().orElseThrow(()-newRuntimeException(用户不存在));// 替换所有字段包括可能为 null 的字段existingUser.setUsername(user.getUsername());existingUser.setEmail(user.getEmail());existingUser.setAge(user.getAge());returnexistingUser;}4.5 DeleteMapping删除资源场景1删除单个用户// 删除用户DeleteMapping(/{id})publicStringdeleteUser(PathVariableLongid){booleanremovedusers.removeIf(u-u.getId().equals(id));if(!removed){thrownewRuntimeException(用户不存在);}return删除成功;}场景2批量删除用户请求参数// 批量删除用户逗号分隔 IDDeleteMapping(/batch)publicStringbatchDeleteUsers(RequestParamListLongids){intremovedCountusers.removeIf(u-ids.contains(u.getId()))?ids.size():0;return成功删除 removedCount 个用户;}五、原理解释5.1 组合注解本质以GetMapping为例其源码为Target(ElementType.METHOD)Retention(RetentionPolicy.RUNTIME)RequestMapping(methodRequestMethod.GET)// 核心绑定 GET 方法publicinterfaceGetMapping{...}可见组合注解是RequestMapping的“语法糖”通过固定method属性简化代码。5.2 请求映射流程DispatcherServlet 接收请求Spring MVC 前端控制器拦截 HTTP 请求。HandlerMapping 匹配处理器根据 URL 和方法GET/POST 等查找对应的XXXMapping方法。参数解析通过HandlerMethodArgumentResolver解析路径变量PathVariable、请求体RequestBody等。执行方法并返回调用目标方法通过HttpMessageConverter如 Jackson将返回值转为 JSON 响应。六、核心特性方法绑定注解与 HTTP 方法强绑定避免误用如用 GET 执行删除。参数注解支持完美配合PathVariable路径变量、RequestParam请求参数、RequestBody请求体等。参数校验结合Valid触发 JSR-380 校验如NotBlank异常由全局处理器捕获。幂等性语义注解名直观反映操作幂等性如PutMapping幂等PostMapping非幂等。七、原理流程图HTTP 请求 → DispatcherServlet → HandlerMapping匹配 XXXMapping→ 参数解析PathVariable/RequestBody→ 执行 Controller 方法 → HttpMessageConverterJSON 序列化→ HTTP 响应八、环境准备与运行8.1 环境JDK 8、Maven 3.6、Spring Boot 2.7。8.2 运行步骤创建 Spring Boot 项目添加spring-boot-starter-web依赖。复制上述代码到UserController.java。启动类添加SpringBootApplication运行main方法。访问http://localhost:8080/api/users测试接口。九、运行结果与测试9.1 测试用例curl 命令操作命令预期结果查询所有用户curl http://localhost:8080/api/users返回 2 条用户数据查询单个用户curl http://localhost:8080/api/users/1返回 ID1 的用户创建用户curl -X POST -H Content-Type: application/json -d {username:wangwu,email:wangwuexample.com,age:25} http://localhost:8080/api/users返回创建的用户含 ID3全量更新用户curl -X PUT -H Content-Type: application/json -d {username:zhangsan2,email:zsexample.com,age:21} http://localhost:8080/api/users/1返回更新后的用户删除用户curl -X DELETE http://localhost:8080/api/users/2返回 “删除成功”十、疑难解答10.1 404 错误原因URL 与XXXMapping路径不匹配如少写/api前缀。解决检查RequestMapping类级别路径与方法级别路径拼接是否正确。10.2 415 不支持的媒体类型原因请求体格式与Content-Type不匹配如传 JSON 但未设application/json。解决POST/PUT 请求添加-H Content-Type: application/json。10.3 参数校验失效原因未添加Valid注解或未引入spring-boot-starter-validation依赖。解决方法参数前加Valid并在pom.xml中添加依赖dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-validation/artifactId/dependency十一、未来展望与技术趋势11.1 技术趋势GraphQL 补充 REST复杂查询场景下GraphQL 可减少过度获取/获取不足问题但 REST 仍因简单直观占主流。响应式编程Spring WebFlux 支持GetMapping等注解的响应式版本如MonoUser返回。API 文档自动化结合 OpenAPI 3.0Swagger注解驱动生成实时文档如Operation描述接口。11.2 挑战幂等性保障PUT/DELETE 需确保多次调用结果一致如分布式锁防止重复删除。版本管理API 迭代时需通过 URL/v1/users或 Header 区分版本避免破坏旧客户端。十二、总结GetMapping、PostMapping等组合注解是 Spring Boot 简化 REST API 开发的核心工具其本质是RequestMapping的方法绑定语法糖。通过本文的场景化代码实现和原理解析我们掌握了不同 HTTP 方法对应的注解选择路径变量、请求参数、请求体的参数绑定技巧参数校验、异常处理的最佳实践。未来随着云原生和微服务的普及这些注解将继续作为 API 开发的基石结合新特性如响应式、GraphQL满足更复杂的业务需求。掌握其本质与最佳实践是成为高效 Spring Boot 开发者的关键一步。