5.2 使用Spring的验证器接口进行验证 {#toc_2}
Spring具有一个Validator
接口可以让你用于验证对象。Validator
接口在工作时需要使用一个Errors
对象,以便于在验证过程中,验证器可以将验证失败的信息报告给这个Errors
对象。
让我们考虑一个小的数据对象:
public class Person {
private String name;
private int age;
// the usual getters and setters...
}
通过实现org.springframework.validation.Validator
的下列两个接口,我们打算为Person
类提供验证行为:
support(Class)
– 这个Validator
是否可以验证给定Class
的实例validate(Object,org.springframework.validation.Errors)
- – 验证给定的对象并且万一验证错误,可以将这些错误注册到给定的
Errors
对象
实现一个Validator
是相当简单的,特别是当你知道Spring框架还提供了ValidationUtils
辅助类:
public class PersonValidator implements Validator {
/**
* This Validator validates *just* Person instances
*/
public boolean supports(Class clazz) {
return Person.class.equals(clazz);
}
public void validate(Object obj, Errors e) {
ValidationUtils.rejectIfEmpty(e, "name", "name.empty");
Person p = (Person) obj;
if (p.getAge() < 0) {
e.rejectValue("age", "negativevalue");
} else if (p.getAge() > 110) {
e.rejectValue("age", "too.darn.old");
}
}
}
正如你看到的,ValidationUtils
类的静态方法rejectIfEmpty(..)
被用于拒绝那些值为null
或者空字符串的'name'
属性。除了上面展示的例子之外,去看一看ValidationUtils
的java文档有助于了解它提供的功能。
通过实现单个的Validator
类来逐个验证富对象中的嵌套对象当然是有可能的,然而将验证逻辑封装在每个嵌套类对象自身的Validator
实现中可能是一种更好的选择。Customer
就是一个‘富’对象的简单示例,它由两个字符串属性(姓和名)以及一个复杂对象Address
组成。Address
对象可能独立于Customer
对象使用,因此已经实现了一个独特的AddressValidator
。如果你想要你的CustomerValidator
不借助于复制粘贴而重用包含在AddressValidator
中的逻辑,那么你可以通过依赖注入或者实例化你的CustomerValidator
中的AddressValidator
,然后像这样使用它:
public class CustomerValidator implements Validator {
private final Validator addressValidator;
public CustomerValidator(Validator addressValidator) {
if (addressValidator == null) {
throw new IllegalArgumentException("The supplied [Validator] is " +
"required and must not be null.");
}
if (!addressValidator.supports(Address.class)) {
throw new IllegalArgumentException("The supplied [Validator] must " +
"support the validation of [Address] instances.");
}
this.addressValidator = addressValidator;
}
/**
* This Validator validates Customer instances, and any subclasses of Customer too
*/
public boolean supports(Class clazz) {
return Customer.class.isAssignableFrom(clazz);
}
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "field.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "surname", "field.required");
Customer customer = (Customer) target;
try {
errors.pushNestedPath("address");
ValidationUtils.invokeValidator(this.addressValidator, customer.getAddress(), errors);
} finally {
errors.popNestedPath();
}
}
}
验证错误被报告给传递到验证器的Errors
对象。在使用Spring Web MVC的情况下,你可以使用<spring:bind/>
标签来检查错误信息,不过当然你也可以自己检查错误对象。有关它提供的方法的更多信息可以在java文档中找到。