在Java企业级开发中,SpringMVC 作为最主流的Web框架之一,凭借其强大的注解驱动开发模式,极大地简化了Servlet层的开发。告别了繁琐的web.xml配置,我们只需要在普通的POJO上添加几个注解,就能轻松处理客户端请求。
本文将系统性地总结 SpringMVC 中最常用、最核心的注解,并结合代码片段说明其具体用法。
1. 控制器定义:`@Controller` 与 `@RestController`
这是开启 SpringMVC 之旅的第一步。
-
**`@Controller`**: 标记一个类作为Spring MVC的**控制器**。默认情况下,它返回的是**视图名称**(如返回 "userList",会跳转到 userList.jsp)。
-
**`@RestController`**: 这是 `@Controller` + `@ResponseBody` 的组合注解。常用于**RESTful API**开发,它默认所有方法返回的都是 **JSON/XML** 格式的数据,而不是视图页面。
**用法示例:**
```java
// 传统Web应用,返回视图
@Controller
public class ViewController {
@GetMapping("/hello")
public String sayHello() {
return "helloPage"; // 跳转到 helloPage.html/jsp
}
}
// 前后端分离/接口开发,返回JSON
@RestController
@RequestMapping("/api/users")
public class UserApiController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.getById(id); // 自动转为JSON
}
}
```
2. 请求映射:`@RequestMapping` 及其衍生
`@RequestMapping` 是最核心的映射注解,用于将HTTP请求映射到特定处理器的某个方法上。为了方便和语义化,Spring 提供了它的四个快捷版本:
-
**`@GetMapping`**: 映射 GET 请求(查询数据)
-
**`@PostMapping`**: 映射 POST 请求(提交数据)
-
**`@PutMapping`**: 映射 PUT 请求(更新数据)
-
**`@DeleteMapping`**: 映射 DELETE 请求(删除数据)
**用法示例:**
```java
@RestController
@RequestMapping("/product")
public class ProductController {
// 传统写法:@RequestMapping(value = "/list", method = RequestMethod.GET)
@GetMapping("/list")
public List<Product> list() {
return productService.findAll();
}
@PostMapping("/add")
public Result add(@RequestBody Product product) {
// 处理新增逻辑
return Result.success();
}
}
```
3. 参数接收:从请求到方法的桥梁
这是日常开发中使用频率最高的部分。
-
**`@PathVariable`**: 接收**URL路径**中的占位符参数。常用于RESTful风格接口,如 `/user/1`。
-
**`@RequestParam`**: 接收**URL查询参数**或**表单参数**。如 `/user?id=1` 或表单中的 `name` 字段。
-
**`@RequestBody`**: 接收**HTTP请求体**中的JSON/XML数据,并将其自动反序列化为Java对象。常用于POST/PUT请求。
-
**`@RequestHeader`**: 获取请求头中的特定值(如 Token、User-Agent)。
-
**`@CookieValue`**: 获取Cookie中的值。
**用法示例:**
```java
@RestController
@RequestMapping("/order")
public class OrderController {
// URL: /order/detail/1001
@GetMapping("/detail/{orderId}")
public Order getOrder(@PathVariable Long orderId) {
// orderId = 1001
return orderService.get(orderId);
}
// URL: /order/search?page=1&size=10
@GetMapping("/search")
public PageResult search(@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
// 参数非必传时设置 required = false
return orderService.search(page, size);
}
// 接收JSON:{"productId":101, "quantity":2}
@PostMapping("/create")
public Result createOrder(@RequestBody OrderDto orderDto) {
// 自动将JSON映射到OrderDto对象
return orderService.create(orderDto);
}
}
```
4. 数据绑定与格式化
-
**`@ModelAttribute`**: 将请求参数绑定到**模型对象**上,并将该对象存入Model中供视图使用。也可以标注在方法上,表示在控制器方法执行前预先初始化模型数据。
-
**`@DateTimeFormat`**: 用于字符串到日期类型的转换(通常在POJO的字段上使用)。
-
**`@NumberFormat`**: 用于字符串到数字类型的格式化。
**用法示例:**
```java
@Controller
public class UserController {
// 场景:表单提交自动封装为User对象,并传到页面
@PostMapping("/register")
public String register(@ModelAttribute("user") User user) {
// 表单字段自动填充到user对象
return "registerSuccess";
}
}
// POJO中的格式化示例
public class OrderForm {
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@NumberFormat(pattern = "#,###.##")
private BigDecimal amount;
}
```
5. 响应处理
-
**`@ResponseBody`**: 将方法返回的Java对象转换为JSON/XML,并直接写入HTTP响应体中,不经过视图解析器。`@RestController` 内部已经包含了此注解。
-
**`@ResponseStatus`**: 指定HTTP响应的状态码(如 `@ResponseStatus(HttpStatus.CREATED)`),通常用于异常类或成功创建资源的场景。
**用法示例:**
```java
@RestController
public class ResponseDemoController {
// 明确返回201状态码
@PostMapping("/resource")
@ResponseStatus(HttpStatus.CREATED)
public Resource createResource() {
return new Resource("New Resource");
}
// 使用ResponseBody返回JSON(虽然RestController已内置)
@GetMapping("/data")
@ResponseBody
public Map<String, Object> getData() {
return Map.of("key", "value");
}
}
```
6. 文件上传与处理
- **`@RequestPart`**: 专门用于处理**multipart/form-data**格式的请求,既可以接收文件(MultipartFile),也可以接收JSON数据块。
**用法示例:**
```java
@PostMapping("/upload")
public String handleFileUpload(@RequestParam("file") MultipartFile file) {
// 处理上传的文件
String originalName = file.getOriginalFilename();
// 保存文件逻辑...
return "upload success";
}
// 同时上传文件和JSON数据
@PostMapping("/submit")
public String submitForm(@RequestPart("file") MultipartFile file,
@RequestPart("meta") ProductMeta meta) {
// 处理文件和元数据
return "success";
}
```
7. 全局异常处理(进阶常用)
虽然不属于单个控制器注解,但在大型项目中极其常用:
-
**`@ControllerAdvice`** / **`@RestControllerAdvice`**: 定义全局的控制器增强类。
-
**`@ExceptionHandler`**: 定义全局处理特定异常的方法。
**用法示例:**
```java
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result handleValidationException(MethodArgumentNotValidException e) {
String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
return Result.error(400, message);
}
@ExceptionHandler(Exception.class)
public Result handleGenericException(Exception e) {
return Result.error(500, "服务器内部错误");
}
}
```
总结
| 注解 | 核心作用 | 常见场景 |
| :--- | :--- | :--- |
| `@Controller` | 声明控制器,返回视图 | 传统Web应用 |
| `@RestController` | 声明控制器,返回数据 | RESTful API |
| `@RequestMapping` | 映射请求路径 | 类级别路径前缀 |
| `@GetMapping`等 | 映射HTTP方法 | 根据语义处理CRUD |
| `@PathVariable` | 获取URL路径参数 | `/user/{id}` |
| `@RequestParam` | 获取URL查询参数 | `?page=1` |
| `@RequestBody` | 获取请求体JSON | POST/PUT提交数据 |
| `@ResponseBody` | 返回JSON数据 | 接口数据响应 |
| `@ModelAttribute` | 表单数据绑定 | 传统表单提交 |
| `@RestControllerAdvice` | 全局异常/数据绑定 | 统一异常处理 |
掌握这些注解,你就能够灵活应对 SpringMVC 开发中 95% 的业务场景。注解的核心思想就是 **"约定大于配置"** ------ 少写XML,多关注业务逻辑。
希望这篇总结对你的开发学习有帮助!