3.7. Java Bean 验证

Spring Framework 提供对 Java Bean Validation API 的支持。

3.7.1. Bean 验证概述

Bean Validation 通过约束声明和 Java 应用程序的元数据提供了一种通用的验证方式。要使用它,您可以使用声明性验证约束来注解域模型属性,然后由运行时强制执行。有内置约束,您也可以定义自己的自定义约束。

考虑以下示例,该示例显示了一个PersonForm具有两个属性的简单模型:

public class PersonForm {
    private String name;
    private int age;
}

Bean Validation 允许您声明约束,如以下示例所示:

public class PersonForm {

    @NotNull
    @Size(max=64)
    private String name;

    @Min(0)
    private int age;
}

一个 Bean Validation 验证器然后根据声明的约束来验证这个类的实例。有关 API 的一般信息,请参阅Bean 验证。有关特定约束,请参阅Hibernate Validator文档。要了解如何将 bean 验证提供程序设置为 Spring bean,请继续阅读。

3.7.2. 配置 Bean 验证提供程序

Spring 为 Bean Validation API 提供全面支持,包括将 Bean Validation 提供者引导为 Spring bean。这使您可以在应用程序中任何需要验证的位置注入一个 javax.validation.ValidatorFactoryjavax.validation.Validator

您可以使用 LocalValidatorFactoryBean将默认验证器配置为 Spring bean,如以下示例所示:

import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

@Configuration
public class AppConfig {

    @Bean
    public LocalValidatorFactoryBean validator() {
        return new LocalValidatorFactoryBean();
    }
}

前面示例中的基本配置触发 bean 验证以使用其默认引导机制进行初始化。Bean Validation 提供程序,例如 Hibernate Validator,预计会出现在类路径中并且会被自动检测到。

注入验证器

LocalValidatorFactoryBean实现javax.validation.ValidatorFactoryjavax.validation.Validator以及 Spring 的org.springframework.validation.Validator. 您可以将对这些接口中的任何一个的引用注入到需要调用验证逻辑的 bean 中。

如果您更喜欢直接使用 Bean Validation API,您可以注入一个引用javax.validation.Validator,如以下示例所示:

import javax.validation.Validator;

@Service
public class MyService {

    @Autowired
    private Validator validator;
}

如果您的 bean 需要 Spring Validation API,您可以注入一个引用org.springframework.validation.Validator,如以下示例所示:

import org.springframework.validation.Validator;

@Service
public class MyService {

    @Autowired
    private Validator validator;
}

配置自定义约束

每个 bean 验证约束由两部分组成:

  • @Constraint声明约束及其可配置属性的注解。

  • javax.validation.ConstraintValidator实现约束行为的接口的实现。

要将声明与实现相关联,每个@Constraint注解都引用相应的ConstraintValidator实现类。在运行时, ConstraintValidatorFactory当在域模型中遇到约束注解时,实例化引用的实现。

默认情况下,LocalValidatorFactoryBean 配置一个 SpringConstraintValidatorFactory,它使用 Spring 创建ConstraintValidator 实例。这可以让您的自定义ConstraintValidators像任何其他 Spring bean 一样从依赖注入中受益。

以下示例显示了一个自定义@Constraint声明,后跟一个使用 Spring 进行依赖注入的关联 ConstraintValidator实现:

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=MyConstraintValidator.class)
public @interface MyConstraint {
}
import javax.validation.ConstraintValidator;

public class MyConstraintValidator implements ConstraintValidator {

    @Autowired;
    private Foo aDependency;

    // ...
}

如前面的示例所示,ConstraintValidator 实现可以像任何其他 Spring bean 一样具有其依赖项 @Autowired

spring驱动的方法验证

您可以通过 MethodValidationPostProcessor bean 定义将 Bean Validation 1.1(以及作为自定义扩展,也由 Hibernate Validator 4.3)支持的方法验证功能集成到 Spring 上下文中:

import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;

@Configuration
public class AppConfig {

    @Bean
    public MethodValidationPostProcessor validationPostProcessor() {
        return new MethodValidationPostProcessor();
    }
}

为了符合 Spring 驱动的方法验证的条件,所有目标类都需要使用 Spring 的@Validated注解进行注解,它还可以选择声明要使用的验证组。请参阅 MethodValidationPostProcessor Hibernate Validator 和 Bean Validation 1.1 提供程序的设置详细信息。

方法验证依赖于目标类周围的AOP 代理,要么是接口上方法的 JDK 动态代理,要么是 CGLIB 代理。使用代理有某些限制,其中一些在 了解 AOP 代理中进行了描述。此外,请记住始终在代理类上使用方法和访问器;直接字段访问将不起作用。

其他配置选项

对于大多数情况,LocalValidatorFactoryBean默认配置就足够了。从消息插值到遍历解析,各种 Bean Validation 构造都有许多配置选项。有关这些选项的更多信息,请参阅 LocalValidatorFactoryBean javadoc。

3.7.3. 配置DataBinder

从 Spring 3 开始,您可以使用 Validator 配置 DataBinder 实例. 配置完成后,您可以通过调用binder.validate()来调用Validator. 任何验证 Errors都会自动添加到活页夹的BindingResult.

以下示例显示了如何在绑定到目标对象后以DataBinder编程方式调用验证逻辑:

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();

您还可以通过 dataBinder.addValidators dataBinder.replaceValidators 配置具有多个 Validator 实例的 DataBinder。当将全局配置的 bean 验证与 DataBinder 实例上本地配置的 Spring Validator 相结合时,这非常有用。请参阅 Spring MVC 验证配置。

3.7.4. Spring MVC 3 验证

请参阅Spring MVC 章节中的验证

最后更新于