请求参数与数据绑定
本教程共 48 篇 · 第 20 篇 · 更新于 2026-08-13 · 约 3 分钟阅读
本节目标:分清四种参数来源,会用对应注解取参数、绑对象,并用 Bean Validation 校验入参。
参数从哪来
HTTP 请求里的数据,藏在四个地方:
- URL 路径里:
/products/5的5。 - 查询字符串里:
/products?page=2的page。 - 请求体里:POST 提交的 JSON。
- 表单字段里:
name=张三&age=18。
Spring MVC 给每处都配了注解,一一对应,很好记。
@PathVariable:路径变量
路径变量写在 URL 的花括号里。上一章的 {id} 就是它。
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/users")
public class UserController {
// GET /users/42
@GetMapping("/{id}")
public String getUser(@PathVariable Long id) {
// id 自动从 URL 里解析出来,等于 42
return "用户 " + id;
}
}
花括号名和方法参数名一致时,@PathVariable 不用写名字。不一致时写明:@PathVariable("id") Long userId。
@RequestParam:查询参数
查询参数跟在 ? 后面,用 @RequestParam 接收。
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SearchController {
// GET /search?keyword=java&page=2
@GetMapping("/search")
public String search(
@RequestParam String keyword,
@RequestParam(defaultValue = "1") int page) {
// keyword 必填;page 缺省时用 1
return "搜索 " + keyword + ",第 " + page + " 页";
}
}
两个属性常用:
required = false:参数可缺省。defaultValue = "1":缺省时给默认值。
Warning默认情况下 @RequestParam 必填。漏传直接报 400,不会走进方法体。
@RequestBody:JSON 请求体
POST 接口传 JSON 时用 @RequestBody。Spring 用 Jackson 把 JSON 反序列化成对象。
package com.example.demo.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.model.User;
@RestController
public class RegisterController {
// POST /register
// body: {"name":"张三","email":"zhang@example.com"}
@PostMapping("/register")
public String register(@RequestBody User user) {
return "注册成功:" + user.getName();
}
}
User 就是个普通 POJO,字段名和 JSON 键一一对应:
package com.example.demo.model;
public class User {
private String name;
private String email;
private Integer age;
// getter / setter 省略
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
}
JSON 里的 age 缺省时,对象里就是 null。
表单绑定:不用注解也能收
HTML 表单提交(application/x-www-form-urlencoded)时,Spring MVC 会自动把字段绑定到对象属性。方法参数上加 @ModelAttribute 更明确,不加也能绑定。
package com.example.demo.controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.model.User;
@RestController
public class FormController {
// POST /form
// body: name=李四&email=li@example.com
@PostMapping("/form")
public String form(@ModelAttribute User user) {
return "表单绑定:" + user.getName();
}
}
字段名对得上就自动装进去,类型转换(字符串转数字)由框架完成,转不了就报 400。
Tip前端页面向服务端页面提交时用表单绑定;前后端分离传 JSON 时用 @RequestBody。两种别混。
@Valid 参数校验
裸奔的参数容易出问题。空名字、超长文本、非法邮箱,全靠手工 if 判断太啰嗦。
Spring Boot 集成 Bean Validation,用注解声明规则。先加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
NoteSpring Boot 2.3 起,校验 starter 不再随 web starter 携带,需要显式添加。4.x 同样如此。
给字段加规则:
package com.example.demo.model;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
public class User {
@NotBlank(message = "姓名不能为空")
@Size(max = 20, message = "姓名最长 20 个字")
private String name;
@Email(message = "邮箱格式不对")
@NotBlank(message = "邮箱不能为空")
private String email;
// getter / setter 省略
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
}
方法参数上加 @Valid 触发校验:
package com.example.demo.controller;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.model.User;
@RestController
public class RegisterController {
@PostMapping("/register")
public String register(@Valid @RequestBody User user) {
// 走到这里说明校验通过
return "注册成功:" + user.getName();
}
}
校验失败时抛 MethodArgumentNotValidException,默认返回 400。想给客户端友好提示,需要配合异常处理,下一章专门讲。
常用注解速查:
| 注解 | 作用 |
|---|---|
| @NotBlank | 字符串非空且去掉空格后长度大于 0 |
| @NotNull | 对象不为 null |
| @Size(min, max) | 长度在区间内 |
| 邮箱格式 | |
| @Min / @Max | 数值下限 / 上限 |
| @Pattern | 正则匹配 |
Warning@NotBlank、@Email 等注解来自
jakarta.validation.constraints包,不是javax。Spring Boot 4.x 全线 Jakarta EE 11 命名空间。
本节小结
- 路径变量用 @PathVariable,查询参数用 @RequestParam。
- JSON 请求体用 @RequestBody,表单绑定用 @ModelAttribute。
- 校验规则写在字段注解上,方法参数加 @Valid 生效。
- 校验失败抛 MethodArgumentNotValidException,交给异常处理器统一应答。