对于最新的稳定版本,请使用 Spring Framework 6.2.0spring-doc.cadn.net.cn

@ModelAttribute

您可以使用@ModelAttribute对 method 参数的注释来访问属性 模型,如果不存在,则对其进行实例化。model 属性还覆盖了 其名称与字段名称匹配的 HTTP Servlet 请求参数的值。这是指 to 作为数据绑定,并且它使您不必处理解析和转换单个 查询参数和表单字段。以下示例显示了如何执行此作:spring-doc.cadn.net.cn

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute Pet pet) { (1)
	// method logic...
}
1 绑定 的实例Pet.
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
fun processSubmit(@ModelAttribute pet: Pet): String { (1)
	// method logic...
}
1 绑定 的实例Pet.

Pet上述实例通过以下方式之一获取:spring-doc.cadn.net.cn

使用 @ModelAttribute 方法的一种替代方法 提供它或依赖框架来创建 model 属性,就是要有一个Converter<String, T>以提供实例。这在 model 属性 name 与请求值的名称匹配,例如 path 变量或 request 参数,并且有一个ConverterString设置为 model 属性类型。 在以下示例中,模型属性名称为account与 URI 匹配 path 变量account,并且有一个已注册的Converter<String, Account>哪 可以加载Account从数据存储:spring-doc.cadn.net.cn

@PutMapping("/accounts/{account}")
public String save(@ModelAttribute("account") Account account) { (1)
	// ...
}
1 绑定 的实例Account使用显式属性名称。
@PutMapping("/accounts/{account}")
fun save(@ModelAttribute("account") account: Account): String { (1)
	// ...
}
1 绑定 的实例Account使用显式属性名称。

获取 model 属性实例后,将应用数据绑定。这WebDataBinderclass 匹配 Servlet 请求参数名称(查询参数和表单 fields) 添加到目标上的字段名称Object.匹配字段在 type 之后填充 必要时应用 conversion。有关数据绑定(和验证)的更多信息,请参阅验证。有关自定义数据绑定的更多信息,请参阅DataBinder.spring-doc.cadn.net.cn

数据绑定可能会导致错误。默认情况下,BindException被提升。但是,要检查 对于 controller 方法中的此类错误,您可以添加BindingResult紧接着的参数 到@ModelAttribute,如下例所示:spring-doc.cadn.net.cn

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) { (1)
	if (result.hasErrors()) {
		return "petForm";
	}
	// ...
}
1 添加BindingResult@ModelAttribute.
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
fun processSubmit(@ModelAttribute("pet") pet: Pet, result: BindingResult): String { (1)
	if (result.hasErrors()) {
		return "petForm"
	}
	// ...
}
1 添加BindingResult@ModelAttribute.

在某些情况下,您可能希望访问没有数据绑定的 model 属性。对于这样的 cases,您可以注入Model放入控制器并直接访问它,或者, 或者,将@ModelAttribute(binding=false),如下例所示:spring-doc.cadn.net.cn

@ModelAttribute
public AccountForm setUpForm() {
	return new AccountForm();
}

@ModelAttribute
public Account findAccount(@PathVariable String accountId) {
	return accountRepository.findOne(accountId);
}

@PostMapping("update")
public String update(@Valid AccountForm form, BindingResult result,
		@ModelAttribute(binding=false) Account account) { (1)
	// ...
}
1 设置@ModelAttribute(binding=false).
@ModelAttribute
fun setUpForm(): AccountForm {
	return AccountForm()
}

@ModelAttribute
fun findAccount(@PathVariable accountId: String): Account {
	return accountRepository.findOne(accountId)
}

@PostMapping("update")
fun update(@Valid form: AccountForm, result: BindingResult,
		   @ModelAttribute(binding = false) account: Account): String { (1)
	// ...
}
1 设置@ModelAttribute(binding=false).

您可以通过在数据绑定后自动应用验证,方法是添加jakarta.validation.Valid注解或 Spring 的@Validated注解 (Bean 验证Spring 验证)。以下示例显示了如何执行此作:spring-doc.cadn.net.cn

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result) { (1)
	if (result.hasErrors()) {
		return "petForm";
	}
	// ...
}
1 验证Pet实例。
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
fun processSubmit(@Valid @ModelAttribute("pet") pet: Pet, result: BindingResult): String { (1)
	if (result.hasErrors()) {
		return "petForm"
	}
	// ...
}
1 验证Pet实例。

请注意,使用@ModelAttribute是可选的(例如,设置其属性)。 默认情况下,任何不是简单值类型的参数(由 BeanUtils#isSimpleProperty 确定) 并且未由任何其他参数解析 resolver 被视为已批注 跟@ModelAttribute.spring-doc.cadn.net.cn

使用 GraalVM 编译为原生镜像时,隐式的@ModelAttribute上述支持不允许对相关数据进行适当的提前推理 绑定反射提示。因此,建议显式注释 method 参数替换为@ModelAttribute用于 GraalVM 原生映像。