kapok

垃圾桶,嘿嘿,我藏的这么深你们还能找到啊,真牛!

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  455 随笔 :: 0 文章 :: 76 评论 :: 0 Trackbacks
http://dev2dev.bea.com/pub/a/2004/01/Dew.html

Web application development is hard. Or rather, Web application development used to be hard. Web application development used to be an activity that required developers to learn and use complex programming models. Web application development used to be an activity that required developers to manage the myriad details of configuring their Web application so that the various pieces of the application worked together. Web application development used to be an activity that was performed outside of the helpful environment of an IDE.

No longer.

The new Java Page Flow feature set of WebLogic Workshop 8.1 beta makes Web application development easy. Java Page Flow provides a simplified, easy-to-understand Web application programming model. Java Page Flow automatically manages Web application configuration details. And Java Page Flow provides a set of tools that help developers to quickly and correctly build Web applications and to integrate those applications with business logic.

What is it?

Java Page Flow is a feature set built upon a Struts-based Web application programming model. Java Page Flow leverages the power and extensibility of Struts while also eliminating the difficulties and challenges of building Struts-based applications. Java Page Flow features include runtime support for the Web application programming model and tools that enable developers to quickly and easily build applications based upon the model.

The central concept and construct of Java Page Flow is called page flow. Basically, a page flow is a directory of Web app files that work together to implement a UI feature. For example, a page flow could implement a Web app’s user registration wizard feature. The files of such a page flow could be arranged in a userRegistration directory as follows:

1


The userRegistration directory contains several *.jsp files, a *.jcs file and a *.jpf file. The *.jsp files are standard Java Server Pages files that contain markup that describes the visual aspect of the user registration wizard. For example, name.jsp contains markup that describes a First Name and Last Name data entry form. The *.jcs file is a BEA innovation. It contains annotated Java code that implements logic used by the user registration wizard. For example, UserManager.jcs contains code that implements a createUser( ) function. The *.jpf file is also a BEA innovation and is the main focus of this article. It contains annotated Java code that implements the navigation and state management logic of the user registration wizard and that makes calls to business logic. For example, UserRegistrationController.jpf contains code that decides that name.jsp should be presented before address.jsp, that gathers the firstName and lastName information from name.jsp before presenting address.jsp, and that calls the createUser( ) function of UserManager.jcs.

For those who are familiar with Struts and the Model-View-Controller (MVC) way of programming, the files of the user registration wizard may be mapped to the 'M', the 'V' and the 'C' of MVC this way:

 Model ( M )  UserManager.jcs
 View ( V )  name.jsp
 address.jsp
 confirmation.jsp
 Controller ( C )  UserRegistrationController.jpf


Page Flow Controllers

Page flow controllers are the main focus of this article. So, let’s take a step-by-step look at the contents of the UserRegistrationController.jpf file and how the file performs its navigation, state management, and logic-calling functions.

First of all, UserRegistrationController.jpf contains a class definition whose skeleton looks like this:


  package userRegistration;

  import com.bea.wlw.netui.pageflow.PageFlowController;

  public class UserRegistrationController
  extends PageFlowController
  {
    ...
  }

UserRegistrationController extends PageFlowController, which is a class that provides useful base class functionality and that derives indirectly from org.apache.struts.action.Action. The base class functionality of PageFlowController provides support for things such as login and logout. The derivation from Action is an important aspect of the Struts interoperability of PageFlowController. Many classes in Java Page Flow inherit from Struts classes and interoperate with the Struts plumbing that serves as the foundation for the Java Page Flow runtime.

Actions and Navigation

Because UserRegistrationController acts as the controller for the user registration wizard, it contains code that performs the page navigation decisions for the wizard. This code is in the form of action methods. Action methods are methods that are invoked in response to things like form submissions. For example, UserRegistrationController contains an action method named name_next:


  package userRegistration;

  import com.bea.wlw.netui.pageflow.Forward;
  import com.bea.wlw.netui.pageflow.PageFlowController;

  public class UserRegistrationController
  extends PageFlowController
 {

    /**
     * @jpf:action
     * @jpf:forward name="getAddress"
     *              path="address.jsp"
     */
   public Forward name_next( ... )
   {
     ...

     return new Forward("getAddress");
   }

   ...
  }

