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

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

问题描述:

是否存在(必须有?)清除Spring 3中存在验证错误的表单字段的方法?我知道清除命令"对象属性是可行的……但前提是没有错误.出现验证错误(FieldErrors或GlobalErrors)时,Spring会以某种方式重新填充字段.

Is there (there must be?) a way to clear a form field that has validation errors in Spring 3? I know that clearing the "command" object properties works ... but only if there are no errors. Somehow the fields gets repopulated by Spring when there are validation errors (FieldErrors or GlobalErrors).

所以我找到了解决该问题的方法.它工作得很好,但是对于像清除字段这样的简单操作来说似乎有些过头了.

So I have found a solution to the problem. It works very well but It seems a bit overkill for something as simple as clearing a field.

也许javascript代码段是一种更干净的解决方案?

Maybe a javascript snippet is a cleaner solution?

这里的解决方案足够好了: 如果字段中没有错误,请清除命令"对象(表单支持对象)中的表单字段.

Well enough with the ranting here is the solution: Clear the form field in the "command" object (the form backing object) when there are no error in the field.

当存在验证错误时,Spring从BindingResult对象中获取值"rejectedValuse",因此 使BindingResult成为代理",并在调用getFieldValue(String s)函数时返回". 做一个你说什么"? ...代理人像这样:

When there is validation errors Spring picks up the values "rejectedValuse" from the BindingResult object so make a "proxy" of the BindingResult and return "" when the getFieldValue(String s) function is called.. Make a "what did you say"? ... a proxy. Like this:

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();
}

....然后像上面的方法一样使用Proxy重写BindingResults中的所有方法 ..然后在某种机制决定时,在getFieldValue()中返回".(列表)您明白了吗? :-)

.... And it goes on to override all the methods in BindingResults using proxied like the above method .. then in getFieldValue() return "" when decided by some mechanism.. (list) you get the point? :-)

        @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);
    }

真的很简单吗?!??!?

Very simple indeed?!??!?