|
对于最新稳定版本,请使用 Spring Framework 7.0.6! |
Java Bean 验证
Spring 框架提供了对 Java Bean Validation API 的支持。
Bean 验证概述
Bean Validation 为 Java 应用程序提供了一种通过约束声明和元数据进行验证的通用方式。要使用它,您可以在领域模型属性上添加声明式验证约束注解,这些约束将在运行时被强制执行。该框架提供了内置的约束,您也可以定义自己的自定义约束。
考虑以下示例,它展示了一个包含两个属性的简单 PersonForm 模型:
-
Java
-
Kotlin
public class PersonForm {
private String name;
private int age;
}
class PersonForm(
private val name: String,
private val age: Int
)
Bean Validation 允许你声明如下示例所示的约束:
-
Java
-
Kotlin
public class PersonForm {
@NotNull
@Size(max=64)
private String name;
@Min(0)
private int age;
}
class PersonForm(
@get:NotNull @get:Size(max=64)
private val name: String,
@get:Min(0)
private val age: Int
)
然后,Bean Validation 验证器会根据声明的约束条件来验证该类的实例。有关该 API 的一般信息,请参阅 Bean Validation。有关特定约束的详细信息,请参阅 Hibernate Validator 文档。若要了解如何将 Bean Validation 提供程序配置为 Spring Bean,请继续阅读。
配置 Bean 验证提供程序
Spring 对 Bean Validation API 提供全面支持,包括将 Bean Validation 提供程序作为 Spring bean 进行引导。这使得你可以在应用程序中任何需要验证的地方注入 jakarta.validation.ValidatorFactory 或 jakarta.validation.Validator。
您可以使用 LocalValidatorFactoryBean 将默认的 Validator 配置为 Spring bean,如下例所示:
-
Java
-
XML
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
@Configuration
public class AppConfig {
@Bean
public LocalValidatorFactoryBean validator() {
return new LocalValidatorFactoryBean();
}
}
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
前面示例中的基本配置会触发 Bean Validation,使用其默认的引导机制进行初始化。系统期望在类路径中存在一个 Bean Validation 提供者(例如 Hibernate Validator),并会自动检测到它。
注入验证器
LocalValidatorFactoryBean 同时实现了 jakarta.validation.ValidatorFactory 和
jakarta.validation.Validator,以及 Spring 的 org.springframework.validation.Validator。
你可以将对其中任意一个接口的引用注入到需要调用验证逻辑的 bean 中。
如果你更倾向于直接使用 Bean Validation API,可以注入一个对 jakarta.validation.Validator 的引用,如下例所示:
-
Java
-
Kotlin
import jakarta.validation.Validator;
@Service
public class MyService {
@Autowired
private Validator validator;
}
import jakarta.validation.Validator;
@Service
class MyService(@Autowired private val validator: Validator)
如果您的 bean 需要使用 Spring 验证 API,您可以注入一个对 org.springframework.validation.Validator 的引用,如下例所示:
-
Java
-
Kotlin
import org.springframework.validation.Validator;
@Service
public class MyService {
@Autowired
private Validator validator;
}
import org.springframework.validation.Validator
@Service
class MyService(@Autowired private val validator: Validator)
配置自定义约束
每个 Bean Validation 约束由两部分组成:
-
一个
@Constraint注解,用于声明约束及其可配置的属性。 -
实现
jakarta.validation.ConstraintValidator接口的类,用于实现约束的行为。
为了将声明与实现关联起来,每个 @Constraint 注解都会引用一个对应的 ConstraintValidator 实现类。在运行时,当在您的领域模型中遇到约束注解时,ConstraintValidatorFactory 会实例化所引用的实现类。
默认情况下,LocalValidatorFactoryBean 会配置一个 SpringConstraintValidatorFactory,
该工厂使用 Spring 来创建 ConstraintValidator 实例。这使得您自定义的
ConstraintValidators 能够像其他 Spring Bean 一样受益于依赖注入。
以下示例展示了一个自定义的 @Constraint 声明,以及一个关联的 ConstraintValidator 实现,该实现使用 Spring 进行依赖注入:
-
Java
-
Kotlin
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=MyConstraintValidator.class)
public @interface MyConstraint {
}
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
@Constraint(validatedBy = MyConstraintValidator::class)
annotation class MyConstraint
-
Java
-
Kotlin
import jakarta.validation.ConstraintValidator;
public class MyConstraintValidator implements ConstraintValidator {
@Autowired;
private Foo aDependency;
// ...
}
import jakarta.validation.ConstraintValidator
class MyConstraintValidator(private val aDependency: Foo) : ConstraintValidator {
// ...
}
如上例所示,ConstraintValidator 的实现可以像其他任何 Spring Bean 一样,通过 @Autowired 注入其依赖项。
Spring 驱动的方法验证
你可以通过一个 MethodValidationPostProcessor bean 定义,将 Bean Validation 1.1(以及作为自定义扩展,Hibernate Validator 4.3 也支持)所提供的方法验证功能集成到 Spring 上下文中:
-
Java
-
XML
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
@Configuration
public class AppConfig {
@Bean
public MethodValidationPostProcessor validationPostProcessor() {
return new MethodValidationPostProcessor();
}
}
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
要使基于 Spring 的方法验证生效,所有目标类都需要使用 Spring 的 @Validated 注解进行标注,该注解还可以可选地声明要使用的验证组。请参阅
MethodValidationPostProcessor
以了解使用 Hibernate Validator 和 Bean Validation 1.1 提供程序的设置详情。
其他配置选项
默认的 LocalValidatorFactoryBean 配置足以满足大多数情况。针对各种 Bean Validation 构造,存在多种配置选项,范围涵盖消息插值到遍历解析。有关这些选项的更多信息,请参阅 LocalValidatorFactoryBean 的 javadoc。
配置一个DataBinder
你可以使用一个 DataBinder 来配置 Validator 实例。配置完成后,可以通过调用 Validator 来触发验证器。所有验证产生的 binder.validate() 会自动添加到绑定器的 Errors 中。
以下示例展示了如何以编程方式使用 DataBinder,在绑定到目标对象后调用验证逻辑:
-
Java
-
Kotlin
Foo target = new Foo();
DataBinder binder = new DataBinder(target);
binder.setValidator(new FooValidator());
// bind to the target object
binder.bind(propertyValues);
// validate the target object
binder.validate();
// get BindingResult that includes any validation errors
BindingResult results = binder.getBindingResult();
val target = Foo()
val binder = DataBinder(target)
binder.validator = FooValidator()
// bind to the target object
binder.bind(propertyValues)
// validate the target object
binder.validate()
// get BindingResult that includes any validation errors
val results = binder.bindingResult
您还可以通过 DataBinder 和 Validator 为 dataBinder.addValidators 配置多个 dataBinder.replaceValidators 实例。当需要将全局配置的 Bean 验证与在 DataBinder 实例上本地配置的 Spring Validator 结合使用时,这种做法非常有用。请参阅
Spring MVC 验证配置。
Spring MVC 3 验证
参见 Spring MVC 章节中的验证部分。