FieldError vs ObjectError与全局错误

时间:2016-06-13 04:01:17

标签: spring

我正在阅读Spring 4 API,并尝试了解FieldErrorObjectError与全局错误之间的区别,所有这些都在{{3 }}。我猜测全局错误是ObjectError的另一个名称,因为BindingResult会返回ObjectError

上下文是我希望在一些表单验证之后简单地打印错误消息,并想知道如何避免检查instanceof,如getGlobalError()中所示。我可以使用FieldError并忽略对象错误吗?如果我只记录FieldError,我会失踪什么?

我尝试过几个场景,但还没看到这个区别。在此期间会查看一些来源。

1 个答案:

答案 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标记匹配的模型值)而不是对象本身而注册的。

以下是创建全局错误的几种方法:

  1. 假设它是根表单对象而不是通过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>

  2. 通过在类级别应用的JSR 303约束注释。请参阅javadoc,其中检查模型对象是否存在于数据存储区中。

  3. 以下是引用全局与字段级别错误的示例:

    <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