无法从获得任何输出标签库

发布于 2024-10-21 08:31:59 字数 3576 浏览 2 评论 0原文

我正在编写一个基于 Spring 3 MVC 的 Web 应用程序,使用 JSP 作为我的视图层。我在尝试报告 JSP 中特定 Model 对象的 BindingResult 错误的特定区域中遇到了困难。这可能最好用适当的代码来解释:

这是我的 Spring 控制器方法:

@RequestMapping(value = "/**", method = RequestMethod.GET)
public ModelAndView get(@ModelAttribute("xApiRequest") @Valid final XAPIRequest xApiRequest,
                       final BindingResult xapiBindingResult,
                       final HttpServletResponse response,
                       Model model) throws EntityNotFoundException {
  String viewName = "/WEB-INF/views/get-single-entity.jsp";
  /* 
   * Create a MAV passing in the original Model object which contains:
   * 1: The 'xApiRequest' @ModelAttribute object.
   * 2: The BindingResult for the 'xApiRequest' object.
   */
  final ModelAndView mav = new ModelAndView(viewName, model.asMap());
  final XAPIResponse<Resource> xApiResponse = buildXAPIResponse(false, 200, xApiRequest, null);
  response.setStatus(200);
  mav.addObject("xApiResponse", xApiResponse);
  return mav;
}

当我执行此方法时,我可以看到以下内容:

  • xApiRequest 对象是从 HttpServletRequest 正确创建的(我有一个单独的方法可以执行此操作)
  • JSR-由 @Valid 注释引起的 303 验证已经发生,并识别出 2 个验证错误,正如我所期望的那样,这些错误表示为 BindingResult 对象。
  • BindingResult 对象存在于 Model 方法参数中。
  • xApiRequest 和 BindingResult 对象已成功从 Model 方法参数传输到从该方法返回的 ModelAndView 对象。

我可以确认 BindingResult 的内容确实正确地将 xApiRequest 对象识别为验证错误的来源:

{xApiRequest=com.stretchr.xapi.entity.request.XAPIRequest@1e28608, org.springframework.validation.BindingResult.xApiRequest=org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'xApiRequest' on field 'userId': rejected value [null]; codes [NotEmpty.xApiRequest.userId,NotEmpty.userId,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [xApiRequest.userId,userId]; arguments []; default message [userId]]; default message [may not be empty]
Field error in object 'xApiRequest' on field 'projectId': rejected value [null]; codes [NotEmpty.xApiRequest.projectId,NotEmpty.projectId,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [xApiRequest.projectId,projectId]; arguments []; default message [projectId]]; default message [may not be empty]}

JSP 看起来像这样:

<%@ page contentType="application/json; charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="json" uri="http://www.atg.com/taglibs/json" %>
<%@ page session="false" %>
<spring:hasBindErrors name="xApiRequest">
</spring:hasBindErrors>
<c:if test="${errors}">
  <json:object name="exceptions">
    <json:property name="exceptionCount" value="${errors.errorCount}" />
    <json:property name="globalExceptionCount" value="${errors.globalErrorCount}" />
    <c:forEach var="error" items="${errors.allErrors}" varStatus="index">
      <json:property name="${index}" value="${error.defaultMessage}" />
    </c:forEach>
  </json:object>
</c:if>

无论我做什么,我都看不到进行调用以识别 xApiRequest 模型对象存在绑定错误,因此 JSP 输出不包含包含错误详细信息的 例外 对象:

{
  w: false
  s: 200
  c: ""
  r: {
    o ~path: ""
  }
}

任何人都可以看到什么我这里做错了吗?如果失败的话,有什么方法可以调试 JSP 处理过程中发生的情况吗?我热衷于调试 Spring taglib,但不太确定如何在 taglib 和相关代码位之间建立链接。

希望我在这里提供了足够的信息,但如果需要更多信息,请随时询问。

非常感谢,

艾德

I'm writing a Spring 3 MVC based web app, using JSPs for my view layer. I'm struggling on a particular area where I'm trying to report BindingResult errors for a particular Model object in a JSP. This is probably best explained with the appropriate code:

This is my Spring Controller method:

