Не удается получить какие-либо выходные данные из taglib ‹spring:hasBindErrors›

Я пишу веб-приложение на основе Spring 3 MVC, используя JSP для моего уровня представления. Я борюсь с определенной областью, где пытаюсь сообщить об ошибках BindingResult для определенного объекта модели в JSP. Это, вероятно, лучше всего объясняется соответствующим кодом:

Это мой метод контроллера 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-303, вызванная аннотацией @Valid, имела место и выявила 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 не содержит объект exceptions содержащий подробную информацию об ошибках:

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

Может ли кто-нибудь увидеть, что я делаю неправильно здесь? В противном случае я могу отладить то, что происходит во время обработки JSP? Я очень хочу отладить taglib Spring, но не совсем уверен, как сделать связь между taglib и соответствующим фрагментом кода.

Надеюсь, что я предоставил достаточно информации здесь, но если требуется что-то еще, не стесняйтесь спрашивать.

Большое спасибо,

Эдд


person Edd Grant    schedule 10.03.2011    source источник


Ответы (3)


Переменная errors отображается только внутри тегов <spring:hasBindErrors>, поэтому вы должны сделать что-то вроде этого (обратите внимание, что она также заменяет <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>
person axtavt    schedule 10.03.2011
comment
Спасибо. На самом деле я уже пробовал это. Когда я это делаю, JSP отображает объекты JSON (как бы говоря, что были BindErrors присутствуют, но вызовы ${errors.errorCount} и т. д. ничего не дают, как если бы не было ошибки) данные присутствуют Любые дальнейшие идеи? - person Edd Grant; 10.03.2011
comment
К сожалению, он делает то же самое. С тех пор я определил класс тега org.springframework.web.servlet.tags.BindErrorsTag, поэтому я собираюсь посмотреть, смогу ли я отладить то, что происходит. - person Edd Grant; 10.03.2011

Как неловко, после попытки отладки класса BindErrorsTag я понял, что он вообще не вызывается. Это открытие привело меня к выводу, что я не включил объявление пространства имен Spring taglib в JSP, в том числе это решило проблему.

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

Проклинаю себя за то, что пропустил эту теперь очень очевидную ошибку, и несколько сбит с толку тем, почему JSP (и моя IDE) не жаловались на отсутствующее объявление taglib. Я думал, что отсутствующее объявление taglib обычно вызывает исключение RuntimeException при выполнении тега, но, похоже, это не так (хотелось бы, чтобы это сэкономило мне добрую пару часов отладки!)

В любом случае, проблема решена.

@axtavt - Спасибо за помощь!

person Edd Grant    schedule 12.03.2011

О Боже! У меня была такая же проблема, большое спасибо за ответ на ваш вопрос.

В моем случае - надеюсь, поможет кому-то еще - простой 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'>&times;</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, если это кому-то поможет.

person AlpharettaTechy    schedule 06.11.2015