Using Form Beans to Encapsulate Data

The concepts behind page flows - separation of business logic and presentation, and centralized navigational control - reflect a design pattern that may be familiar to you: Model-View-Controller (MVC). The following diagram shows a typical sequence of events involving the various MVC components:

  1. The client browser issues an HTTP request to the web application.
  2. The Controller component receives the request. The Controller makes decisions on the processing that will occur next, based on its business rules. In the case of WebLogic Workshop page flows, the Controller is the page flow's JPF file. In the source code, simple tags that appear in Javadoc comments are used to annotate the purpose of the Controller's methods.
  3. The Model components interact with the persistent data resources, such as a relational database. In WebLogic Workshop, the Model components can for instance be implemented as controls.
  4. The Controller decides which View component should be used, based on the results of processing and the data returned by the Model components.
  5. The View component (the selected JSP file) renders the HTTP response, which the server displays to the client browser.

The separation of JSP (view) presentation code from navigation decisions and business logic is an important principle of page flows. Separating the presentation of data on a JSP page from the processing of the data by the controller allows for the encapsulation of the data itself and its handling. For example, to handle customer registration you can create a separate Java class - embedded in the controller or in a separate Java class or custom Java Control- that contains the customer's registration data, such as name, address, login name and password, as well as the business logic necessary to register a new custom, change an existing registration, or remove the customer account. Updates to the business logic can be made in one class instead of in multiple web pages throughout your web application.

Data binding is the process of associating the presentation of the data on a JSP page with the data itself. There are various data binding contexts in WebLogic Workshop, which are described in Using Data Binding Tags in Page Flows. A very common type of data binding is done using forms and form beans, which is described in the following example. The various presentation elements that can be used in the design of a JSP page, such as textboxes, radiobuttons and checkboxes, are discussed in Designing User Interfaces in JSPs.

A Page Flow Action that Uses Form Beans

A typical way of eliciting information from a user is through a form. The fields in the form can be empty when the form is first presented to the user, for instance when entering new information, or can be prepopulated, for example when a user modifies information that he/she entered on an earlier occasion. In either case a form bean is used to encapsulate the data.

A form bean class is typically defined as an inner class within a page flow class, and in most cases extend com.bea.wlw.netui.pageflow.FormData. When you define a new action method with a form bean in the page flow's Flow View, the relevant import statement is automatically included:

import com.bea.wlw.netui.pageflow.FormData;
import com.bea.wlw.netui.pageflow.Forward;
import com.bea.wlw.netui.pageflow.PageFlowController;
import javax.servlet.http.HttpServletRequest;
   

In the page flow, an action method is used to receive and process a form bean from one JSP to the next. In the controller's Flow View, an action method that uses a form bean displays a slightly different icon compared to an action method without a form bean argument:

Let's look at an example of a page flow that does simple navigation and uses a form bean. The page flow's purpose is to pass data between JSP pages that participate in this page flow. The example, named "dataFlowController", defines and uses a form bean named NameActionForm within the dataFlowController.jpf class. To run this example and examine the code, go to:

<WEBLOGIC_HOME>\samples\workshop\SamplesApp\WebApp\handlingData\dataFlow\

The complete Flow View for dataFlowController.jpf is given here. To demonstrate the use of form beans, we'll focus on the firstNameAction action method:

Let's switch to Action View to examine the local flow of the firstNameAction method. After clicking the Action View tab near the bottom of the window, the IDE initially displays all the actions defined in the page flow, and shows a message that "No action is currently selected." The following diagram shows a portion of the display, after firstNameAction has been selected:

The Local Flow indicates that the firstName.jsp file raises an action named firstNameAction. This action method is defined in the page flow controller file dataFlowController.jpf. When the firstNameAction action method runs, its Forward object returns a logical name of "success", and the result is that the lastName.jsp page is loaded.

Now click the Form Bean tab to examine the form bean used by this firstNameAction method:

The Form Bean details section shows that the firstNameAction method uses a form called NameActionForm, which contains two String variables, lastname and firstname. There are two icons to the right of the form bean name. When you click the left-most icon you can add and remove fields using the form bean editor, while clicking the other icon will take you to the source view of the form bean. Let's do the latter by clicking this icon:

This is the source code for NameActionForm form bean:

    public static class NameActionForm extends com.bea.wlw.netui.pageflow.FormData
    {
        private java.lang.String firstname;
        private java.lang.String lastname;
 
        public void setLastname(java.lang.String lastname)
        { this.lastname = lastname; }
 
        public java.lang.String getLastname()
        { return this.lastname; }
 
        public void setFirstname(java.lang.String firstname)
        { this.firstname = firstname; }
 
        public java.lang.String getFirstname()
        { return this.firstname; }
    }

Now let's turn to the source code of the firstNameAction method:

    /**
     * This method is passed the page-flow-scoped Form Bean pageFlowScopedBean.
     * 
     * If the annotation 
     * 
     *    jpf:action form="pageFlowScopedBean" 
     * 
     * were not present, this method would be passed a new instance of the Form Bean
     * and that instance would be request-scoped, not page-flow-scoped.
     * 
     * @jpf:action form="pageFlowScopedBean"
     * @jpf:forward name="success" path="lastName.jsp"
     */
    public Forward firstNameAction(NameActionForm form)
    {
        return new Forward( "success" );
    }

As shown conceptually on the Flow View and Action View drawings, when the firstNameAction action method runs, its Forward object returns a name of "success", matching the @jpf:forward annotation's logical name, and the result is that the lastName.jsp page is loaded next.

Note also that the firstNameAction method is passed a Page Flow-scoped Form Bean instance. Page Flow-scoped instances of Form Beans have a life-cycle that is as long as the Page Flow instance. Because they persist as long as the Page Flow instance, they are a good place to store data accumulated by the wizard.

Finally, the actual databinding between a form element and a field in the form bean is done using the reserved keyword actionForm on the form element. You can reference fields in the form bean using the 'dot' notation. You must always enclose the entire expression in curly braces, like is shown in this example taken from firstName.jsp:

<netui:form action="firstNameAction">
     ...
     <netui:textBox dataSource="{pageFlow.pageFlowScopedBean.firstname}" />
     ...
</netui:form>

The textbox for the first name that is part of the form is tied to the variable firstname in the form bean. Notice that when the form is submitted, the action method firstNameAction is called. Databinding is discussed in detail in Using Data Binding Tags in Page Flows. To learn how to check the information a user entered in a form, see Validating User Input.

Related Topics

Designing User Interfaces in JSPs

Presenting Complex Data Sets in JSPs

A Detailed Page Flow Example

Page Flow and JSP Sample Applications