Best Practice

This page contains information on how the Orchestra developers believe Orchestra is best used. As always, best practices evolve - see the wiki for the latest information.

Single Page Conversation With Flash Scope

Write a single managed bean for the view. Configure this bean as belonging to an unnamed "flash" conversation scope and reference it as normal from your presentation pages (jsp, facelets, clay, etc).

The conversation will be started when the bean is first accessed, and will automatically be terminated when navigation to some other page occurs (well, technically when a page is rendered that does not reference this managed bean). If you have an action method that wants to "start fresh" while remaining at the same view, then from the action method call ConversationUtils.invalidateAndRestartCurrent() to discard the current conversation.

If this bean is named to match the view that it is backing (eg beanname="edit" for the "/edit" viewid), then it is trivial to get "lifecycle events" from Orchestra's ViewController. See the ViewController documentation for more information on this.

Multi Page Conversation With Flash Scope

Use one flash-scoped controller for the whole conversation, plus one simple request-scoped bean per view. For example, if you have three pages then structure things as follows:

  • Page:purchaseStep1.jsp
  • Page:purchaseStep2.jsp

    Bean name: purchaseStep2
  • Page:purchaseStep3.jsp

    Bean name: purchaseStep3
  • Conversation bean name: purchaseController
The request-scoped beans are used only to check whether the conversation is really running; this avoids problems when users leap into the middle page of a sequence (eg via a bookmark). EL expressions in all of the pages reference the purchaseController object, not the request-scoped beans. We have to ensure that the user starts with the start page. Reasons why this might be violated are:
  • the conversation timed out in the mid of the work
  • the user tampered with the url
To ensure a running conversation, simply add a method called initView() to the purchaseStep2 and purchaseStep3 beans which looks like the following:
public void initView()
{
    ConversationUtils.ensureConversationRedirect("pagesController", "/startPage.faces");
}
					
As noted above, Orchestra's ViewController will invoke "lifecycle events" for a view onto any bean that has a "matching name". Because the request-scoped beans above have names that match the viewid, the initView method on the appropriate bean is called when a request for that view is received, and a check can be made for the existence of the right conversation. Without this check, when a user leaps into the middle of a conversation, EL expressions will trigger the creation of the missing purchaseController (and its associated conversation) but the bean probably does not have the appropriate state to render the page correctly. There is no need for a bean to back the first page (purchaseStep1) because it is perfectly valid for the user to enter that page with no existing conversation. Notice: There is also a JsfConversationUtils-class which allows you to invoke a navigation rule rather than encoding a url in the call to method ensureConversationRedirect. An alternative to declaring "dummy beans" just to receive lifecycle callbacks is to customise the way the ViewController maps viewids to beannames. In particular, see the ViewController annotations from the Orchestra core15 module.

Multi Page Conversation With Manual Scope

In some cases a conversation should not terminate until page N has been visited, but in the middle a user can go off and visit a page that has no references to any managed beans within the main conversation. When using Flash scopes, Orchestra will interpret a visit to such as page as the user "abandoning" the conversation, so the conversation will be discarded. In this case, use a manual scoped conversation, ie one that must be explicitly ended via either a JSF component (ox:endConversation) or a call to the Orchestra API from an action method. Use flash scopes where possible, though - they are less work.

Component bindings

We recommend you read about component binding and the scoping problem. This document is not specifically about Apache MyFaces Orchestra, but the same issues apply when dealing with component-bindings and conversation-scoped beans.