【发布时间】:2013-05-26 02:28:36
【问题描述】:
是否有(必须有?)一种方法来清除 Spring 3 中存在验证错误的表单字段?我知道清除“命令”对象属性是有效的……但前提是没有错误。当出现验证错误(FieldErrors 或 GlobalErrors)时,Spring 会以某种方式重新填充字段。
【问题讨论】:
标签: spring forms validation field
是否有(必须有?)一种方法来清除 Spring 3 中存在验证错误的表单字段?我知道清除“命令”对象属性是有效的……但前提是没有错误。当出现验证错误(FieldErrors 或 GlobalErrors)时,Spring 会以某种方式重新填充字段。
【问题讨论】:
标签: spring forms validation field
所以我找到了解决问题的方法。它工作得很好,但对于像清除字段这样简单的事情来说似乎有点矫枉过正。
也许 javascript sn-p 是更清洁的解决方案?
这里的咆哮已经足够了,解决方案是: 当字段没有错误时,清除“命令”对象(表单支持对象)中的表单字段。
当出现验证错误时,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);
}
确实很简单?!??!?
【讨论】:
七年后更清洁的解决方案。感谢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 多行代理类并在控制器方法中配置它。
【讨论】: