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
withjavax.portlet.actionScopedRequestAttributes
set totrue
- Wiring a
AnnotationMethodHandlerAdapter
withConfigurableWebBindingInitializer
using myLocalValidatorFactoryBean
- 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>
toenterBookingDetails.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?