Spring MVC 常用注解详解
- 发布时间:2025-12-16 07:33:44
- 本文热度:浏览 8 赞 0 评论 0
- 文章标签: SpringMVC Java SpringBoot
- 全文共1字,阅读约需1分钟
一、Spring MVC 注解体系总体认知
Spring MVC 是 Java Web 开发最核心的 MVC 框架之一,其强大之处除了 DispatcherServlet、HandlerMapping、HandlerAdapter 这些基础设施外,更关键的是一套高度抽象的 注解体系。这些注解帮助开发者以最少的样板代码实现请求映射、参数解析、响应输出、异常处理、数据校验及拦截等核心能力。
Spring MVC 注解大致可以分为以下几类:
-
控制器相关注解
@Controller@RestController@RequestMapping/@GetMapping/@PostMapping等
-
请求参数与响应映射注解
@RequestParam@PathVariable@RequestBody@ResponseBody@CookieValue@RequestHeader
-
数据校验
@Valid/@Validated- 配合 Bean Validation 注解使用
-
JSON/XML 序列化控制
@JsonIgnore/@JsonProperty(来自 Jackson)
-
作用于控制层流程的注解
@ModelAttribute@SessionAttributes@InitBinder
-
全局异常处理
@ExceptionHandler@ControllerAdvice
这一类注解合起来,构成了 Spring MVC 在 Web 层的全部能力。
为了让小白能更清晰地理解,我们按照实际开发流程来逐类讲解。
二、控制器注解
1. @Controller 与 @RestController
原理
@Controller基于 Spring 组件扫描,被注册为一个 Web 控制器组件。@RestController=@Controller+@ResponseBody,表示控制器所有方法的返回值都以 JSON/XML 方式响应,而不是返回页面。
用途
@Controller适用于 MVC + Thymeleaf/JSP 页面渲染@RestController用于 API 服务(前后端分离最常用)
思维图示
@Controller
↓
返回视图(View)
@RestController
↓
返回 JSON (自动序列化)
示例代码
@Controller
public class PageController {
@GetMapping("/home")
public String home() {
return "home"; // 跳转到 home.html 页面
}
}
@RestController
@RequestMapping("/api/user")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return new User(id, "Tom");
}
}
实战场景
- 后端返回 HTML 页面的老式 MVC 项目使用
@Controller。 - 前后端分离项目使用
@RestController。
常见错误
@Controller忘记加@ResponseBody导致返回字符串被当成视图名- 同时使用
@RestController又返回ModelAndView会出现混乱
作者经验总结
大部分企业项目使用前后端分离,建议所有 API 控制层统一使用 @RestController,避免因忘记 @ResponseBody 造成的问题。
三、请求映射注解体系
Spring MVC 提供一套族式注解用于请求路由:
@RequestMapping@GetMapping@PostMapping@PutMapping@DeleteMapping@PatchMapping
1. @RequestMapping
原理
@RequestMapping 核心是 指定 URL、请求方法、参数、绑定条件。底层由 RequestMappingHandlerMapping 进行处理。
示例
@RestController
@RequestMapping("/api/user")
public class UserController {
@RequestMapping(value = "/list", method = RequestMethod.GET)
public List<String> list() {
return List.of("A", "B");
}
}
2. @GetMapping 等快捷注解
这些注解是 @RequestMapping(method=...) 的语法糖。
示例:
@GetMapping("/find/{id}")
public User find(@PathVariable Long id) {
return new User(id, "Tom");
}
URL 组合逻辑图(伪图示)
类级别 @RequestMapping("/api/user")
+
方法级别 @GetMapping("/find")
=
最终 URL: /api/user/find
常见错误
- 类级 URL 末尾加
/导致路径重复 - 方法级 URL 以
/开头不影响最终路径,但容易造成风格不统一 - 多个控制器映射到相同 URL 导致歧义
最佳实践
- 统一以 REST 风格命名 API
- URL 不加版本号,采用
/api/v1/user/*风格
作者经验总结
企业项目应建立统一 API 命名规范,例如:
GET /api/v1/users/{id}
POST /api/v1/users
PUT /api/v1/users/{id}
DELETE /api/v1/users/{id}
REST 命名让接口文档更标准可读。
四、请求参数相关注解
这一类注解是 Spring MVC 的灵魂,决定请求数据如何被映射到后端方法入参。
4.1 @RequestParam
原理
用于获取 URL 查询参数或表单参数。例如:
GET /user/search?name=tom&age=20
示例
@GetMapping("/search")
public String search(
@RequestParam String name,
@RequestParam(required = false, defaultValue = "18") Integer age
) {
return "name=" + name + ", age=" + age;
}
常见错误
- 传参名称不匹配导致 400 错误
- 参数未标记
required=false导致必须传参
作者经验总结
若参数带默认值,优先写在注解上而不是代码逻辑中,提高可维护性。
4.2 @PathVariable
原理
用于 REST 风格 URL 获取路径中变量。
例如:
GET /user/1/detail
示例
@GetMapping("/{id}/detail")
public User detail(@PathVariable("id") Long userId) {
return new User(userId, "Tom");
}
注意事项
@PathVariable名称必须一致,否则需手动指定"value"- Spring 3.2+ 支持 PathVariable URI 模板正则表达式
示例:
@GetMapping("/order/{orderId:[0-9]+}")
public String order(@PathVariable Integer orderId) {
return "OK";
}
4.3 @RequestBody
原理
从请求体中读取 JSON/XML 内容,并通过 HttpMessageConverter 反序列化成对象。
流程图:
请求 JSON → HttpMessageConverter → Java 对象
示例
@PostMapping("/create")
public User create(@RequestBody User user) {
return user;
}
application/json 请求示例:
{
"id": 1,
"name": "Tom"
}
常见错误
- 未开启对象序列化库(Spring Boot 默认开启 Jackson)
- 未加
@RequestBody导致参数为 null - Content-Type 设置不正确(必须
application/json)
4.4 @ResponseBody
原理
将方法返回值序列化为 JSON(XML),返回给客户端。
在 @RestController 中已自动包含。
示例
@ResponseBody
@GetMapping("/info")
public User info() {
return new User(1L, "Tom");
}
4.5 @RequestHeader
用于获取请求头参数。
@GetMapping("/ua")
public String ua(@RequestHeader("User-Agent") String ua) {
return ua;
}
4.6 @CookieValue
用于获取 Cookie。
@GetMapping("/cookie")
public String cookie(@CookieValue("token") String token) {
return token;
}
作者经验总结(本章节)
Spring MVC 参数解析由 HandlerMethodArgumentResolver 体系负责,掌握各类注解能避免大量手写 HttpServletRequest 的臃肿代码。建议保持 API 规范:“路径参数用 PathVariable,查询参数用 RequestParam,复杂对象用 RequestBody”。
五、MVC 高级注解
5.1 @ModelAttribute
原理
用于方法入参绑定,也可用于方法执行前向 Model 中填充数据。
用途
- 绑定表单对象
- 在所有请求前注入公共参数
示例 1:绑定表单对象
@PostMapping("/update")
public String update(@ModelAttribute User user) {
return "ok";
}
表单提交数据会自动绑定到 User 对象。
示例 2:方法级提前注入 Model 数据
@ModelAttribute
public void common(Model model) {
model.addAttribute("sysName", "UserCenter");
}
5.2 @SessionAttributes
用于将 model 中的指定属性放入 session。
@Controller
@SessionAttributes("user")
public class DemoController {
@GetMapping("/set")
public String set(Model model) {
model.addAttribute("user", new User(1L, "Tom"));
return "ok";
}
}
5.3 @InitBinder
用于参数绑定控制,如日期格式化、字段过滤。
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(
new SimpleDateFormat("yyyy-MM-dd"), true));
}
作者经验总结(本章节)
多数企业项目不会大量使用 @ModelAttribute、@SessionAttributes,但 @InitBinder 在处理自定义数据类型(金额、时间)时非常有用。
六、校验相关注解
Spring MVC 集成 Bean Validation(JSR-380),核心注解:
@Valid@Validated
示例:
@PostMapping("/add")
public String add(@Validated @RequestBody User user) {
return "ok";
}
配合实体类注解使用:
public class User {
@NotNull
private Long id;
@NotBlank
private String name;
@Min(1)
private Integer age;
}
全局异常处理(必备)
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> handle(MethodArgumentNotValidException e) {
return ResponseEntity.badRequest().body(e.getBindingResult().getFieldError().getDefaultMessage());
}
}
七、全局异常处理注解
7.1 @ControllerAdvice
用于定义全局增强类,可进行:
- 全局异常处理
- 全局数据绑定
- 全局绑定初始化
示例:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public Map<String,Object> handler(Exception e){
Map<String,Object> r = new HashMap<>();
r.put("msg", e.getMessage());
return r;
}
}
八、数据序列化相关注解(Jackson)
@JsonIgnore@JsonProperty@JsonFormat
示例对象:
public class User {
private Long id;
@JsonProperty("userName")
private String name;
@JsonIgnore
private String password;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
}
九、综合实战项目案例(Spring Boot)
下面提供一个完整可运行的 Spring Boot Demo,展示文章中的所有注解。
9.1 application.yml
server:
port: 8080
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
jackson:
time-zone: Asia/Shanghai
serialization:
indent-output: true
9.2 实体类
@Data
public class User {
@NotNull
private Long id;
@NotBlank
private String name;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
}
9.3 Controller
@RestController
@RequestMapping("/api/user")
public class UserController {
@GetMapping("/{id}")
public User find(@PathVariable Long id) {
User u = new User();
u.setId(id);
u.setName("Tom");
u.setCreateTime(LocalDateTime.now());
return u;
}
@PostMapping("/create")
public User create(@Valid @RequestBody User user) {
user.setCreateTime(LocalDateTime.now());
return user;
}
@GetMapping("/search")
public String search(@RequestParam String name,
@RequestHeader("User-Agent") String ua) {
return "name=" + name + ", ua=" + ua;
}
}
9.4 全局异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> valid(MethodArgumentNotValidException e){
String msg = e.getBindingResult().getFieldError().getDefaultMessage();
return ResponseEntity.badRequest().body(msg);
}
}
十、常见错误与 Debug 指南
错误:400 Bad Request
原因:
- 参数类型无法转换
- 缺少必要
@RequestParam值 - 未加
@RequestBody导致请求体为空 - JSON 不合法
错误:415 Unsupported Media Type
- Content-Type 不是
application/json
错误:404
- URL 不匹配
- 类级 @RequestMapping 前缀写错
十一、最佳实践
- API 分层规范
- 注解使用一致性
- 保持 JSON 格式标准
- 所有参数校验必须显式写明
- 异常使用统一处理机制
- Controller 不写业务逻辑,只做参数解析与响应封装
十二、作者经验总结(全文)
Spring MVC 注解体系看似复杂,其实每一类都有明确职责:
- 请求路由注解 决定 URL
- 参数绑定注解 决定数据如何进入方法
- 响应注解 决定数据如何返回
- 校验注解 保证输入合法
- 全局注解 提高可维护性
掌握这些注解,不仅是 Spring MVC 的基础,也是使用 Spring Boot 开发 REST API 的关键能力。在企业项目中,它们能极大简化 Controller 层,提高可读性和稳定性。