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