此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10! |
使用 Spring 的验证器接口进行验证
Spring 具有Validator
可用于验证对象的接口。这Validator
接口的工作原理是使用Errors
对象,以便在验证时,
验证者可以向Errors
对象。
考虑以下小数据对象的示例:
-
Java
-
Kotlin
public class Person {
private String name;
private int age;
// the usual getters and setters...
}
class Person(val name: String, val age: Int)
下一个示例提供了Person
类通过实现
以下两种方法org.springframework.validation.Validator
接口:
-
supports(Class)
:可以这样吗Validator
验证提供的实例Class
? -
validate(Object, org.springframework.validation.Errors)
:验证给定对象 并且,如果出现验证错误,则将这些错误与给定的Errors
对象。
实现Validator
相当简单,尤其是当您知道ValidationUtils
Spring Framework 也提供的 helper 类。以下内容
示例机具Validator
为Person
实例:
-
Java
-
Kotlin
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");
}
}
}
class PersonValidator : Validator {
/**
* This Validator validates only Person instances
*/
override fun supports(clazz: Class<*>): Boolean {
return Person::class.java == clazz
}
override fun validate(obj: Any, e: Errors) {
ValidationUtils.rejectIfEmpty(e, "name", "name.empty")
val p = obj as Person
if (p.age < 0) {
e.rejectValue("age", "negativevalue")
} else if (p.age > 110) {
e.rejectValue("age", "too.darn.old")
}
}
}
这static
rejectIfEmpty(..)
方法ValidationUtils
class 用于
拒绝name
属性(如果是)null
或空字符串。看看ValidationUtils
Java文档
查看除了前面显示的示例之外,它还提供哪些功能。
虽然当然可以实现单个Validator
类来验证每个
对于富对象中的嵌套对象,封装验证可能更好
逻辑Validator
实现。一个简单的
“丰富”对象的示例是Customer
由两个组成String
属性(名字和第二个名字)和复合体Address
对象。Address
对象
可以独立使用Customer
对象,因此AddressValidator
已经实施。如果你想要你的CustomerValidator
重用包含的逻辑
在AddressValidator
类,无需诉诸复制和粘贴,您可以
dependency-inject 或实例化AddressValidator
在您的CustomerValidator
,
如以下示例所示:
-
Java
-
Kotlin
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();
}
}
}
class CustomerValidator(private val addressValidator: Validator) : Validator {
init {
if (addressValidator == null) {
throw IllegalArgumentException("The supplied [Validator] is required and must not be null.")
}
if (!addressValidator.supports(Address::class.java)) {
throw IllegalArgumentException("The supplied [Validator] must support the validation of [Address] instances.")
}
}
/*
* This Validator validates Customer instances, and any subclasses of Customer too
*/
override fun supports(clazz: Class<>): Boolean {
return Customer::class.java.isAssignableFrom(clazz)
}
override fun validate(target: Any, errors: Errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "field.required")
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "surname", "field.required")
val customer = target as Customer
try {
errors.pushNestedPath("address")
ValidationUtils.invokeValidator(this.addressValidator, customer.address, errors)
} finally {
errors.popNestedPath()
}
}
}
验证错误将报告给Errors
对象传递给验证者。在这种情况下
Spring Web MVC 的 MVC,您可以使用<spring:bind/>
标记来检查错误消息,但
您还可以检查Errors
反对自己。有关
它提供的方法可以在 JavaDoc 中找到。
验证器也可以在本地被调用以立即验证给定对象,
不涉及绑定过程。从 6.1 开始,这已通过新的Validator.validateObject(Object)
方法,该方法现在默认可用,返回
一个简单的Errors
可以检查的表示:通常调用hasErrors()
或新的failOnError
将错误摘要消息转换为异常的方法
(例如,validator.validateObject(myObject).failOnError(IllegalArgumentException::new)
).