@RequestMapping(value = "/**", method = RequestMethod.GET)
public ModelAndView get(@ModelAttribute("xApiRequest") @Valid final XAPIRequest xApiRequest,
                       final BindingResult xapiBindingResult,
                       final HttpServletResponse response,
                       Model model) throws EntityNotFoundException {
  String viewName = "/WEB-INF/views/get-single-entity.jsp";
  /* 
   * Create a MAV passing in the original Model object which contains:
   * 1: The 'xApiRequest' @ModelAttribute object.
   * 2: The BindingResult for the 'xApiRequest' object.
   */
  final ModelAndView mav = new ModelAndView(viewName, model.asMap());
  final XAPIResponse<Resource> xApiResponse = buildXAPIResponse(false, 200, xApiRequest, null);
  response.setStatus(200);
  mav.addObject("xApiResponse", xApiResponse);
  return mav;
}

When I execute this method I can see the following:

  • The xApiRequest object is created correctly from the HttpServletRequest (I have a separate method which does this)
  • The JSR-303 validation, caused by the @Valid annotation, has taken place and has identified 2 validation errors, these are represented as BindingResult objects as I would expect.
  • The BindingResult objects are present in the Model method parameter.
  • The xApiRequest and BindingResult objects are successfully transferred from the Model method parameter in to the ModelAndView object which is returned from the method.

And I can confirm that the content of the BindingResult does appear to correctly identify the xApiRequest object as the source of the validation errors:

{xApiRequest=com.stretchr.xapi.entity.request.XAPIRequest@1e28608, org.springframework.validation.BindingResult.xApiRequest=org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'xApiRequest' on field 'userId': rejected value [null]; codes [NotEmpty.xApiRequest.userId,NotEmpty.userId,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [xApiRequest.userId,userId]; arguments []; default message [userId]]; default message [may not be empty]
Field error in object 'xApiRequest' on field 'projectId': rejected value [null]; codes [NotEmpty.xApiRequest.projectId,NotEmpty.projectId,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [xApiRequest.projectId,projectId]; arguments []; default message [projectId]]; default message [may not be empty]}

And the JSP looks like this:

<%@ page contentType="application/json; charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="json" uri="http://www.atg.com/taglibs/json" %>
<%@ page session="false" %>
<spring:hasBindErrors name="xApiRequest">
</spring:hasBindErrors>
<c:if test="${errors}">
  <json:object name="exceptions">
    <json:property name="exceptionCount" value="${errors.errorCount}" />
    <json:property name="globalExceptionCount" value="${errors.globalErrorCount}" />
    <c:forEach var="error" items="${errors.allErrors}" varStatus="index">
      <json:property name="${index}" value="${error.defaultMessage}" />
    </c:forEach>
  </json:object>
</c:if>

No matter what I do I can't seem to get the call to to recognise that the xApiRequest model object has binding errors, hence the JSP output does not contain the exceptions object containing details of the errors:

{
  w: false
  s: 200
  c: ""
  r: {
    o ~path: ""
  }
}

Can anyone see what I'm doing wrong here? Failing that is there any way I can debug what's going on during the JSP processing? I'm keen to debug the Spring taglib but am not quite sure how to make the link between the taglib and the associated bit of code.

Hope I've provided enough information here but if any more is required then don't hesitate to ask.

Many thanks,

Edd

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小清晰的声音 2024-10-28 08:31:59

errors 变量仅在 标记内公开,因此您应该执行类似的操作(请注意,它也替换 ):

<spring:hasBindErrors name="xApiRequest">
<json:object name="exceptions">
    <json:property name="exceptionCount" value="${errors.errorCount}" />
    <json:property name="globalExceptionCount" value="${errors.globalErrorCount}" />
    <c:forEach var="error" items="${errors.allErrors}" varStatus="index">
      <json:property name="${index}" value="${error.defaultMessage}" />
    </c:forEach>
  </json:object>
</spring:hasBindErrors>

The errors variable is exposed only inside the <spring:hasBindErrors> tags, so that you should do something like this (note that it also replaces <c:if>):

