跳到主要内容

验证、数据绑定和类型转换

ChatGPT-4o 中英对照 Validation, Data Binding, and Type Conversion

将验证视为业务逻辑有其优缺点,而 Spring 提供了一种验证和数据绑定的设计,这种设计并不排除其中的任何一个。具体来说,验证不应与 Web 层绑定,并且应该易于本地化,同时应该可以插入任何可用的验证器。考虑到这些问题,Spring 提供了一个 Validator 合约,它既基本又可以在应用程序的每一层中使用。

数据绑定对于让用户输入动态绑定到应用程序的领域模型(或您用来处理用户输入的任何对象)非常有用。Spring 提供了一个恰如其名的 DataBinder 来实现这一点。ValidatorDataBinder 组成了 validation 包,该包主要用于但不限于 Web 层。

BeanWrapper 是 Spring 框架中的一个基本概念,并在许多地方使用。然而,你可能不需要直接使用 BeanWrapper。因为这是参考文档,我们觉得有必要进行一些解释。我们在本章中解释 BeanWrapper,因为如果你要使用它,最有可能是在尝试将数据绑定到对象时使用。

Spring 的 DataBinder 和较低级别的 BeanWrapper 都使用 PropertyEditorSupport 实现来解析和格式化属性值。PropertyEditorPropertyEditorSupport 类型是 JavaBeans 规范的一部分,本章也对此进行了说明。Spring 的 core.convert 包提供了一种通用的类型转换工具,以及一个更高级别的 format 包用于格式化 UI 字段值。你可以使用这些包作为 PropertyEditorSupport 实现的简单替代方案。本章也会对此进行讨论。

Spring 通过设置基础设施和适配器支持 Java Bean Validation,以适应 Spring 自己的 Validator 合约。应用程序可以按照 Java Bean Validation 中的描述,全局启用 Bean Validation,并将其专门用于所有验证需求。在 Web 层,应用程序可以为每个 DataBinder 注册控制器本地的 Spring Validator 实例,如 Configuring a DataBinder 中所述,这对于插入自定义验证逻辑非常有用。

章节摘要

📄️ 解析代码为错误信息

我们已经讨论了数据绑定和验证。本节介绍如何输出与验证错误对应的消息。在前一节中展示的示例中,我们拒绝了 name 和 age 字段。如果我们想使用 MessageSource 输出错误消息,可以通过我们在拒绝字段时提供的错误代码(在本例中是 'name' 和 'age')来实现。当你调用(直接或间接地,通过例如 ValidationUtils 类)rejectValue 或 Errors 接口中的其他拒绝方法时,底层实现不仅会注册你传入的代码,还会注册许多其他错误代码。MessageCodesResolver 决定了 Errors 接口注册哪些错误代码。默认情况下,使用 DefaultMessageCodesResolver,它不仅注册你提供的代码的消息,还注册包含你传递给拒绝方法的字段名称的消息。例如,如果你使用 rejectValue(\"age\", \"too.darn.old\") 拒绝一个字段,除了 too.darn.old 代码外,Spring 还会注册 too.darn.old.age 和 too.darn.old.age.int(第一个包含字段名称,第二个包含字段的类型)。这样做是为了方便开发人员在定位错误消息时使用。

📄️ 春季字段格式化

正如前一节所讨论的,core.convert 是一个通用的类型转换系统。它提供了一个统一的 ConversionService API 以及一个强类型的 Converter SPI,用于实现从一种类型到另一种类型的转换逻辑。Spring 容器使用这个系统来绑定 bean 属性值。此外,Spring 表达式语言 (SpEL) 和 DataBinder 也使用这个系统来绑定字段值。例如,当 SpEL 需要将一个 Short 强制转换为一个 Long 以完成 expression.setValue(Object bean, Object value) 尝试时,core.convert 系统会执行这种强制转换。