Spring MVC 常用请求处理注解总结
一、@RequestBody 和 @ResponseBody 的作用与区别
这两个注解在 Spring 框架中处理 HTTP 请求和响应时扮演着重要角色,它们的主要区别在于处理方向:
1.@RequestBody
- 作用:将 HTTP 请求体中的数据绑定到方法参数上
- 应用场景:处理 POST/PUT 请求中的 JSON、XML 等格式的数据
- 实现原理:依赖 HttpMessageConverter 将请求体数据转换为 Java 对象
2.@ResponseBody
- 作用:将方法返回值绑定到 HTTP 响应体中
- 应用场景:返回 JSON、XML 等格式的数据给客户端
- 实现原理:依赖 HttpMessageConverter 将 Java 对象转换为响应体数据
3.代码示例
下面是一个完整的示例,展示了这两个注解的使用方式:
@Controller
@RequestMapping("/api/users")
public class UserController {// 使用 @RequestBody 接收请求体中的 JSON 数据@PostMapping("/create")@ResponseBody // 显式指定返回 JSON 数据public User createUser(@RequestBody User user) {// 这里 user 对象已经由 JSON 转换而来System.out.println("创建用户: " + user.getName());user.setId(1001L); // 模拟生成 IDreturn user; // 返回给客户端}// 使用 @ResponseBody 返回 JSON 数据@GetMapping("/{id}")@ResponseBodypublic User getUser(@PathVariable Long id) {User user = new User();user.setId(id);user.setName("张三");user.setAge(25);return user; // 返回给客户端}// 使用 @RestController 时可以省略 @ResponseBody@RestController@RequestMapping("/api/products")public static class ProductController {@PostMapping("/update")public Product updateProduct(@RequestBody Product product) {// 自动将请求体转换为 Product 对象System.out.println("更新产品: " + product.getName());return product; // 自动转换为 JSON 返回}}
}// 用户实体类
class User {private Long id;private String name;private Integer age;// getter 和 setter 方法public Long getId() { return id; }public void setId(Long id) { this.id = id; }public String getName() { return name; }public void setName(String name) { this.name = name; }public Integer getAge() { return age; }public void setAge(Integer age) { this.age = age; }
}// 产品实体类
class Product {private Long id;private String name;private Double price;// getter 和 setter 方法// ...
}
4.实际应用示例
请求示例 1:创建用户
POST /api/users/create HTTP/1.1
Content-Type: application/json{"name": "李四","age": 30
}
响应示例 1:
HTTP/1.1 200 OK
Content-Type: application/json{"id": 1001,"name": "李四","age": 30
}
请求示例 2:获取用户
GET /api/users/1001 HTTP/1.1
响应示例 2:
HTTP/1.1 200 OK
Content-Type: application/json{"id": 1001,"name": "张三","age": 25
}
总结
- @RequestBody:从请求体到 Java 对象的转换
- @ResponseBody:从 Java 对象到响应体的转换
- @RestController:相当于
@Controller
+@ResponseBody
的组合注解
这两个注解通过 HttpMessageConverter 实现了 HTTP 数据与 Java 对象之间的自动转换,大大简化了 RESTful API 的开发。
- 注意:
- 需配合
@Controller
+@ResponseBody
或@RestController
- 依赖 Jackson 等序列化框架解析请求体
- 需配合
二、@RestController
的作用
@RestController
是 Spring Boot 中一个组合注解,等价于 @Controller
+ @ResponseBody
。它表明该类中的所有方法的返回值都直接作为 HTTP 响应体返回,而不是视图名称。
1.为何不需要 @ResponseBody
因为 @RestController
已隐含了 @ResponseBody
的行为,所以方法返回的对象(如 Result.ok(user)
)将自动被 Jackson 序列化为 JSON 格式返回给客户端。
2.前提条件
确保 User
和 Result
类具有可访问的属性(通过 getter 方法或字段可见性),以便 Jackson 正确序列化。
三、 @RequestMapping:路由映射核心注解
- 作用:将 URL 路径映射到控制器方法,支持多种请求方法
- 应用场景:定义控制器的访问路径和请求类型
- 示例:
@Controller
@RequestMapping("/api/users")
public class UserController {// 处理 GET /api/users/123@RequestMapping(value = "/{id}", method = RequestMethod.GET)public User getUser(@PathVariable Long id) { ... }
}
1.路径匹配规则:
- 只要是 GET 请求,且路径格式为 /api/users/任意数字,都会匹配到这个方法。
- 例如:/api/users/1、/api/users/123、/api/users/99999 等都可以访问。
2.参数要求:
- 路径中的 {id} 部分必须是 有效的 Long 类型数字(Java 中的长整型)。
- 如果不是数字(如 /api/users/abc),会抛出 TypeMismatchException 异常,因为无法将字符串转换为 Long。
3.简化注解(Spring 4.3+):
- @GetMapping:等价于 @RequestMapping(method = GET)
- @PostMapping:等价于 @RequestMapping(method = POST)
- 其他:@PutMapping、@DeleteMapping、@PatchMapping
四、HTTP 请求与响应中的头部和参数注解
在 Spring 框架中,@RequestHeader和@RequestParam是用于处理 HTTP 请求的注解,它们分别对应于请求头和请求参数。虽然没有直接命名为@ResponseHeader和@ResponseParam的注解,但 Spring 提供了其他机制来处理 HTTP 响应的头部和参数。
1.@RequestHeader:获取请求头信息
- 作用:获取 HTTP 请求头中的字段值(如 User-Agent、自定义 Token)
- 应用场景:认证授权(获取 Token)、请求溯源(获取客户端信息)
- 示例:
@GetMapping("/profile")
public User getProfile(@RequestHeader("Authorization") String token,@RequestHeader("User-Agent") String userAgent) {// 使用 token 和 userAgent
}
- 进阶用法:
@RequestHeader("X-User-Id") Long userId
:自定义请求头@RequestHeader(value = "Accept", required = false)
:可选请求头
2.@RequestParam:获取请求参数
- 作用:获取 URL 查询参数或表单参数(
?name=张三&age=20
) - 示例:
@GetMapping("/search")
public List<User> search(@RequestParam("keyword") String keyword,@RequestParam(value = "page", defaultValue = "1") int page) {// 对应 URL: /search?keyword=abc&page=2
}
- 参数说明:
value
:参数名(可省略,直接用变量名)required
:是否必填(默认true
)defaultValue
:默认值(当参数不存在时使用)
3.请求注解与响应机制的对应关系
@RequestHeader vs 响应头部处理
@RequestHeader
: 用于从 HTTP 请求中提取头部信息- 响应头部处理:通过
HttpServletResponse
对象或@ResponseStatus
注解设置
@RequestParam vs 响应体处理
@RequestParam
: 用于从 HTTP 请求中提取查询参数- 响应体处理:通过
@ResponseBody
或ResponseEntity
返回响应数据
4.响应头部的设置方式
在 Spring 中,设置响应头部有以下几种方式:
使用HttpServletResponse
对象直接设置:
@GetMapping("/example")
public void example(HttpServletResponse response) {response.setHeader("Custom-Header", "Value");// 其他响应处理
}
使用@ResponseStatus
注解设置状态码和原因:
@ResponseStatus(value = HttpStatus.CREATED, reason = "Resource created successfully")
@PostMapping("/create")
public void createResource() {// 创建资源的逻辑
}
使用ResponseEntity
构建完整响应:
@GetMapping("/example")
public ResponseEntity<String> example() {HttpHeaders headers = new HttpHeaders();headers.add("Custom-Header", "Value");return new ResponseEntity<>("Response Body", headers, HttpStatus.OK);
}
五、@PathVariable:获取路径变量
- 作用:获取 RESTful 路径中的动态参数(如
/user/123
中的123
) - 应用场景:RESTful API 设计(资源查询、删除等)
- 示例:
@DeleteMapping("/users/{id}")
public Result deleteUser(@PathVariable Long id) {// 对应 URL: /users/123
}
六、@ModelAttribute:绑定请求参数到模型
- 作用:
- 绑定请求参数到模型属性(类似
@RequestParam
,但支持复杂对象) - 在控制器方法执行前填充模型(如公共数据)
- 绑定请求参数到模型属性(类似
- 示例:
@PostMapping("/user")
public String saveUser(@ModelAttribute User user) {// 自动绑定表单参数到 user 对象
}
注解 | 作用场景 | 数据来源 | 典型用法 |
---|---|---|---|
@RequestBody | 请求体数据(JSON/XML) | 请求体 | 提交表单、API 数据交互 |
@RequestParam | 查询参数 / 表单参数 | URL 参数或表单 | ?id=1&name=张三 |
@PathVariable | RESTful 路径参数 | URL 路径 | /user/{id} |
@RequestHeader | 请求头字段 | HTTP 请求头 | 获取 Authorization 、User-Agent |
@ModelAttribute | 模型属性绑定 | 请求参数或模型 | 表单提交、模型数据填充 |
@ResponseBody | 响应体数据 | 方法返回值 | 返回 JSON/XML 数据 |
七、其他注解
1.@Value:注入配置属性
- 作用:从配置文件(如
application.properties
)读取值 - 示例:
@Component
public class AppConfig {@Value("${server.port}")private int port;@Value("${app.name:默认名称}") // 默认值private String appName;
}
2.@Configuration:配置类注解
- 作用:声明 Java 配置类,替代 XML 配置
- 示例:
@Configuration
public class AppConfig {@Beanpublic DataSource dataSource() {return new HikariDataSource();}
}
3.@Bean:注册 Bean
- 作用:在配置类中手动注册 Bean
- 示例:
@Configuration
public class AppConfig {@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}
4.@Transactional:事务管理
- 作用:声明事务边界,支持事务传播行为
- 示例:
@Service
public class UserService {@Transactional(rollbackFor = Exception.class)public void transferMoney(Long fromId, Long toId, BigDecimal amount) {// 事务内操作}
}