Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

Refer to this thread for background and problem analysis.

Make sure you check pages.xml when your back button is not working.

Example:

<page view-id="/ManageEquipment.xhtml">
    	<description>Manage Equipment</description>
    	<navigation from-action="#{manageEquipment.processRepairHistorySelection}">
    		<redirect view-id="/RepairCaseDetails.xhtml"/>    		            
        </navigation>
        
        <navigation from-action="#{manageEquipment.searchSerialNumber}">
        	<redirect view-id="/ManageEquipment.xhtml"/>
        </navigation>
        
    </page>

The second <navigation> block above fixed my problem and now the cid is not being lost. When I click the browser back button, the previous page is displayed with all components/data intact. Previously it was being wiped out after the temporary conversation was destroyed. There was a LRC but b/c the cid was lost, a temporary conversation was instantiated (remember with Seam and HTTP requests, there is always a conversation, but it may be temporary or long-running).

With the above configuration in pages.xml, when user clicks the submit button to execute a search, the cid is post-pended to the URL on postback. Seam will no longer use a temporary conversation and thus the SFSB modeling the LRC will not be destroyed prematurely.

In Seam, if a business method of a Seam component returns void, there will be a postback after successful form submission and method execution. If you return a String, it will forward the request to foo.xhtml.

Summary: if you want to make sure Seam does not lose your conversation id, make sure you use <redirect> for the appropriate action in your pages.xml so that on postback, the URL contains the conversation id and you avoid problems with browser back button scenarios.

As per DAllen from SiA book, pg. 101:

The presence of the <redirect/> element in the rule indicates that a redirect should be issued prior to rendering the next view, rather than rendering the view immediately in the same request, which is the default. A redirect results in a new initial request.

As per KMann from JSFiA book, pg. 132:

The last navigation case specifies the <redirect> element, which tells JSF to send an HTTP redirect to send the user to the new view, as opposed to forwarding the user to the view internally. The <redirect> element also forces the request for the new view to be handled externally by the web container, which means it will be processed by any additional application logic you may have (like a servlet filter).
1 comment:
 
29. May 2009, 21:37 America/New_York | Link

I was having the same behavior and your article helped me figure out the problem I had.

Here is some more info for anyone who still has the problem.

An important thing to know is that the navigation rule from-action is matched with the string literal and not the method signature. Let me explain:

Let's say you have a page in which you have a search button and a paging component that is a facelet.

<h:inputText id="firstName" value="#{userList.user.firstName}" />
<a:commandButton id="find" value="Find" action="#{userPaginator.refresh}" reRender="users">
  <a:actionparam name="firstResult" assignTo="#{userPaginator.firstResult}" value="#{0}" />
</a:commandButton>

<rich:dataTable id="users" var="_user" value="#{userPaginator.pagedData}">
  ... columns ...
  <f:facet name="footer">
    <ui:include src="/layout/paging.xhtml">
      <ui:param name="paginator" value="#{userPaginator}" />
      <ui:param name="dataTable" value="users" />
    </ui:include>
  </f:facet>
</rich:dataTable>

In the code bloc above, note that userPaginator is passed as a param named paginator to the paging.xhtml facelet.

In that paging component, you have commandButtons that allow you to move to the previous, next and directly to page numbers a bit like the google search page.

Here is the link to move to the next page that is in the pagin.xhtml facelet.

<a:commandButton action="#{paginator.refresh}" value="next" reRender="#{dataTable}" >
  <a:actionparam name="firstResult" assignTo="#{paginator.firstResult}" value="#{paginator.nextFirstResult}" />
</a:commandButton>

The important thing to notice here is the action that is paginator.refresh instead of userPaginator.refresh. Because of that, I had to create a from-action navigation rule for each action.

In pages.xml so that other pages using the paging facelet benifit from it:

<page view-id="*">
  <navigation from-action="#{paginator.refresh}">
    <redirect />
  </navigation>
</page>

And in userList.page.xml:

<navigation from-action="#{userPaginator.refresh}">
  <redirect />
</navigation>

Hope that can help someone.

PS: I was impressed by your perseverance talking to yourself on that thread. Thank you very much for sharing your adventures, it shortened the time it took me to fix my problem. It is just a bit sad that you had practically no help.