Redirecting to the same state of a web stream view causes an exception to nested composites

Consider a simple page with input text and some validation. The page is included in the Spring web stream as view state. If verification fails, the same display state must be repeated, including verification messages. It works great. Using a composite component that encapsulates input and message also works great.

However, using the same composite component inside another composite results in the following error:

FacesException: Cannot add the same component twice

This exception stems from the handleAddRemoveWithAutoPrune method, which adds components to the list of dynamic actions and throws an error if the component should be added a second time.

Here is an example of behavior reproduction:

JSF Page

 <h:form id="form"> <h:inputText id="text" value="#{bean.someValue}" > <f:validateLength maximum="3" /> </h:inputText> <h:message for="text" /> <!-- This will work --> <test:ccInner anything="Blubb" /> <!-- This will not work --> <test:ccOuter id="outer" title="Outer Component"> <test:ccInner id="inner" anything="Inner Component" /> </test:ccOuter> <h:commandButton id="button" type="submit" value="Submit" action="#{bean.doStuff}" /> </h:form> 

Components

Inner

 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:cc="http://java.sun.com/jsf/composite" xmlns:h="http://java.sun.com/jsf/html"> <cc:interface> <cc:attribute name="anything" /> </cc:interface> <cc:implementation> #{cc.attrs.anything} </cc:implementation> </html> 

Top

 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:cc="http://java.sun.com/jsf/composite" xmlns:h="http://java.sun.com/jsf/html"> <cc:interface> <cc:attribute name="title" /> </cc:interface> <cc:implementation> #{cc.attrs.title} <cc:insertChildren /> </cc:implementation> </html> 

(Lowering the bean and determining flow. Normal standard material)

I studied this for a while. Others, which have similar problems, usually encounter this when using composites inside iterative components (for example, dataTable), so the components will be dynamically added when creating a view and restoring a view. Then the problem arises with the postback in the same form, see, for example, this ticket here . There, the error was caused by a lack of source code for plugin encoding, however my components are simple and simple, no custom Java behind, so this does not help me ...

However, I found two approaches: as described in the Spring Webflows documentation , the web stream automatically redirects when it transitions to the same view state.

1) When disabling this behavior by adding

 <webflow:flow-executor id="flowExecutor"> <webflow:flow-execution-attributes> <webflow:redirect-in-same-state value="false"/> </webflow:flow-execution-attributes> </webflow:flow-executor> 

in webflow.xml problem disappears. However, as the text says, the initial redirect is the desired behavior to prevent sending and notifying as two forms in some browsers, such as chrome, when you press F5 or use back / forward.

2) As described in the text, Ajax requests will not cause redirects, so adding <f:ajax execute="@form" render="@form" /> to the submit button will also solve the problem. But do I really want to use Ajax to represent the full form? It seems to me pointless.

While this works, 1) has serious flaws and 2) makes things a little more complicated and may also not always be desirable. So, I would prefer to solve the original question (or understand it first, for that matter). Also, if this is a problem in the base implementation, it may be helpful to file a bug report (if it is not already).

Edit: Works on JBoss with Mojarra 2.1.21, JSF 2.1, Spring Webflow 2.3.2

+4
source share

Source: https://habr.com/ru/post/1500691/


All Articles