此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.2.0! |
使用 Spring 的 Validator 接口进行验证
Spring 具有Validator
可用于验证对象的接口。这Validator
interface 通过使用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
helper 类。以下内容
示例 implementsValidator
为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 用于
reject 的name
property (如果是null
或空字符串。看看ValidationUtils
Javadoc
以查看除了前面显示的示例之外,它还提供了哪些功能。
虽然当然可以实现单个Validator
类来验证每个
的嵌套对象中,最好将验证
每个嵌套类的对象在其自己的 logicValidator
实现。一个简单的
“rich” 对象的示例是Customer
它由两个String
属性(名字和第二个名称)和复杂Address
对象。Address
对象
可以独立使用Customer
对象,因此AddressValidator
已实施。如果您希望您的CustomerValidator
以重用包含的 logic
在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 中,您可以使用<spring:bind/>
标签来检查错误消息,但
您还可以检查Errors
反对自己。有关
它提供的方法可以在 Javadoc 中找到。
验证器也可以在本地调用以立即验证给定对象。
不涉及绑定过程。从 6.1 开始,这已通过新的Validator.validateObject(Object)
方法,返回
一个简单的Errors
表示:通常调用hasErrors()
或新的failOnError
将错误摘要消息转换为异常的方法
(例如,validator.validateObject(myObject).failOnError(IllegalArgumentException::new)
).