The name_next action method is invoked whenever a user submits the form of the name.jsp page:


  <%@ taglib uri="netui-tags-html.tld" prefix="netui"%>

  <html>
      <head>
          <title>Name Page</title>
      </head>
      <body>
          <netui:form action="name_next" focus="">
              <table>
                  <tr>
                      <th align="right" valign="top">First Name:</th>
                      <td align="left">
                          <netui:textBox dataSource="{actionForm.firstName}"
                                                   size="16"
                                                   maxlength="18"/>
                      </td>
                  </tr>
                  <tr>
                      <th align="right" valign="top">Last Name:</th>
                      <td align="left">
                          <netui:textBox dataSource="{actionForm.lastName}"
                                                   size="16"
                                                   maxlength="18"/>
                      </td>
                  </tr>
                  <tr>
                      <td align="right"></td>
                      <td align="left">
                          <netui:button value="name_next"/>
                      </td>
                  </tr>
              </table>
          </netui:form>
      </body>
  </html>
 

The name_next action method decides that the address.jsp page should be the next page presented to a user. Because the name_next action method is invoked whenever a user submits the form of the name.jsp page, the name_next method effectively causes navigation from the name.jsp page to the address.jsp page.

All action methods have similar signatures. For example, they all have Forward as their return type. All action methods are specially annotated with @jpf:action to indicate to the *.jpf compiler that they should be configured as action methods in the auto-generated Struts configuration files. Also, all action methods may be annotated with @jpf:forward to indicate to the *.jpf compiler and to the IDE tools the possible navigation decisions that the action methods may make such as deciding to forward to a page like address.jsp. All action methods are called by the page flow runtime and express their navigation decisions to the runtime by returning objects of type Forward to the runtime. The Forward objects encapsulate information described by the @jpf:forward annotations on the action methods.

The page flow runtime is responsible for selecting and calling action methods in controllers as part of the runtime’s request processing lifecycle. The page flow runtime is also responsible for executing the navigation decisions made by the action methods. In other words, if a user submits the form of address.jsp., the page flow runtime performs a request processing lifecycle that includes these steps:

  1. Intercept the submission when it arrives at the application server
  2. Determine that the name_next action method should be called
  3. Call the name_next method
  4. Receive the Forward("getAddress") object from the name_next method
  5. Forward to the address.jsp. page described by the Forward("getAddress") object
Page flow controllers may contain any number of action methods. For example, UserRegistrationController contains five action methods in addition to the name_next action method:


  package userRegistration;
  import com.bea.wlw.netui.pageflow.Forward;
  import com.bea.wlw.netui.pageflow.PageFlowController;

  public class UserRegistrationController
  extends PageFlowController
  {
    ...

    /**
     * @jpf:action
     * @jpf:forward name="getName"
     *              path="name.jsp"
     */
    public Forward begin( ... )
    {
      ...

      return new Forward("getName");
    }

    /**
     * @jpf:action
     * @jpf:forward name="getAddress"
     *              path="address.jsp"
     */
    public Forward name_next( ... )
    {
      ...

      return new Forward("getAddress");
    }

    **
     * @jpf:action
     * @jpf:forward name="getConfirmation"
     *              path="confirmation.jsp"
     */
    public Forward address_next( ... )
    {
      ...

      return new Forward("getConfirmation");
    }

    /**
     * @jpf:action
     * @jpf:forward name="done"
     *              returnAction="userRegistrationDone"
     */
    public Forward confirmation_next( ... )
    {
      ...

      return new Forward("done");
    }

    /**
     * @jpf:action
     * @jpf:forward name="getName"
     *              path="name.jsp"
     */
    public Forward address_back( ... )
    {
      ...

      return new Forward("getName");
    }

    /**
     * @jpf:action
     * @jpf:forward name="getAddress"
     *              path="address.jsp"
     */
     public Forward confirmation_back( ... )
     {
      ...

      return new Forward("getAddress");
     }

  }
 

