[英]Spring MVC and JSR 303 - Manual Validation
我正在使用Spring MVC 3和JSR 303.我有一個表單支持對象,其中包含不同類型的bean。 根據請求參數值,我必須選擇一個bean來驗證和保存。 我無法使用@Valid
進行驗證,因為要運行時才知道要驗證的bean。
我能夠向控制器注入一個javax.validation.Validator
,但我不知道如何用它來驗證bean並在“Spring方式” BindingResult/Error
任何錯誤存儲在BindingResult/Error
中。
由於請求映射,我需要在處理程序方法而不是initBinder
方法中執行此操作。
[編輯]
我在validate(Object, Errors)
遇到的問題是它無法識別嵌套bean。 要驗證的bean是通過foo.getBar()。getBean()訪問的,其中foo是表單后備對象。 當我validate(foo.getBar().getBean(), errors)
,我收到以下錯誤消息。
JSR-303 validated property 'property-name' does not have a corresponding accessor for Spring data binding
以前有人做過這樣的事嗎? 謝謝。
是的,你正在尋找的魔法類是org.springframework.validation.beanvalidation.SpringValidatorAdapter
該類獲取一個注入其中的javax.validation.Validator,並包含代碼,顧名思義,將輸出“調整”回熟悉的Errors
對象。 當你將@Valid
放在方法參數上時,它就是在內部用來進行處理的。
您可以通過在調度程序servlet中添加顯式LocalValidatorFactoryBean
來直接獲取它們。 只需注入一個實例作為標准Spring Validator接口的實例,並像使用任何'pre jsr-303'彈簧驗證提供程序一樣使用它。
只是一個猜測,但你有沒有嘗試過
errors.pushNestedPath("bar.bean"); // Path to the nested bean
validate(foo.getBar().getBean(), errors)
errors.popNestedPath();
這就是BindingResult
通常用於驗證嵌套bean的方式。
我看到這樣做的方式是使用標准的JSR-303驗證器(無論你注入的是什么)來獲取違規(即Set<ConstraintViolaion<T>>
)
然后使用類似於LocalValidatorFactoryBean內部的代碼來轉換這些違規和Spring錯誤:
public static <T> void convert(Errors errors, Collection<ConstraintViolation<T>> violations) {
for (ConstraintViolation<?> violation : violations) {
String field = violation.getPropertyPath().toString();
FieldError fieldError = errors.getFieldError(field);
if (fieldError == null || !fieldError.isBindingFailure()) {
errors.rejectValue(field, violation.getConstraintDescriptor().getAnnotation().annotationType()
.getSimpleName(), getArgumentsForConstraint(errors.getObjectName(), field, violation
.getConstraintDescriptor()), violation.getMessage());
}
}
}
private static Object[] getArgumentsForConstraint(String objectName, String field,
ConstraintDescriptor<?> descriptor) {
List<Object> arguments = new LinkedList<Object>();
String[] codes = new String[] { objectName + Errors.NESTED_PATH_SEPARATOR + field, field };
arguments.add(new DefaultMessageSourceResolvable(codes, field));
arguments.addAll(descriptor.getAttributes().values());
return arguments.toArray(new Object[arguments.size()]);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.