Тег проверки правильности Spring не работает полностью с портлетом webflow +

У меня есть небольшой проект (использующий Spring 4.2.0, Spring Webflow 2.4.2, валидатор Hibernate 5.2.2), который работает как положено в мире сервлетов, но после преобразования его в портлет обратная связь проверки в JSP не ' больше не работает полностью, как ожидалось.

Для формы, которая выглядит следующим образом:

<form:form modelAttribute="person" action="${flowExecutionUrl}">
    <form:input path="voornaam"/>
    ....
</form:form>

Это все еще работает в портлете (поэтому я получаю по крайней мере подтверждение того, что моя ошибка проверки была вызвана):

  <form:errors path="*" />
  <form:errors path="voornaam" />

Это правильно делает:

<span id="person.errors">may not be empty</span>
<span id="voornaam.errors">may not be empty</span>

Но этот вариант <form:error />где содержимое <form:error> тег должен отображаться в случае ошибок, перестать работать и не отображается:

<form:errors path="*">
    <p>Should only show in case of any errors</p>
</form:errors>

Некоторые из сообщений отладки в журнале:

2016-02-23 15:18:36 DEBUG DefaultMessageContext:116 - Resolving message using [DefaultMessageResolver@3a13a7e3 source = 'voornaam', severity = ERROR, codes = array<String>['person.voornaam.NotBlank', 'voornaam.NotBlank', 'java.lang.String.NotBlank', 'NotBlank'], args = array<Object>[org.springframework.context.support.DefaultMessageSourceResolvable: codes [person.voornaam,voornaam]; arguments []; default message [voornaam]], defaultText = 'may not be empty']
2016-02-23 15:18:37 DEBUG SessionBindingConversationManager:86 - Putting conversation attribute 'scope' with value map['flashScope' -> map['viewUserEventState' -> [ViewActionStateHolder@6c38a8f7 eventId = 'save', mappingResults = Mapping Results = [[TargetAccessError@1c127930 mapping = parameter:'execution' -> execution, code = 'propertyNotFound', error = true, errorCause = org.springframework.binding.expression.PropertyNotFoundException: Property not found, originalValue = 'e1s2', mappedValue = [null]], [Success@67b8b31e mapping = parameter:'achternaam' -> achternaam, code = 'success', error = false, originalValue = 'Prefab achternaam', mappedValue = 'Prefab achternaam'], [Success@6083383d mapping = parameter:'tussenvoegsel' -> tussenvoegsel, code = 'success', error = false, originalValue = '', mappedValue = ''], [Success@5fc92799 mapping = parameter:'voornaam' -> voornaam, code = 'success', error = false, originalValue = '', mappedValue = '']]], 'messagesMemento' -> map[[null] -> list[[empty]], 'voornaam' -> list[[Message@5a930a7c source = 'voornaam', severity = ERROR, text = 'may not be empty']]]]]
2016-02-23 15:18:37 DEBUG AbstractMvcView:194 - Rendering MVC [org.springframework.web.servlet.view.JstlView: unnamed; URL [/WEB-INF/flows/editPersonDetails.jsp]] with model map [{viewUserEventState=[ViewActionStateHolder@6c38a8f7 eventId = 'save', mappingResults = Mapping Results = [[TargetAccessError@1c127930 mapping = parameter:'execution' -> execution, code = 'propertyNotFound', error = true, errorCause = org.springframework.binding.expression.PropertyNotFoundException: Property not found, originalValue = 'e1s2', mappedValue = [null]], [Success@67b8b31e mapping = parameter:'achternaam' -> achternaam, code = 'success', error = false, originalValue = 'Prefab achternaam', mappedValue = 'Prefab achternaam'], [Success@6083383d mapping = parameter:'tussenvoegsel' -> tussenvoegsel, code = 'success', error = false, originalValue = '', mappedValue = ''], [Success@5fc92799 mapping = parameter:'voornaam' -> voornaam, code = 'success', error = false, originalValue = '', mappedValue = '']]], org.springframework.validation.BindingResult.person=org.springframework.webflow.mvc.view.BindingModel: 1 errors
Field error in object 'person' on field 'voornaam': rejected value [null]; codes []; arguments []; default message [may not be empty], masterData={tussenvoegsel=[, de...]}, currentUser=10201, viewScope=map[[empty]], flowExecutionKey=e1s2, flowExecutionUrl=http://localhost:8080/web/guest/person-details?p_auth=Cknp0vsP&p_p_id=webflowportlet_WAR_webflowpoc10SNAPSHOT&p_p_lifecycle=1&p_p_state=normal&p_p_mode=view&p_p_col_id=column-1&p_p_col_count=1&_webflowportlet_WAR_webflowpoc10SNAPSHOT_execution=e1s2, person=Person{voornaam='', achternaam='Prefab achternaam', tussenvoegsel=''}, flashScope=map['viewUserEventState' -> [ViewActionStateHolder@6c38a8f7 eventId = 'save', mappingResults = Mapping Results = [[TargetAccessError@1c127930 mapping = parameter:'execution' -> execution, code = 'propertyNotFound', error = true, errorCause = org.springframework.binding.expression.PropertyNotFoundException: Property not found, originalValue = 'e1s2', mappedValue = [null]], [Success@67b8b31e mapping = parameter:'achternaam' -> achternaam, code = 'success', error = false, originalValue = 'Prefab achternaam', mappedValue = 'Prefab achternaam'], [Success@6083383d mapping = parameter:'tussenvoegsel' -> tussenvoegsel, code = 'success', error = false, originalValue = '', mappedValue = ''], [Success@5fc92799 mapping = parameter:'voornaam' -> voornaam, code = 'success', error = false, originalValue = '', mappedValue = '']]]], flowRequestContext=[RequestControlContextImpl@77af2f59 externalContext = org.springframework.webflow.context.portlet.PortletExternalContext@603391cf, currentEvent = [null], requestScope = map[[empty]], attributes = map[[empty]], messageContext = [DefaultMessageContext@5ef95b61 sourceMessages = map[[null] -> list[[empty]], 'voornaam' -> list[[Message@5a930a7c source = 'voornaam', severity = ERROR, text = 'may not be empty']]]], flowExecution = [FlowExecutionImpl@bee658a flow = 'personDetails', flowSessions = list[[FlowSessionImpl@3ac3099f flow = 'personDetails', state = 'editPersonDetails', scope = map['masterData' -> map['tussenvoegsel' -> list['', 'de', 'den', 'ten', 'ter', 'uit', 'van', 'van de', 'van den', 'van der']], 'viewScope' -> map[[empty]], 'person' -> Person{voornaam='', achternaam='Prefab achternaam', tussenvoegsel=''}]]]]]}]

Я уже пытался безрезультатно

  • container-runtime-option с javax.portlet.actionScopedRequestAttributes установлен в true
  • Проводка AnnotationMethodHandlerAdapter с ConfigurableWebBindingInitializer используя мой LocalValidatorFactoryBean
  • Воспроизведение того же поведения с официальным примером проекта booking-portlet-mvc, который показал ту же ошибку. (Я добавил строку <form:errors path="checkinDate">only shown on error</form:errors> в enterBookingDetails.jsp который не рендерит)

Есть ли какие-то подсказки о различиях между сервлетами и миром портлетов, которые могут вызвать это? Или какие-либо подсказки о том, где искать это при отладке?

1 ответ

На данный момент у меня есть обходной путь, который является функциональным (хотя и немного менее элегантным). Я создал собственный тег JSP следующим образом:

<%@ attribute name="path" required="true" type="java.lang.String" description="The path, or a wildcard '*'" %>
<spring:bind path="${path}">
    <c:if test="${status.errors.errorCount > 0}">
        <jsp:doBody />
    </c:if>
</spring:bind>
Другие вопросы по тегам