使用 Spring 验证器验证嵌套对象列表?
Posted
技术标签:
【中文标题】使用 Spring 验证器验证嵌套对象列表?【英文标题】:Validate a list of nested objects with Spring validator? 【发布时间】:2012-09-22 17:48:51 【问题描述】:我想知道如何在 Spring MVC 应用程序中使用 Spring Validator(不是注释)来验证我的表单中的嵌套对象列表。
class MyForm()
String myName;
List<TypeA> listObjects;
class TypeA()
String number;
String value;
如何创建 MyFormValidator 来验证 listObjects 并为 TypeA 的数量和值添加错误消息。
【问题讨论】:
【参考方案1】:对于嵌套验证,您可以执行以下操作:
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");
希望这会有所帮助。
【讨论】:
我会推荐这个解决方案。刚刚在我正在进行的项目中遇到了类似的问题。此解决方案允许您保持代码模块化,如果需要,将您的验证拆分为多个不同的验证器。 很高兴它有帮助。我发布此内容的目的是因为它是模块化且易于维护的。 知道如何报告哪一行有错误吗? 当TypeA
有一个属性List<TypeA>
(嵌套)时,这会起作用吗?如果我有一个类是 RuleCondition
... 我可能有一个嵌套的 List<RuleCondition>
字段。我想知道这是否也适用于这种情况
^ 请忽略我的问题,我试过了,它适用于我给定的场景。谢谢!【参考方案2】:
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");
...
...
有趣的链接:
Spring MVC: Multiple Row Form Submit using List of Beans【讨论】:
谢谢,杰罗姆。如果 TypeA 有自己的验证器,如何在 MyFormValidator 中使用验证器?如果有多个错误,如何在表单页面上只显示一条错误消息?【参考方案3】:我使用的一个方便的辅助类 -
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()
【讨论】:
如何使用ValidationHelper类?【参考方案4】:你可以在项目的任何地方使用它
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++;
【讨论】:
以上是关于使用 Spring 验证器验证嵌套对象列表?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ReactJS 中验证嵌套对象的 PropTypes?