3.1使用Spring Validator接口

Spring提供了一个Validator接口,你可以使用它来验证对象。Validator接口通过使用Errors对象工作,以便在验证时,验证程序可以向Errors对象报告验证失败。

考虑下面的小数据对象示例:

public class Person {

    private String name;
    private int age;

    // the usual getters and setters...
}

下面例子提供了Person的验证方式,通过实现org.springframework.validation.Validator接口的下面两个方法:

  • supports(Class): 该Class是否支持Validator

  • validate(Object, org.springframework.validation.Errors): 验证给定的对象,如果验证失败,将错误注册到Errors对象。

实现Validator很简单,尤其当你知道Spring框架提供的ValidationUtils帮助类,下面是Person Validator的例子:

public class PersonValidator implements Validator {

    /**
     * This Validator validates *only* 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类上的static rejectIfEmpty(..) 方法用于拒绝name属性(如果该属性为空或空字符串)。查看 ValidationUtils javadoc,了解它除了前面的示例外还提供了哪些功能。

虽然可以实现单个验证器类来验证富对象中的每个嵌套对象,但最好将对象的每个嵌套类的验证逻辑封装在自己的验证器实现中。“rich”对象的一个简单示例是由两个字符串属性(名字和第二个名字)和一个复杂地址对象组成的Customer。地址对象可以独立于客户对象使用,因此实现了一个不同的地址验证器。如果希望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();
        }
    }
}

验证错误将报告给传递给验证程序的错误对象。对于SpringWeb MVC,可以使用\标记检查错误消息,但也可以自己检查Errors对象。关于它提供的方法的更多信息可以在javadoc中找到。

最后更新于