Forms

In addition to selecting and calling action methods, the page flow runtime also passes to the action methods any form data that may have been submitted. For example, when a user submits the form of the name.jsp page, the page flow runtime captures the firstName and lastName data of the form in properties of a NameForm object, and passes the populated NameForm object to the name_next action method:


  package userRegistration;

  import com.bea.wlw.netui.pageflow.FormData;
  import com.bea.wlw.netui.pageflow.Forward;
  import com.bea.wlw.netui.pageflow.PageFlowController;

  public class UserRegistrationController
  extends PageFlowController
  {
  ...

  /**
   * @jpf:action
   * @jpf:forward name="getAddress"
   *              path="address.jsp"
   */
  public Forward name_next( NameForm form )
  {
    ...

    return new Forward("getAddress");
  }

  public static class NameForm
  extends FormData
  {
    private String firstName;
    private String lastName;

    public String getFirstName()
    {
      return firstName;
    }

    public void setFirstName(String firstName)
    {
      this.firstName = firstName;
    }

    public String getLastName()
    {
      return lastName;
    }

    public void setLastName(String lastName)
    {
      this.lastName = lastName;
    }
    }

    ...
 }

State Management

Java Page Flow provides a powerful yet easy-to-use foundation for state management that makes it simple for UserRegistrationController to perform its state management responsibilities. For example, to manage the form data that is received from pages such as name.jsp, code may be added to UserRegistrationController that captures the data in convenient instance members:


  package userRegistration;

  import com.bea.wlw.netui.pageflow.FormData;
  import com.bea.wlw.netui.pageflow.Forward;
  import com.bea.wlw.netui.pageflow.PageFlowController;

  public class UserRegistrationController
  extends PageFlowController
  {
    ...

    public String firstName;
    public String lastName;

    /**
     * @jpf:action
     * @jpf:forward name="getAddress"
     *              path="address.jsp"
     */
    public Forward name_next( NameForm form )
    {
      firstName = form.getFirstName();
      lastName = form.getLastName();

      return new Forward("getAddress");
    }

    public static class NameForm
    extends FormData
    {
      private String firstName;
      private String lastName;

      public String getFirstName()
      {
        return firstName;
      }

      public void setFirstName(String firstName)
      {
        this.firstName = firstName;
      }

      public String getLastName()
      {
        return lastName;
    }

      public void setLastName(String lastName)
    {
        this.lastName = lastName;
    }
    }

    ...
  }
  

Because the page flow runtime makes it possible to cache state in controller instance members, it’s very easy to implement support for a back button in a wizard. For example, if the confirmation.jsp page contained a back button, UserRegistrationController could respond to a press of the back button by navigating backward to the address.jsp page with all previously-filled-out address.jsp form data still intact:


  package userRegistration;

  import com.bea.wlw.netui.pageflow.FormData;
  import com.bea.wlw.netui.pageflow.Forward;
  import com.bea.wlw.netui.pageflow.PageFlowController;

  public class UserRegistrationController
  extends PageFlowController
  {
    ...

    public String firstName;
    public String lastName;
    public String street;
    public String city;
    public String state;
    public String zip;

    /**
     * @jpf:action
     * @jpf:forward name="getConfirmation"
     *              path="confirmation.jsp"
     */
    public Forward address_next( AddressForm form )
    {
      street = form.getStreet();
      city = form.getCity();
      state = form.getState();
      zip = form.getZip();

      return new Forward("getConfirmation");
    }

    /**
     * @jpf:action
     * @jpf:forward name="getAddress"
     *              path="address.jsp"
     */
    public Forward confirmation_back( )
    {
      AddressForm addressForm = new AddressForm();
      addressForm.setStreet(street);
      addressForm.setCity(city);
      addressForm.setState(state);
      addressForm.setZip(zip);

      return new Forward("getAddress", addressForm);
    }

    public static class AddressForm
    extends FormData
    {
      private String street;
      private String city;
      private String state;
      private String zip;

      public String getStreet()
  {
      return street;
  }

  public void setStreet(String street)
  {
      this.street = street;
  }

  public String getCity()
  {
      return city;
  }

  public void setCity(String city)
  {
      this.city = city;
  }

    public String getState()
  {
      return state;
  }

    public void setState(String state)
  {
      this.state = state;
  }

    public String getZip()
  {
      return zip;
  }

    public void setZip(String zip)
  {
      this.zip = zip;
  }

  }

  ...
 }

