3

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

4

2 回答 2

2

所以我找到了解决问题的方法。它工作得很好,但对于像清除字段这样简单的事情来说似乎有点矫枉过正。

也许 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() 中,当由某种机制决定时返回 "" .. (list) 你明白了吗?:-)

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

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

于 2013-05-31T07:22:35.763 回答
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 多行代理类并在控制器方法中配置它。

于 2020-05-06T15:50:40.463 回答