对于最新的稳定版本,请使用 Spring Framework 6.2.4spring-doc.cadn.net.cn

Java Bean 验证

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

Bean 验证概述

Bean Validation 提供了一种通用的验证方法,通过 constraint declaration 和 元数据。要使用它,您可以使用 声明性验证约束,然后由运行时强制执行。有 built-in constraints,您还可以定义自己的自定义 constraints。spring-doc.cadn.net.cn

请考虑以下示例,它显示了一个简单的PersonFormmodel 具有两个属性: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 验证允许您声明约束,如下例所示: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 的 API 创建。请参阅 Hibernate Validator 文档 特定约束。了解如何将 Bean 验证提供程序设置为 Spring Bean,请继续阅读。spring-doc.cadn.net.cn

配置 Bean 验证提供程序

Spring 提供了对 Bean 验证 API 的全面支持,包括 Bean Validation 提供程序作为 Spring Bean。这样,您就可以在邮件中注入jakarta.validation.ValidatorFactoryjakarta.validation.ValidatorWhere 验证 在您的应用程序中需要。spring-doc.cadn.net.cn

您可以使用LocalValidatorFactoryBean将默认 Validator 配置为 Spring bean,如下例所示: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"/>

The basic configuration in the preceding example triggers bean validation to initialize by using its default bootstrap mechanism. A Bean Validation provider, such as the Hibernate Validator, is expected to be present in the classpath and is automatically detected.spring-doc.cadn.net.cn

Injecting a Validator

LocalValidatorFactoryBean implements both jakarta.validation.ValidatorFactory and jakarta.validation.Validator, as well as Spring’s org.springframework.validation.Validator. You can inject a reference to either of these interfaces into beans that need to invoke validation logic.spring-doc.cadn.net.cn

You can inject a reference to jakarta.validation.Validator if you prefer to work with the Bean Validation API directly, as the following example shows: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)

You can inject a reference to org.springframework.validation.Validator if your bean requires the Spring Validation API, as the following example shows: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)

Configuring Custom Constraints

Each bean validation constraint consists of two parts:spring-doc.cadn.net.cn

  • A @Constraint annotation that declares the constraint and its configurable properties.spring-doc.cadn.net.cn

  • An implementation of the jakarta.validation.ConstraintValidator interface that implements the constraint’s behavior.spring-doc.cadn.net.cn

To associate a declaration with an implementation, each @Constraint annotation references a corresponding ConstraintValidator implementation class. At runtime, a ConstraintValidatorFactory instantiates the referenced implementation when the constraint annotation is encountered in your domain model.spring-doc.cadn.net.cn

By default, the LocalValidatorFactoryBean configures a SpringConstraintValidatorFactory that uses Spring to create ConstraintValidator instances. This lets your custom ConstraintValidators benefit from dependency injection like any other Spring bean.spring-doc.cadn.net.cn

The following example shows a custom @Constraint declaration followed by an associated ConstraintValidator implementation that uses Spring for dependency injection: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 {

	// ...
}

As the preceding example shows, a ConstraintValidator implementation can have its dependencies @Autowired as any other Spring bean.spring-doc.cadn.net.cn

Spring-driven Method Validation

You can integrate the method validation feature supported by Bean Validation 1.1 (and, as a custom extension, also by Hibernate Validator 4.3) into a Spring context through a MethodValidationPostProcessor bean definition:spring-doc.cadn.net.cn

import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;

@Configuration
public class AppConfig {

	@Bean
	public MethodValidationPostProcessor validationPostProcessor() {
		return new MethodValidationPostProcessor();
	}
}
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>

To be eligible for Spring-driven method validation, all target classes need to be annotated with Spring’s @Validated annotation, which can optionally also declare the validation groups to use. See MethodValidationPostProcessor for setup details with the Hibernate Validator and Bean Validation 1.1 providers.spring-doc.cadn.net.cn

Method validation relies on AOP Proxies around the target classes, either JDK dynamic proxies for methods on interfaces or CGLIB proxies. There are certain limitations with the use of proxies, some of which are described in Understanding AOP Proxies. In addition remember to always use methods and accessors on proxied classes; direct field access will not work.spring-doc.cadn.net.cn

Additional Configuration Options

The default LocalValidatorFactoryBean configuration suffices for most cases. There are a number of configuration options for various Bean Validation constructs, from message interpolation to traversal resolution. See the LocalValidatorFactoryBean javadoc for more information on these options.spring-doc.cadn.net.cn

Configuring a DataBinder

You can configure a DataBinder instance with a Validator. Once configured, you can invoke the Validator by calling binder.validate(). Any validation Errors are automatically added to the binder’s BindingResult.spring-doc.cadn.net.cn

The following example shows how to use a DataBinder programmatically to invoke validation logic after binding to a target object: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

You can also configure a DataBinder with multiple Validator instances through dataBinder.addValidators and dataBinder.replaceValidators. This is useful when combining globally configured bean validation with a Spring Validator configured locally on a DataBinder instance. See Spring MVC Validation Configuration.spring-doc.cadn.net.cn

Spring MVC 3 Validation

See Validation in the Spring MVC chapter.spring-doc.cadn.net.cn