As shown, the confirmation_back action method forwards backwards to the address.jsp page. As part of the forward, confirmation_back passes to address.jsp the address data that had already been received from address.jsp as an argument to the address_next action method.

Calling Business Logic

WebLogic Workshop makes it easy to expose business logic as controls, and the Java Page Flow feature makes it easy to call controls from action methods. Because the page flow runtime performs automatic instantiation and initialization of controls for all instance members that are annotated with @common:control, action methods in page flow controllers may call Workshop controls without having to include code that performs control instantiation and initialization. For example, the confirmation_next action method can simply and directly call the createUser( ) method of UserManager.jcs:


  package userRegistration;

  import com.bea.wlw.netui.pageflow.FormData;
  import com.bea.wlw.netui.pageflow.Forward;
  import com.bea.wlw.netui.pageflow.PageFlowController;

  public class UserRegistrationController
  extends PageFlowController
  {
    ...

    public String firstName;
    public String lastName;
    public String street;
    public String city;
    public String state;
    public String zip;

    /**
     * @common:control
     */
    public UserManager userManager;

    /**
     * @jpf:action
     * @jpf:forward name="done"
     *              returnAction="userRegistrationDone"
     */
    public Forward confirmation_next( ... )
    {
      userManager.createUser(firstName,
                              lastName,
                              street,
                              city,
                              state,
                              zip);

      return new Forward("done");
    }

    ...
 }

WebLogic Workshop makes it easy to expose all kinds of business logic as controls, including business logic that is implemented as EJBs. In other words, WebLogic Workshop even makes it easy to build Web applications over EJBs.

Additional Features

Java Page Flow contains many features in addition to those described above. For example, you may have noticed that the @jpf:forward annotation for the confirmation_next action method was a bit different than all of the other @jpf:forward annotations:


  package userRegistration;

  import com.bea.wlw.netui.pageflow.Forward;
  import com.bea.wlw.netui.pageflow.PageFlowController;

  public class UserRegistrationController
  extends PageFlowController
  {
    ...

    /**
     * @jpf:action
     * @jpf:forward name="done"
     *              returnAction="userRegistrationDone"
     */
    public Forward confirmation_next( ... )
    {
      ...

      return new Forward("done");
    }
  }
 

The returnAction="userRegistrationDone" attribute enables UserRegistrationController to participate in a Java Page Flow feature that is called "nesting".

We’ll take a look at nesting as well as other Java Page Flow features such as data binding and custom tag support in a future dev2dev article.

Tools

As mentioned, the Java Page Flow feature set includes some IDE tools that do much to help developers build Web applications. An example of such a tool is the new flow view that enables developers to architect entire Web applications using little more than simple drag-and-drop gestures:

1


Like nesting, data binding, and custom tags, we’ll take a look at the IDE tools in a future dev2dev article.

Take It for a Test Spin

For now, the best thing you can do is to download WebLogic Workshop 8.1 beta, experiment with the new Java Page Flow features, and see for yourself just how much easier Web application development can be.
posted on 2005-04-23 10:28 笨笨 阅读(473) 评论(0)  编辑  收藏 所属分类: J2EEALLWeblogic Portal

只有注册用户登录后才能发表评论。


网站导航: