Spring MVCアプリケーションで、Spring Validator(アノテーションではない)を使用してフォーム内のネストされたオブジェクトのリストを検証する方法を知りたいです。
class MyForm() {
String myName;
List<TypeA> listObjects;
}
class TypeA() {
String number;
String value;
}
MyObjectValidatorを作成してlistObjectsを検証し、TypeAの数と値のエラーメッセージを追加するにはどうすればよいですか。
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 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 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++;
}
}