我正在阅读Spring 4 API,并尝试了解FieldError,ObjectError与全局错误之间的区别,所有这些都在{{3 }}。我猜测全局错误是ObjectError
的另一个名称,因为BindingResult会返回ObjectError
。
上下文是我希望在一些表单验证之后简单地打印错误消息,并想知道如何避免检查instanceof,如getGlobalError()中所示。我可以使用FieldError
并忽略对象错误吗?如果我只记录FieldError
,我会失踪什么?
我尝试过几个场景,但还没看到这个区别。在此期间会查看一些来源。
答案 0 :(得分:1)
我猜测全局错误是ObjectErrors的另一个名称 因为getGlobalError()返回一个ObjectError。
实际上,“全局错误”是ObjectError
不是FieldError
的{{1}} getGlobalErrors()
ObjectError
的实例{/ 1}}
如果我只记录了FieldErrors,我会失踪什么?
该代码注册为“全局错误”的任何BindingResult.reject(errorCode, errorArgs, defaultMessage)
例如致电rejectValue(field, errorCode, errorArgs, defaultMessage)
。
另请参阅modelAttribute
的{{3}}。通常,错误是针对已验证/绑定对象的字段(例如,其属性与Spring表单标记的rejectValue
标记匹配的模型值)而不是对象本身而注册的。
以下是创建全局错误的几种方法:
假设它是根表单对象而不是通过source验证的嵌套对象,您可以通过传递null来添加“全局错误”(在指定的绑定根对象的上下文中)作为FieldError
的字段名称参数。但是,如果要验证的对象是嵌套对象,则会在嵌套对象字段中注册nestedPath
。因此,关于是否添加了常规Errors
或特定ObjectError
,目标FieldError
对象的public class OverflowErrorsTag extends HtmlEscapingAwareTag {
public static final String OVERFLOW_ERRORS_VARIABLE_NAME = "overflowErrors";
public static final String GLOBAL_ERRORS_VARIABLE_NAME = "globalErrors";
private String name;
/**
* Set the name of the bean that this tag should check.
*/
public void setName(String name) {
this.name = name;
}
/**
* Return the name of the bean that this tag checks.
*/
public String getName() {
return this.name;
}
@Override
protected final int doStartTagInternal() throws ServletException, JspException {
Errors errors = getRequestContext().getErrors(this.name, isHtmlEscape());
Set<FieldError> subsequentErrors = Sets.newTreeSet((fe1, fe2) -> fe1.getField().compareTo(fe2.getField()));
Set<ObjectError> globalErrors = new HashSet<>();
if (errors != null) {
Set<String> firstErrorFields = new HashSet<>();
for (FieldError fieldError : errors.getFieldErrors()) {
if (firstErrorFields.contains(fieldError.getField())) {
subsequentErrors.add(fieldError);
} else {
firstErrorFields.add(fieldError.getField());
}
}
for (ObjectError objectError : errors.getGlobalErrors()) {
globalErrors.add(objectError);
}
}
if (subsequentErrors.isEmpty() && globalErrors.isEmpty()) {
return SKIP_BODY;
} else {
this.pageContext.setAttribute(OVERFLOW_ERRORS_VARIABLE_NAME, subsequentErrors, PageContext.REQUEST_SCOPE);
this.pageContext.setAttribute(GLOBAL_ERRORS_VARIABLE_NAME, globalErrors, PageContext.REQUEST_SCOPE);
return EVAL_BODY_INCLUDE;
}
}
@Override
public int doEndTag() {
this.pageContext.removeAttribute(OVERFLOW_ERRORS_VARIABLE_NAME, PageContext.REQUEST_SCOPE);
this.pageContext.removeAttribute(GLOBAL_ERRORS_VARIABLE_NAME, PageContext.REQUEST_SCOPE);
return EVAL_PAGE;
}
}
(“嵌套对象图”)属性是多么重要。< / p>
通过在类级别应用的JSR 303约束注释。请参阅javadoc,其中检查模型对象是否存在于数据存储区中。
以下是引用全局与字段级别错误的示例:
<spring-ext:overflowErrors name="newModelObject">
<div class="row">
<div class="large-12 columns">
<div class="alert panel">
<c:if test="${overflowErrors.size()>0}">
<p>There are multiple errors with your entry.</p>
<c:forEach var="error" items="${overflowErrors}">
${fn:toUpperCase(fn:substring(error.field, 0, 1))}${fn:toLowerCase(
fn:substring(error.field, 1,fn:length(error.field)))}:
<b><spring:message message="${error}" /></b>
<br/>
</c:forEach>
</c:if>
<c:forEach var="error" items="${globalErrors}">
<b><spring:message message="${error}" /></b>
<br/>
</c:forEach>
</div>
</div>
</div>
</spring-ext:overflowErrors>
然后在视图中显示包含全局错误和字段错误的标记:
Q