# 3.7Spring验证

Spring3为其验证支持引入了一些增强功能。首先，完全支持JSR-303 bean验证API。第二，当以编程方式使用时，Spring的DataBinder既可以验证对象，也可以绑定到对象。第三，SpringMVC支持声明性地验证@Controller输入。

## 3.7.1 JSR-303 Bean Validation API 概览

JSR303标准化了Java平台的验证约束声明和元数据。通过使用此API，你可以使用声明性验证约束来注解域模型属性，并且运行时会强制验证它们。你可以使用许多内置约束。你还可以定义自己的自定义约束。

考虑下面的示例，该示例显示了一个具有两个属性的简单PersonForm模型：

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

JSR-303允许你针对这些属性定义声明性验证约束，如下示例所示：

```
public class PersonForm {

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

    @Min(0)
    private int age;
}
```

当一个JSR-303验证器验证这个类的实例时，这些限制将被执行。

## 3.7.2 配置一个Bean Validation Provider

Spring完全支持bean验证API。这包括对将JSR-303或JSR-349 Bean验证提供者作为SpringBean引导的方便支持。这允许你在应用程序中需要验证的任何位置插入javax.validation.validatorFactory或javax.validation.validator。

你可以使用LocalValidatorFactoryBean将默认验证器配置为Springbean，如下示例所示：

```
<bean id="validator"
    class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
```

前面示例中的基本配置通过使用其默认引导机制触发bean验证进行初始化。JSR-303或JSR-349 provider（如Hibernate验证器）应该出现在类路径中，并被自动检测到。

## 注入一个Validator

LocalValidatorFactoryBean继承了javax.validation.ValidatorFactory, javax.validation.Validator和Spring的org.springframework.validation.Validator。 你可以将对这些接口的引用注入需要调用验证逻辑的bean中。

你可以注入javax.validation.Validator 的引用，如果你想直接使用Bean Validation API ， 如下所示：

```
import javax.validation.Validator;

@Service
public class MyService {

    @Autowired
    private Validator validator;
```

你可以注入org.springframework.validation.Validator的引用，如果你想直接使用Spring Validation API ， 如下所示：

```
import org.springframework.validation.Validator;

@Service
public class MyService {

    @Autowired
    private Validator validator;
}
```

**配置自定义约束**

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

* 声明约束及其可配置属性的@Constraint注解。
* 实现约束行为的javax.validation.ConstraintValidator接口的实现。

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

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

以下示例显示了一个自定义@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实现可以像任何其他SpringBean那样具有其依赖项@Autowired。

**Spring驱动的方法验证**

你可以通过MethodValidationPostProcessor将bean validation 1.1支持的方法验证功能（以及作为自定义扩展的hibernate validator 4.3支持的方法验证功能）集成到Spring上下文中，如下所示：

```
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
```

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

**额外的配置选项**

默认的LocalValidatorFactoryBean配置足以满足大多数情况。对于各种bean验证构造，有许多配置选项，从消息插值到遍历解析。有关这些选项的详细信息，请参阅LocalValidatorFactoryBean javadoc。

## 3.7.3 配置DataBinder

从Spring3开始，你可以使用Validator配置一个DataBinder实例。配置后，可以通过调用binder.validate（）来调用验证器。任何验证错误都会自动添加到binder的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验证结合使用时非常有用。请参见\[验证MVC配置]。

## 3.7.4 Spring MVC 3 验证

请参考 Spring MVC 的 验证章节。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flydean.com/spring-framework-documentation5/core-technologies/3.validation-databinding-typeconversion/3.7spring-validation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