<spring:hasBindErrors name="xApiRequest">
<json:object name="exceptions">
    <json:property name="exceptionCount" value="${errors.errorCount}" />
    <json:property name="globalExceptionCount" value="${errors.globalErrorCount}" />
    <c:forEach var="error" items="${errors.allErrors}" varStatus="index">
      <json:property name="${index}" value="${error.defaultMessage}" />
    </c:forEach>
  </json:object>
</spring:hasBindErrors>
十雾 2024-10-28 08:31:59

多么尴尬啊,在尝试调试 BindErrorsTag 类之后,我意识到它根本没有被调用。这个发现让我意识到我没有在 JSP 中包含 Spring taglib 名称空间声明,包括这个解决了问题。

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

诅咒自己错过了这个现在非常明显的错误,并且有点困惑为什么 JSP(和我的 IDE)没有抱怨缺少 taglib 声明。我认为缺少 taglib 声明通常会在执行标签时导致 RuntimeException,但似乎事实并非如此(我希望它是这样,因为它可以节省我几个小时的调试时间!)

无论如何,问题解决了。

@axtavt - 感谢您的帮助!

How embarassing, after trying to debug the BindErrorsTag class I realised it wasn't being invoked at all. This discovery led me to realise that I hadn't included Spring taglib namespace declaration in the JSP, including this solved the problem.

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

Cursing myself for missing this now very obvious error and somewhat confused as to why the JSP (and my IDE) didn't complain about the missing taglib declaration. I thought a missing taglib declaration usually caused a RuntimeException upon execution of the tag but it seems this is not so (I wish it was as it would have saved me a good couple of hours of debugging!)

Anyway, problem solved.

@axtavt - Thanks for the help!

我不咬妳我踢妳 2024-10-28 08:31:59

我的天啊!我也遇到了同样的问题,非常感谢您回答自己的问题。

就我而言 - 希望可以帮助其他人 - 一个简单的 JSP,调用一个方法,例如:

@RequestMapping(method = RequestMethod.GET)
protected Object loadRegistrationForm(HttpSession session, Model model) {

返回的这个 JSP 有一个可以提交并获取服务器 POST 方法的表单,因此我有以下内容来捕获从返回的错误表单的帖子:

<spring:hasBindErrors name="customerAccountFormObj">    

<div class="alert alert-block pull-right alertmessage alert-warning alert-dismissible" role="alert" id="errorMsgHdr">
                    <button type='button' class='close' data-dismiss='alert' aria-label='Close'><span aria-hidden='true'>×</span></button>

                <form:errors path="*" cssClass="errorList" element="div"/>
</div>

</spring:hasBindErrors>

基本上,当存在绑定错误时,引导程序警报消息会显示错误,猜猜 GET 调用会发生什么?我收到一个空的警报框……经过 12 个小时的苦思冥想,我偶然发现了你的问题,瞧

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

!一切都很干净,没有空警报框,即 GET 调用没有错误。这一定是 JSP/Spring 中的一个错误。如果它对任何人有帮助的话,我使用 Spring mvc 3.0.3.RELEASE 。

Oh my God! I had the same problem, thanks so much for answering your own question.

In my case - hopefully helps someone else out there - A simple JSP, calls a method such as :

@RequestMapping(method = RequestMethod.GET)
protected Object loadRegistrationForm(HttpSession session, Model model) {

This JSP returned has a form which can be submitted and gets to a Server POST method, so I had the following to capture the errors returned from the post of the form:

<spring:hasBindErrors name="customerAccountFormObj">    

<div class="alert alert-block pull-right alertmessage alert-warning alert-dismissible" role="alert" id="errorMsgHdr">
                    <button type='button' class='close' data-dismiss='alert' aria-label='Close'><span aria-hidden='true'>×</span></button>

                <form:errors path="*" cssClass="errorList" element="div"/>
</div>

</spring:hasBindErrors>

Basically a bootstrap alert message displays the errors when there are binderrors, guess what happens on GET call ? I get an empty alert box... after 12 hours of banging my head, I stumbled on your question, added

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

Voila! everything's clean, no empty alert box, i.e., no errors on GET call. This has to be a bug in JSP/Spring. I use Spring mvc 3.0.3.RELEASE if it helps anyone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文