Integrating JavaServer Faces with Beehive Page Flow
Pages: 1, 2, 3

Sending data from a JSF page to a Page Flow

You can also send data along with an action that is raised on the Page Flow. Many actions will require a form bean as input; in general, a form bean is used to get data from a page to the controller. First, let's set up an action that accepts a form bean and then forwards to a page:

@Jpf.Action(

   forwards={

       @Jpf.Forward(name="success", path="page3.faces")

   }

)

public Forward goPage3(NameBean nameBean)

{

    _userName = nameBean.getFirstName() + ' ' + 

                nameBean.getLastName();

    return new Forward("success");

}

This action takes a NameBean, which is a form bean class that has getters/setters for firstName and lastName properties. It sets a member variable to the full name, and then forwards to page3.faces. As you know, you can raise an action either directly from a JSF page or from its backing bean. In both cases, you can send a form bean to the action. Let's look at each case in turn.

From a backing bean

To send a form bean from a command handler in the backing bean, you use a special annotation. Here is what it looks like in page2.java:

private ExampleController.NameBean _nameBean;



protected void onCreate()

{

    _nameBean = new ExampleController.NameBean();

}



public ExampleController.NameBean getName()

{

    return _nameBean;

}



@Jpf.CommandHandler(

    raiseActions={

        @Jpf.RaiseAction(action="goPage3", 

             outputFormBean="_nameBean")

    }

)

public String chooseNextPage()

{

    return "goPage3";

}

In this example, the JSF page can fill in the value for _nameBean in any way it chooses (for example, by binding h:inputText values to #{backing.name.firstName} and #{backing.name.lastName}). Then, it uses the outputFormBean attribute on @Jpf.RaiseAction to signal that _nameBean should be passed to action goPage3.

From a JSF page

Sending a form bean directly from the JSF page is simple, as long as you can get the bean value through a data binding expression. It is done by adding a special h:attribute component named submitFormBean inside the commandButton component:

<h:commandButton action="#{backing.chooseNextPage}" 

                 value="Submit directly from page">

    <f:attribute name="submitFormBean" value="backing.name" />

</h:commandButton>

Here, the button binds to the backing bean's "name" property ( getName) for the form bean to send to action goPage3.

Summary

This article has shown how to pair the richness of JSF for building pages with the power of Beehive Page Flow for controlling navigation between pages. While integrating the two is easy, it has a profound impact on your application: It separates your JSF pages from application-level logic, and brings the pages into the world of features that Page Flow provides. A JSF page gains a clear mission: participate in the flow of an application as a single (if highly capable) view element. What I haven't shown here is a fully fleshed out application, with event handling in JSF pages and complicated navigational logic in the controller. But the more complex an application gets, the more it demands the separation of responsibilities and advanced flow features that Page Flow adds to JSF. Spend a few minutes trying it out—it doesn't take long to start realizing the benefits.

References

Rich Feit is an Apache Beehive committer. He has spent the last four years writing and contributing to web application frameworks.