Java Bean 验证
Spring Framework 提供了对 Java Bean 验证 API 的支持。
Bean 验证概述
Bean Validation 提供了一种通用的验证方法,通过 constraint declaration 和 元数据。要使用它,您可以使用 声明性验证约束,然后由运行时强制执行。有 built-in constraints,您还可以定义自己的自定义 constraints。
请考虑以下示例,该示例显示了一个具有两个属性的简单模型:PersonForm
-
Java
-
Kotlin
public class PersonForm {
private String name;
private int age;
}
class PersonForm(
private val name: String,
private val age: Int
)
Bean 验证允许您声明约束,如下例所示:
-
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 验证器根据声明的 约束。有关 API 的 API 创建。请参阅 Hibernate Validator 文档 特定约束。了解如何将 Bean 验证提供程序设置为 Spring Bean,请继续阅读。
配置 Bean 验证提供程序
Spring 提供了对 Bean 验证 API 的全面支持,包括
Bean Validation 提供程序作为 Spring Bean。这允许您注入 or anywhere 验证
在您的应用程序中需要。jakarta.validation.ValidatorFactory
jakarta.validation.Validator
你可以使用 将默认的 Validator 配置为 Spring
bean,如下例所示:LocalValidatorFactoryBean
-
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 验证以通过以下方式初始化 使用其默认的引导机制。Bean Validation 提供程序,例如 Hibernate Validator 应存在于 Classpath 中,并被自动检测。
注入 Jakarta Validator
LocalValidatorFactoryBean
同时实现 AND ,因此你可以注入对后者的引用
apply 验证逻辑(如果您更喜欢直接使用 Bean 验证 API),
如下例所示:jakarta.validation.ValidatorFactory
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)
注入 Spring 验证器
除了实现 之外,还会适应 ,因此你可以注入一个引用
如果 bean 需要 Spring Validation API,则将其更改为后者。jakarta.validation.Validator
LocalValidatorFactoryBean
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)
当用作 时,调用底层 ,然后将 s 改编为 s,并将它们注册到对象中
传递到方法中。org.springframework.validation.Validator
LocalValidatorFactoryBean
jakarta.validation.Validator
ConstraintViolation
FieldError
Errors
validate
配置自定义约束
每个 bean 验证约束由两部分组成:
-
声明约束及其可配置属性的注释。
@Constraint
-
实现 约束的行为。
jakarta.validation.ConstraintValidator
为了将声明与实现相关联,每个注解
引用相应的实现类。在运行时,当
约束注释。@Constraint
ConstraintValidator
ConstraintValidatorFactory
默认情况下,配置使用 Spring 创建实例。这使您的自定义可以像任何其他 Spring bean 一样从依赖关系注入中受益。LocalValidatorFactoryBean
SpringConstraintValidatorFactory
ConstraintValidator
ConstraintValidators
以下示例显示了一个自定义声明,后跟一个使用 Spring 进行依赖项注入的关联实现:@Constraint
ConstraintValidator
-
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 {
// ...
}
如前面的示例所示,实现可以像任何其他 Spring bean 一样具有其依赖项。ConstraintValidator
@Autowired
Spring 驱动的方法验证
您可以将 Bean Validation 的方法验证功能集成到
Spring 上下文:MethodValidationPostProcessor
-
Java
-
Kotlin
-
Xml
@Configuration
public class ApplicationConfiguration {
@Bean
public static MethodValidationPostProcessor validationPostProcessor() {
return new MethodValidationPostProcessor();
}
}
@Configuration
class ApplicationConfiguration {
companion object {
@Bean
@JvmStatic
fun validationPostProcessor() = MethodValidationPostProcessor()
}
}
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
要获得 Spring 驱动的方法验证的资格,需要对目标类进行注释
替换为 Spring 的注解,它也可以选择性地声明验证
要使用的组。参见MethodValidationPostProcessor
来获得 Hibernate Validator 和 Bean Validation 提供程序的设置细节。@Validated
Spring MVC 和 WebFlux 内置了对相同底层方法验证的支持,但没有 对 AOP 的需求。因此,请检查本节的其余部分,并参阅 Spring MVC 验证和错误响应部分,以及 WebFlux 验证和错误响应部分。
方法验证异常
默认情况下,使用 返回的 s 集引发。作为替代方案,
你可以用 S 来代替 Raise
适应错误。要启用,请设置以下标志:jakarta.validation.ConstraintViolationException
ConstraintViolation
jakarta.validation.Validator
MethodValidationException
ConstraintViolation
MessageSourceResolvable
-
Java
-
Kotlin
-
Xml
@Configuration
public class ApplicationConfiguration {
@Bean
public static MethodValidationPostProcessor validationPostProcessor() {
MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
processor.setAdaptConstraintViolations(true);
return processor;
}
}
@Configuration
class ApplicationConfiguration {
companion object {
@Bean
@JvmStatic
fun validationPostProcessor() = MethodValidationPostProcessor().apply {
setAdaptConstraintViolations(true)
}
}
}
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor">
<property name="adaptConstraintViolations" value="true"/>
</bean>
MethodValidationException
包含一个 s 列表,其中
按方法参数对错误进行分组,每个错误都会公开一个 、 参数
值,以及改编自 s 的错误列表。对于级联冲突开启的方法参数
fields 和 properties 中,是 which
将验证错误实现并公开为 S。ParameterValidationResult
MethodParameter
MessageSourceResolvable
ConstraintViolation
@Valid
ParameterValidationResult
ParameterErrors
org.springframework.validation.Errors
FieldError
自定义验证错误
调整后的错误可以转换为错误消息,以
通过配置的区域设置和特定于语言的
资源包。本节提供了一个示例进行说明。MessageSourceResolvable
MessageSource
给定以下类声明:
-
Java
-
Kotlin
record Person(@Size(min = 1, max = 10) String name) {
}
@Validated
public class MyService {
void addStudent(@Valid Person person, @Max(2) int degrees) {
// ...
}
}
@JvmRecord
internal data class Person(@Size(min = 1, max = 10) val name: String)
@Validated
class MyService {
fun addStudent(person: @Valid Person?, degrees: @Max(2) Int) {
// ...
}
}
a on 改编为 a ,如下所示:ConstraintViolation
Person.name()
FieldError
-
错误代码 、 、 和
"Size.person.name"
"Size.name"
"Size.java.lang.String"
"Size"
-
消息参数 、 和 (字段名称和 constraint 属性)
"name"
10
1
-
默认消息 “size must be between 1 and 10”
要自定义默认消息,您可以使用上述任何错误代码和消息参数将属性添加到 MessageSource 资源包中。另请注意,
message 参数本身是一个带有错误代码的 和 并且也可以自定义。例如:"name"
MessageSourceResolvable
"person.name"
"name"
- 性能
-
Size.person.name=Please, provide a {0} that is between {2} and {1} characters long person.name=username
a 对 method 参数进行以下调整为 a:ConstraintViolation
degrees
MessageSourceResolvable
-
错误代码 、 、 、
"Max.myService#addStudent.degrees"
"Max.degrees"
"Max.int"
"Max"
-
消息参数 “degrees2 和 2 (字段名称和 constraint 属性)
-
默认消息 “must be less than or equal to 2”
要自定义上述默认消息,您可以添加如下属性:
- 性能
-
Max.degrees=You cannot provide more than {1} {0}
其他配置选项
默认配置足以满足大多数
例。各种 Bean 验证有许多配置选项
构造,从消息插值到遍历解析。有关这些选项的更多信息,请参见LocalValidatorFactoryBean
javadoc。LocalValidatorFactoryBean
配置DataBinder
您可以使用 .配置完成后,您可以
通过调用 来调用 。任何验证都是
自动添加到 Binder 的 .DataBinder
Validator
Validator
binder.validate()
Errors
BindingResult
以下示例演示如何以编程方式使用 a 调用验证
绑定到目标对象后的逻辑: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
您还可以通过 和 配置具有多个实例的 。这在以下情况下很有用
将全局配置的 bean 验证与配置的 Spring 相结合
本地的 DataBinder 实例。参见 Spring MVC 验证配置。DataBinder
Validator
dataBinder.addValidators
dataBinder.replaceValidators
Validator
Spring MVC 3 验证
参见 Spring MVC 一章中的 验证。