在Spring 3中验证错误后清除表单字段

时间:2013-05-30 13:23:58

标签: forms spring validation field clear

是否有(必须有?)清除Spring 3中有验证错误的表单字段的方法?我知道清除“命令”对象属性有效......但只有在没有错误的情况下才有效。当存在验证错误(FieldErrors或GlobalErrors)时,Spring会以某种方式重新填充字段。

2 个答案:

答案 0 :(得分:1)

所以我找到了问题的解决方案。它工作得非常好但是对于像清除字段这样简单的事情来说似乎有些过分。

也许javascript片段是一个更清洁的解决方案?

这里的咆哮足以解决问题: 当字段中没有错误时,清除“命令”对象(表单支持对象)中的表单字段。

当存在验证错误时,Spring会从BindingResult对象中获取值“rejectedValuse” 创建BindingResult的“代理”并在调用getFieldValue(String s)函数时返回“”。 做一个“你说的是什么”? ......代理人像这样:

public class BindingResultProxy implements BindingResult {
final private BindingResult proxied;
final private Set<String> fieldsToClearValueFor;

public BindingResultProxy(BindingResult proxied) {
    this.proxied = proxied;
    fieldsToClearValueFor = new TreeSet<String>();
}

public void clearFieldValueFor(String fieldname) {
    fieldsToClearValueFor.add(fieldname);
}

@Override
public Object getTarget() {
    return proxied.getTarget();
}

@Override
public Map<String, Object> getModel() {
    return proxied.getModel();
}

....它继续使用代理方式覆盖BindingResults中的所有方法,就像上面的方法一样 ..然后在getFieldValue()返回“”时由某种机制决定..(列表)你明白了吗? : - )

        @Override
        public Object getFieldValue(String s) {
            if (fieldsToClearValueFor.contains(s)) return "";
            return proxied.getFieldValue(s);
        }

然后在控制器中使用:

  if(result.hasErrors()){
        //If there are errors, clear the fields
        ArrayList<String> fieldsToClear = new ArrayList<String>(3);
        for(FieldError fieldError: result.getFieldErrors()) {
            fieldsToClear.add(fieldError.getField());
        }
        if(result.hasGlobalErrors()){
            //there is only one global error here in case the new password does not match the confirm password
            //so clear the confirmPassword as well
            fieldsToClear.add("confirmPassword");
        }

        clearFormFieldValues(result, model, fieldsToClear.toArray(new String[fieldsToClear.size()]));
return "/account/changePassword";

.....

 private void clearFormFieldValues(BindingResult result, Model model, String... fieldsToClear) {
        final BindingResultProxy configuredBindingResult = new BindingResultProxy(result);
        for (String fieldToClear : fieldsToClear) {
            configuredBindingResult.clearFieldValueFor(fieldToClear);
        }
               model.addAttribute("org.springframework.validation.BindingResult.changePasswordForm",
configuredBindingResult);
    }

确实很简单?!??!?

答案 1 :(得分:0)

更清洁的解决方案,七年后。由https://stackoverflow.com/a/61609112/4618338

提供
    if(result.hasErrors()) {
        BeanPropertyBindingResult result2 = new BeanPropertyBindingResult(watchedDirectory, theBindingResult.getObjectName());
        for(ObjectError error : result.getGlobalErrors()) {
            result2.addError(error);
        }
        for(FieldError error :result.getFieldErrors()) {
            Object rejectedValue = shouldBeCleared(error.getField()) ? null : error.getRejectedValue();
            result2.addError(new FieldError(error.getObjectName(), error.getField(), rejectedValue, error.isBindingFailure(), error.getCodes(), error.getArguments(), error.getDefaultMessage()));
        }

        model.addAllAttributes(result2.getModel());
        return "/account/changePassword";
    }
    // ... no errors; persist changes, return appropriate view

另一种方法是使200条以上的行成为代理类,并始终在controller方法中对其进行配置。