Java 是否使用Spring验证程序验证嵌套对象列表?
我想知道如何在SpringMVC应用程序中使用SpringValidator(而不是注释)验证表单中的嵌套对象列表Java 是否使用Spring验证程序验证嵌套对象列表?,java,list,spring-mvc,nested,validation,Java,List,Spring Mvc,Nested,Validation,我想知道如何在SpringMVC应用程序中使用SpringValidator(而不是注释)验证表单中的嵌套对象列表 class MyForm() { String myName; List<TypeA> listObjects; } class TypeA() { String number; String value; } class MyForm(){ 字符串myName; 列出列表对象; } A类(){ 字符串编号; 字符串值; } 如何创建
class MyForm() {
String myName;
List<TypeA> listObjects;
}
class TypeA() {
String number;
String value;
}
class MyForm(){
字符串myName;
列出列表对象;
}
A类(){
字符串编号;
字符串值;
}
如何创建MyFormValidator来验证listObjects,并为TypeA的编号和值添加错误消息。公共类MyFormValidator实现验证程序{
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");
}
...
}
...
}
}
@凌驾
公共布尔支持(类clazz){
返回MyForm.class.equals(clazz);
}
@凌驾
公共无效验证(对象目标、错误){
MyForm MyForm=(MyForm)目标;
对于(int i=0;i
有趣的链接:
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");
}
}
公共类MyFormValidator实现验证器{
私有类型avalidator类型avalidator;
@凌驾
公共布尔支持(类clazz){
返回MyForm.class.equals(clazz);
}
@凌驾
公共无效验证(对象目标、错误){
MyForm MyForm=(MyForm)目标;
TypeAvailator=新的TypeAvailator();
int-idx=0;
对于(TypeA项:myForm.getListObjects()){
错误。pushNestedPath(“listObjects[“+idx+”]);
ValidationUtils.invokeValidator(this.typeAValidator,item,errors);
错误。popNestedPath();
idx++;
...
}
...
}
}
公共类TypeAvailator实现验证器{
@凌驾
公共布尔支持(类clazz){
返回TypeA.class.isAssignableFrom(clazz);
}
@凌驾
公共无效验证(对象目标、错误){
TypeA objTypeA=(TypeA)目标;
ValidationUtils.rejectIfEmpty(错误,“number”、“number.notEmpty”);
}
}
希望这有帮助。我使用的一个方便的助手类-
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{
公共静态void invokeNestedValidator(验证器验证器、TEntity实体、错误、字符串子路径){
试一试{
错误。pushNestedPath(子路径);
invokeValidator(验证器、实体、错误);
}最后{
错误。popNestedPath();
}
}
公共静态void invokeNestedValidatorForList(验证器验证器、列表实体、错误、字符串子路径根){
对于(int index=0;index
您可以在项目中的任何位置使用此选项
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++;
}
}
谢谢,杰罗姆。如果TypeA有自己的验证器,我如何在MyFormValidator中使用验证器?如果存在多个错误,我如何在表单页面上显示一条错误消息?如何使用ValidationHelper类?我建议使用此解决方案。我在一个项目中遇到了一个类似的问题。此解决方案允许您保持代码模块化,根据需要将验证拆分为多个不同的验证器。很高兴它有所帮助。我想发布这篇文章是因为它是模块化的,易于维护。你知道如何报告哪一行有错误吗?