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

Java Bean 验证

Spring Framework 提供对 Java Bean Validation API 的支持。spring-doc.cadn.net.cn

Bean 验证概述

Bean Validation 通过约束声明和 Java 应用程序的元数据。要使用它,请使用 声明性验证约束,然后由运行时强制执行。有 内置约束,你也可以定义自己的自定义约束。spring-doc.cadn.net.cn

考虑以下示例,该示例显示了一个简单的PersonForm具有两个属性的模型:spring-doc.cadn.net.cn

public class PersonForm {
	private String name;
	private int age;
}
class PersonForm(
		private val name: String,
		private val age: Int
)

Bean Validation 允许您声明约束,如以下示例所示:spring-doc.cadn.net.cn

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 的一般信息,请参阅 Bean Validation。有关特定约束。要了解如何将 Bean 验证提供程序设置为 Springbean,请继续阅读。spring-doc.cadn.net.cn

配置 Bean 验证提供程序

Spring 为 Bean Validation API 提供全面支持,包括将Bean Validation 提供程序引导为 Spring Bean。这使您可以注入一个jakarta.validation.ValidatorFactoryjakarta.validation.Validator无论在哪里验证在您的应用程序中都需要。spring-doc.cadn.net.cn

您可以使用LocalValidatorFactoryBean将默认验证器配置为 Springbean,如以下示例所示:spring-doc.cadn.net.cn

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 验证提供程序,例如 HibernateValidator,应存在于类路径中并自动检测。spring-doc.cadn.net.cn

注入雅加达验证器

LocalValidatorFactoryBean实现两者jakarta.validation.ValidatorFactoryjakarta.validation.Validator,因此您可以将对后者的引用注入到应用验证逻辑,如果您更喜欢直接使用 Bean 验证 API,如以下示例所示:spring-doc.cadn.net.cn

import jakarta.validation.Validator;

@Service
public class MyService {

	@Autowired
	private Validator validator;
}
import jakarta.validation.Validator;

@Service
class MyService(@Autowired private val validator: Validator)

注入弹簧验证器

除了实施jakarta.validation.Validator,LocalValidatorFactoryBean也适应org.springframework.validation.Validator,这样您就可以注入引用如果您的 bean 需要 Spring Validation API,则可以注入后者。spring-doc.cadn.net.cn

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)

当用作org.springframework.validation.Validator,LocalValidatorFactoryBean调用基础jakarta.validation.Validator,然后适应ConstraintViolations 设置为FieldErrors,并将它们注册到Errors对象 传递到validate方法。spring-doc.cadn.net.cn

配置自定义约束

每个 bean 验证约束由两部分组成:spring-doc.cadn.net.cn

要将声明与实现相关联,每个@Constraint注解 引用相应的ConstraintValidator实现类。在运行时,一个ConstraintValidatorFactory实例化引用的实现,当在域模型中遇到constraint 注释。spring-doc.cadn.net.cn

默认情况下,LocalValidatorFactoryBean配置一个SpringConstraintValidatorFactory使用 Spring 创建ConstraintValidator实例。 这可以让您的自定义ConstraintValidators像任何其他 Spring Bean 一样受益于依赖注入。spring-doc.cadn.net.cn

以下示例显示了自定义@Constraint声明后跟关联的ConstraintValidator使用 Spring 进行依赖注入的实现:spring-doc.cadn.net.cn

@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
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实现可以有其依赖关系@Autowired和任何其他春豆一样。spring-doc.cadn.net.cn

弹簧驱动方法验证

您可以通过 Bean Validation 的方法验证功能集成到Spring 上下文中,通过MethodValidationPostProcessor豆子定义:spring-doc.cadn.net.cn

@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 的@Validated注释,也可以选择声明验证组。 看MethodValidationPostProcessor有关 Hibernate Validator 和 Bean Validation 提供程序的设置详细信息。spring-doc.cadn.net.cn

方法验证依赖于 AOP 代理目标类,接口上方法的 JDK 动态代理或 CGLIB 代理。使用代理存在某些限制,其中一些限制在了解 AOP 代理中进行了描述。此外,请记住始终在代理类上使用方法和访问器;直接字段访问将不起作用。spring-doc.cadn.net.cn

Spring MVC 和 WebFlux 内置了对相同底层方法验证的支持,但没有 AOP 的必要性。因此,请检查本节的其余部分,并参见 Spring MVC 验证错误响应部分,以及 WebFlux 验证错误响应部分。spring-doc.cadn.net.cn

方法验证异常

默认情况下,jakarta.validation.ConstraintViolationException用集合ConstraintViolations 返回者jakarta.validation.Validator.作为替代方案, 你可以拥有MethodValidationExceptionraise 代替ConstraintViolations 适应MessageSourceResolvable错误。要启用,请设置以下标志:spring-doc.cadn.net.cn

@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包含以下列表ParameterValidationResults 其中 按方法参数对错误进行分组,每个参数都会公开一个MethodParameter,参数 value,以及MessageSourceResolvable错误改编自ConstraintViolations.为@Valid方法参数,并具有级联违规 字段和属性,则ParameterValidationResultParameterErrors哪 实现org.springframework.validation.Errors并将验证错误公开为FieldErrors.spring-doc.cadn.net.cn

自定义验证错误

适应的MessageSourceResolvable错误可以转换为错误消息 通过配置的MessageSource具有特定于区域设置和语言的语言 资源包。本节提供了一个示例以供说明。spring-doc.cadn.net.cn

给定以下类声明:spring-doc.cadn.net.cn

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) {
		// ...
	}
}

一个ConstraintViolationPerson.name()适应FieldError替换为以下内容:spring-doc.cadn.net.cn

若要自定义默认消息,可以使用上述任何错误代码和消息参数向 MessageSource 资源包添加属性。另请注意, message 参数"name"本身就是一个MessageSourceResolvable带有错误代码"person.name""name"也可以定制。例如:spring-doc.cadn.net.cn

性能
Size.person.name=Please, provide a {0} that is between {2} and {1} characters long
person.name=username

一个ConstraintViolationdegreesmethod 参数适配为MessageSourceResolvable替换为以下内容:spring-doc.cadn.net.cn

要自定义上述默认消息,您可以添加一个属性,例如:spring-doc.cadn.net.cn

性能
Max.degrees=You cannot provide more than {1} {0}

其他配置选项

默认值LocalValidatorFactoryBean配置足以满足大多数需求 例。各种 Bean 验证有许多配置选项 结构,从消息插值到遍历解析。请参阅LocalValidatorFactoryBeanjavadoc 以获取有关这些选项的更多信息。spring-doc.cadn.net.cn

配置DataBinder

您可以配置DataBinder实例与Validator.配置后,您可以 调用Validator通过调用binder.validate().任何验证Errors是 自动添加到活页夹的BindingResult.spring-doc.cadn.net.cn

以下示例显示如何使用DataBinder以编程方式调用验证绑定到目标对象后的逻辑:spring-doc.cadn.net.cn

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.addValidatorsdataBinder.replaceValidators. 这在以下情况下很有用:将全局配置的 bean 验证与 Spring 相结合Validator配置 本地在 DataBinder 实例上。请参阅 Spring MVC 验证配置spring-doc.cadn.net.cn

Spring MVC 验证

请参阅 Spring MVC 章节中的验证spring-doc.cadn.net.cn