Go with the flow

Build Web applications with Webflow components

Webflow is the core of the BEA WebLogic Portal framework. BEA WebLogic Portal encompasses many components including user management, commerce, entitlements, and campaigns. Web applications built with BEA WebLogic Portal can leverage the Webflow system to help separate the presentation logic and the underlying business processes.

The Model-View-Controller 2 (MVC2) pattern is the foundation of Webflow's architecture. Webflow functions mostly as a controller, but it also provides basic model support and includes tag libraries for the view. Unlike most other controller systems, Webflow is more like a workflow system. It provides the ability to chain multiple business logic classes together and supports branching. It builds on the event and handler concept of other controller systems, like Struts, but provides more functionality through chaining and branching based on events.

Web applications can leverage Webflow's functionality to set up event, logic, and site flows. Webflow's "flow" begins at a presentation node (JavaServer Pages (JSP)) and continues through zero or more classes (event handlers called InputProcessors) until another presentation node is encountered. This design makes Webflow a powerful tool for building Web applications.

Webflow's key features include:

  • Component-based structure encourages code reuse; frontend, middle-tier, and backend components are all addressed
  • Java 2 Platform, Enterprise Edition (J2EE) compliance
  • Built-in form validation
  • Inherent separation between responsibilities of frontend and backend developers

Let's examine each component and then discuss some best practices for Webflow development.

Note: You can download this article's source code from Resources.

Webflow components

A Webflow is composed entirely of nodes. A node is an abstract component that represents an object in a Web application. Nodes are interconnected by transitions (events). A simple Webflow can illustrate this:

Origin JSP -> Input processor -> Destination JSP

Each arrow in the illustration is an event processed by the Webflow system. Therefore, a Webflow is a string of connected nodes that outlines a logical flow of a part of a Web application. This section briefly describes the types of nodes and other concepts that compose the Webflow framework. We will not rehash existing BEA documentation here. In-depth information about these components can be found on BEA Systems' Website (see Resources).

Presentation nodes

Presentation nodes represent components that allow users to interact with a Web application. Some examples include JSP, HTML, Wireless Markup Language (WML), or servlets.

InputProcessor nodes

These nodes are Java classes that implement the InputProcessor interface. As a result, InputProcessors must implement the following method:

   public Object process(HttpSerlvetRequest request, Object requestContext) throws ProcessingException

The HttpServletRequest object is the request submitted to the WebLogic application server from a client. This request derives from the presentation node that preceded the InputProcessor. In the simple Webflow example above, a form or anchor tag in the Origin JSP creates the request that passes to the InputProcessor. The requestContext is a unique identifier for the request.

Pipelines and PipelineComponent nodes

PipelineComponents execute specific tasks related to business processes and can be transactional or nontransactional. Multiple PipelineComponents can connect into a single pipeline. Pipeline execution is linear because it does not support branching. Transactional pipelines ensure that all the components complete successfully or the transaction will roll back. PipelineComponents contain business logic that may apply to multiple Web applications within a larger enterprise application and are therefore loaded into BEA WebLogic's Enterprise JavaBeans (EJB) container. PipelineComponents implement the PipelineComponent interface. As a result, PipelineComponents must implement the following method:

   public Object process(PipelineSession pipelineSession, Object requestContext) throws PipelineException, RemoteException

The PipelineSession mechanism allows communication between InputProcessors within the Web application and PipelineComponents within the enterprise application. The requestContext is the same unique identifier passed to the InputProcessors.

Namespaces

Namespaces allow developers to divide a Web application into multiple Webflows. Each Webflow has its own namespace, and it is not embeddable. Usually, namespaces are created along logical lines. For example, in a typical e-commerce Website, a developer could create separate namespaces for an online catalog, profile management, check-out, and order lookup.

Events

Events are the transitions from one node to another and the transitions between Webflows and pipelines. When a node completes its task, it returns an event used by the Webflow system to determine the next node in the Webflow to call. Presentation nodes can generate events from form submissions, hyperlinks, or any other method of generating a request to the server. InputProcessor nodes generate events by the return value from the process method. They can also generate exception events by throwing exceptions. Both event types from InputProcessors tell the Webflow system which node is next.

The E-Business Control Center

The E-Business Control Center (EBCC) is the main graphical user interface (GUI) application used to create Webflows and manage the BEA WebLogic Portal application. Within EBCC, developers can associate nodes with JSP pages, PipelineComponents, and InputProcessor classes. They can also perform other tasks related to BEA WebLogic Portal such as user management tasks and campaign tasks. For this article, we just focus on EBCC aspects related to Webflow creation and management.

Under EBCC's hood, several XML files store the information about a Webflow. While a developer usually doesn't edit these files directly, it is important to know about the following Webflow files:

  • The project file, <project name>.eaprj, is the main project file for a Webflow application
  • The .wf file, <namespace>.wf, contains the primary information for a Webflow namespace, including transitions/events between nodes
  • The .wf.ui and .ui files contain information used to display Webflow components in the way they were last organized in the EBCC
  • The .wfx file allows extensions to Webflow and is outside this article's scope

Sample Webflow application

In this section, we create a sample application using Webflow to simulate a shipment tracking process. This sample application includes the concept of emailing tracking information to the user. However, the actual work of retrieving the tracking information and emailing it has been removed to keep the application simple.

