此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10spring-doc.cadn.net.cn

@InitBinder

@Controller@ControllerAdvice类可以有@InitBinder方法设置为 初始化WebDataBinder反过来,这些实例可以:spring-doc.cadn.net.cn

@Controller,DataBinder自定义在控制器内本地应用, 甚至通过注释指向名称引用的特定模型属性。 在@ControllerAdvice自定义可以应用于所有或一部分控制器。spring-doc.cadn.net.cn

您可以注册PropertyEditor,ConverterFormatter组件中的DataBinder用于类型转换。或者,您可以使用 MVC 配置进行注册ConverterFormatter全局共享的组件FormattingConversionService.spring-doc.cadn.net.cn

@InitBinder方法可以有许多相同的参数@RequestMapping方法 有,但值得注意的是@ModelAttribute.通常,此类方法具有WebDataBinder参数(用于注册)和void返回值,例如:spring-doc.cadn.net.cn

@Controller
public class FormController {

	@InitBinder (1)
	public void initBinder(WebDataBinder binder) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		dateFormat.setLenient(false);
		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
	}

	// ...
}
1 定义@InitBinder方法。
@Controller
class FormController {

	@InitBinder (1)
	fun initBinder(binder: WebDataBinder) {
		val dateFormat = SimpleDateFormat("yyyy-MM-dd")
		dateFormat.isLenient = false
		binder.registerCustomEditor(Date::class.java, CustomDateEditor(dateFormat, false))
	}

	// ...
}
1 定义@InitBinder方法。

或者,当您使用Formatter通过共享的基于设置FormattingConversionService,您可以重复使用相同的方法并注册 控制器专用Formatter实现,如以下示例所示:spring-doc.cadn.net.cn

@Controller
public class FormController {

	@InitBinder (1)
	protected void initBinder(WebDataBinder binder) {
		binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));
	}

	// ...
}
1 定义@InitBinder自定义格式化程序上的方法。
@Controller
class FormController {

	@InitBinder (1)
	protected fun initBinder(binder: WebDataBinder) {
		binder.addCustomFormatter(DateFormatter("yyyy-MM-dd"))
	}

	// ...
}
1 定义@InitBinder自定义格式化程序上的方法。

模型设计

Web 请求的数据绑定涉及 将请求参数绑定到模型对象。默认情况下,可以绑定请求参数 添加到模型对象的任何公共属性,这意味着恶意客户端可以提供 模型对象图中存在但预计不会的属性的额外值 被设定。这就是为什么模型对象设计需要仔细考虑的原因。spring-doc.cadn.net.cn

模型对象及其嵌套对象图有时也称为命令对象表单支持对象POJO(普通旧 Java 对象)。

一个好的做法是使用专用的模型对象,而不是公开您的域 模型,例如 JPA 或 Hibernate 实体,用于 Web 数据绑定。例如,在表单上将 更改电子邮件地址,创建ChangeEmailFormmodel 对象,该对象仅声明 输入所需的属性:spring-doc.cadn.net.cn

public class ChangeEmailForm {

	private String oldEmailAddress;
	private String newEmailAddress;

	public void setOldEmailAddress(String oldEmailAddress) {
		this.oldEmailAddress = oldEmailAddress;
	}

	public String getOldEmailAddress() {
		return this.oldEmailAddress;
	}

	public void setNewEmailAddress(String newEmailAddress) {
		this.newEmailAddress = newEmailAddress;
	}

	public String getNewEmailAddress() {
		return this.newEmailAddress;
	}

}

另一个好的做法是应用构造函数绑定, 它仅使用构造函数参数所需的请求参数,以及任何其他 输入被忽略。这与属性绑定形成鲜明对比,属性绑定默认情况下绑定每个 request 参数,其属性匹配。spring-doc.cadn.net.cn

如果专用模型对象和构造函数绑定都不够,并且您必须 使用属性绑定,强烈建议注册allowedFields图案(大小写 敏感)在WebDataBinder以防止设置意外属性。 例如:spring-doc.cadn.net.cn

@Controller
public class ChangeEmailController {

	@InitBinder
	void initBinder(WebDataBinder binder) {
		binder.setAllowedFields("oldEmailAddress", "newEmailAddress");
	}

	// @RequestMapping methods, etc.

}

您也可以注册disallowedFields模式(不区分大小写)。然而 “允许”配置优于“不允许”,因为它更明确且更少 容易出错。spring-doc.cadn.net.cn

默认情况下,构造函数和属性绑定都使用。如果你想使用 构造函数绑定,您可以将declarativeBinding标记 onWebDataBinder通过@InitBinder方法在控制器内本地或通过@ControllerAdvice.打开此标志可确保仅使用构造函数绑定 并且除非allowedFields配置了模式。 例如:spring-doc.cadn.net.cn

@Controller
public class MyController {

	@InitBinder
	void initBinder(WebDataBinder binder) {
		binder.setDeclarativeBinding(true);
	}

	// @RequestMapping methods, etc.

}