我想知道如何在 Spring MVC 应用程序中使用 Spring Validator(不是注释)验证表单中的嵌套对象列表。
class MyForm() {
String myName;
List<TypeA> listObjects;
}
class TypeA() {
String number;
String value;
}
如何创建 MyFormValidator 来验证 listObjects 并为 TypeA 的数量和值添加错误消息。
我想知道如何在 Spring MVC 应用程序中使用 Spring Validator(不是注释)验证表单中的嵌套对象列表。
class MyForm() {
String myName;
List<TypeA> listObjects;
}
class TypeA() {
String number;
String value;
}
如何创建 MyFormValidator 来验证 listObjects 并为 TypeA 的数量和值添加错误消息。
对于嵌套验证,您可以执行以下操作:
public class MyFormValidator implements Validator {
private TypeAValidator typeAValidator;
@Override
public boolean supports(Class clazz) {
return MyForm.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
MyForm myForm = (MyForm) target;
typeAValidator = new TypeAValidator();
int idx = 0;
for (TypeA item : myForm.getListObjects()) {
errors.pushNestedPath("listObjects[" + idx + "]");
ValidationUtils.invokeValidator(this.typeAValidator, item, errors);
errors.popNestedPath();
idx++;
...
}
...
}
}
public class TypeAValidator implements Validator{
@Override
public boolean supports(Class<?> clazz) {
return TypeA.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
TypeA objTypeA = (TypeA)target;
ValidationUtils.rejectIfEmpty(errors, "number", "number.notEmpty");
}
}
希望这可以帮助。
public class MyFormValidator implements Validator {
@Override
public boolean supports(Class clazz) {
return MyForm.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
MyForm myForm = (MyForm) target;
for (int i = 0; i < myForm.getListObjects().size(); i++) {
TypeA typeA = myForm.getListObjects().get(i);
if(typeAHasAnErrorOnNumber) {
errors.rejectValue("listObjects[" + i + "].number", "your_error_code");
}
...
}
...
}
}
有趣的链接:
我使用的一个方便的助手类 -
public final class ValidationHelper {
public static <TEntity> void invokeNestedValidator(Validator validator, TEntity entity, Errors errors, String subPath) {
try {
errors.pushNestedPath(subPath);
ValidationUtils.invokeValidator(validator, entity, errors);
} finally {
errors.popNestedPath();
}
}
public static <TEntity> void invokeNestedValidatorForList(Validator validator, List<TEntity> entities, Errors errors, String subPathRoot) {
for (int index = 0; index < entities.size(); index++) {
invokeNestedValidator(validator, entities.get(index), errors, subPathRoot + "[" + index + "]");
}
}
private ValidationHelper() {}
}
您可以在项目的任何地方使用它
import org.springframework.validation.ValidationUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.CollectionUtils;
public static void invokeValidatorForNestedCollection(Validator validator,
Object obj,
String collectionPath,
Errors errors) {
Collection collection;
try {
collection = (Collection) PropertyUtils.getProperty(obj, collectionPath);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
if (CollectionUtils.isEmpty(collection)) return;
int counter = 0;
for (Object elem : collection) {
errors.pushNestedPath(String.format(collectionPath + "[%d]", counter));
ValidationUtils.invokeValidator(validator, elem, errors);
errors.popNestedPath();
counter++;
}
}