Spring MVC 常用请求处理注解总结

发布于:2025-06-13 ⋅ 阅读:(23) ⋅ 点赞:(0)

一、@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); // 模拟生成 ID
        return user; // 返回给客户端
    }

    // 使用 @ResponseBody 返回 JSON 数据
    @GetMapping("/{id}")
    @ResponseBody
    public 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.前提条件

确保 UserResult 类具有可访问的属性(通过 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 请求中提取查询参数
  • 响应体处理:通过@ResponseBodyResponseEntity返回响应数据

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:绑定请求参数到模型

  • 作用
    1. 绑定请求参数到模型属性(类似 @RequestParam,但支持复杂对象)
    2. 在控制器方法执行前填充模型(如公共数据)
  • 示例
@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 请求头 获取 AuthorizationUser-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 {
    @Bean
    public DataSource dataSource() {
        return new HikariDataSource();
    }
}

3.@Bean:注册 Bean

  • 作用:在配置类中手动注册 Bean
  • 示例
@Configuration
public class AppConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

4.@Transactional:事务管理

  • 作用:声明事务边界,支持事务传播行为
  • 示例
@Service
public class UserService {
    @Transactional(rollbackFor = Exception.class)
    public void transferMoney(Long fromId, Long toId, BigDecimal amount) {
        // 事务内操作
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到