Spring validation errors tag not working completely with webflow + portlet
Asked Answered
R

1

1

I have a small project (using Spring 4.2.0, Spring Webflow 2.4.2, Hibernate validator 5.2.2) that is working as expected in the servlet world, but after having transformed it to a portlet, the validation feedback in JSP doesn't work fully as expected anymore.

For a form that looks like this:

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

This still works in the portlet (so I get at least the confirmation that my validation error has been triggered):

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

This correctly renders:

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

But this variant of the <form:error />, where the contents of the <form:error> tag should be rendered in case of errors, stopped working and is not rendered:

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

Some of the debug messages in the log:

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=''}]]]]]}]

I already tried to no avail:

  • container-runtime-option with javax.portlet.actionScopedRequestAttributes set to true
  • Wiring a AnnotationMethodHandlerAdapter with ConfigurableWebBindingInitializer using my LocalValidatorFactoryBean
  • Reproducing the same behaviour with the official sample project booking-portlet-mvc, which showed the same error. (I added a line <form:errors path="checkinDate">only shown on error</form:errors> to enterBookingDetails.jsp which does not render)

Any clues on differences between the servlet and portlet world that might cause this? Or any hints on where to look for in debugging this?

Romanticize answered 24/2, 2016 at 8:16 Comment(1)
Did you check with newer versions of Spring framework?Platt
R
0

For now I have a workaround that is functional (albeit slightly less elegant). I created a custom JSP tag like this:

<%@ 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>
Romanticize answered 24/2, 2016 at 13:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.