Remember: Pipelines are linear, so branching based on a pipeline's result is difficult, and looping is even more difficult; therefore, pipelines should be placed in a location where the flow is linear and no branching or looping occurs. Unless you need transactions, pipelines are usually too restricting.

Webflow in EBCC

The first step in building a Webflow-based application is to conceptually break down the pieces. A few best practices apply here. For example, it is a good idea to separate form validation from the rest of the logic. In the Webflow world, this means putting the validation logic into its own InputProcessor.

Another best practice involves deciding whether to use pipelines and PipelineComponents. Pipelines are ideal when business logic is grouped together and no branching or looping conditions exist, as mentioned above. If the execution flow will reach a certain point after which one of many different flows are taken next, then you should use InputProcessors. Likewise, if you have a condition where you need to repeat the same flow again, you should use InputProcessors. However, if neither of these cases applies to you, pipelines may suit your needs.

Lastly, consider whether the flow needs to be transactional. For example, if a flow contains two steps and both must complete successfully and commit or unsuccessfully and roll back, you may want to leverage PipelineComponents as EJB components, as this allows support for transactions.

In our application, we have a branching case, regardless of whether the user selects to receive email about the tracking information. Therefore, we put all our logic into InputProcessors. We'll have three InputProcessors for our application's three logical steps. These steps are:

  1. Retrieve input from the user and validate it
  2. Retrieve tracking information from the backend system
  3. Optionally email tracking information to the user

An implied fourth step is displaying the tracking information to the user. That logic is not part of our business logic, but rather the view logic, and therefore belongs in a JSP page.

The Webflow, following the addition of InputProcessors and the setup of JSP pages, is depicted in Figure 1:

Figure 1. Complete Webflow

You can see the starting node is the index presentation node. This node contains a single event named submit (shown in Figure 2) that directs the flow to the ExampleValidationIP.

Figure 2. Webflow event

For this node, there are two events. The first one, shown in Figure 3, is an exception event for the com.bea.p13n.appflow.Webflow.forms.InvalidFormDataException exception. If the ExampleValidationIP class throws an instance of this exception, then the Webflow will follow this event back to the index presentation node.

Figure 3. Webflow exception

Details for Figures 2 and 3 are shown in Figures 4 and 5, respectively:

Figure 4. Webflow event detail
Figure 5. Webflow exception detail

The JSP page

We now need to write the code that performs validation and throws the exception. Before we tackle this piece, we first need to construct our JSP page or at least have in mind what the JSP page will contain. We will have a single form for the user to supply tracking information, such as a tracking number. The user will have a selection for email and a place to insert his email address.

As part of Webflow, BEA provides a tag library that supplies tags that facilitate form value validation. These tags and the associated API are called the validated form. The validated form is an under-documented feature of Webflow. Roughly speaking, a validated form allows developers to easily validate form fields by name (the HttpServletRequest parameter's name) and populate very simple JavaBean properties. This API does not support complex JavaBean operations.

First we include the tag library on the JSP page like this:

   <%@ taglib uri="WebFlow.tld" prefix="wf" %>

Our validated form within the JSP looks like this:

   <wf:validatedForm event="submit" namespace="Example" applyStyle="field" invalidStyle="color: red;">
      Tracking number <wf:text name="trackingNumber"/><br>
      Email? <wf:checkbox name="email" value="true"/><br>
      Email address <wf:text name="emailAddress"/><br>
      <input type="submit" value="Submit" name="submit"/>
   </wf:validatedForm>

The validation code

Now that we have set up our JSP page, we can start on the validation code. We will use a few classes from the ValidatedForm API: the ValidatedFormFactory creates the ValidatedForm class, and the ValidatedValuesFactory creates the ValidatedValues class. The ValidatedForm class and the ValidatedValues class together track the values the user supplies on each form field and determine whether the particular form field is valid. So, when validation errors are encountered, and our Webflow redirects the user back to the input page, the ValidatedForm API repopulates the form fields with the previous values, and any error messages will display.

The code to validate a form field looks like this:

   // Create the request JavaBean and store it in the request
   TrackingRequest trackingRequest = new TrackingRequest();
   request.setAttribute("trackingRequest", trackingRequest);
   ValidatedForm vForm = ValidatedFormFactory.getValidatedForm();
   ValidatedValues vValues = ValidatedValuesFactory.getValidatedValues(request);
   // Set the JavaBean values, except the Boolean for the check box, which
   // we will have to set automatically, because the ValidatedForm API from
   // BEA doesn't handle it
   vForm.validate(vValues, trackingRequest);
   ...
   // Validate the tracking number
   vForm.validate(vValues, STRING_VALIDATOR, "trackingNumber", new MinMaxExpression(10, 15),"The tracking number must be between 10 and 15 characters");
   // If the user selected email, validate the email address
   if (trackingRequest.isEmail()) {
    vForm.validate(vValues, STRING_VALIDATOR, "emailAddress",
        new MinMaxExpression(10, 100),
        "The email address must be between 10 and 100 characters");
   }
   if (vValues.getInvalidFieldCount() > 0) {
       throw new InvalidFormDataException("Please correct the invalid   fields");
   }

This code snippet uses the validate() method. This method takes the name of the request parameter to validate, the name of the validator to use (here we use the STRING_VALIDATOR, which is a validator provided by BEA), and an expression to assist the validator during validation.

1 2 Page 1
Page 1 of 2