“Struts Your Stuff” in JDeveloper 10g[1]

Dr. Paul Dorsey, Dulcian, Inc.

Overview of Struts

Struts is a framework of reusable components used in J2EE web applications built with various technologies such as JavaServer Pages (JSPs), JavaBeans, and servlets. The Struts framework is part of the Apache Software Foundation's Jakarta Project. Although Struts can be used to manage any J2EE (or Java) development effort, its primary use is for web development. This includes applications built using JSP pages, HTML, and Oracle's Application Development Framework (ADF) UIX. Struts is used for building and managing page flow. Struts logic manages how pages are connected, what happens before calling a page, how the page is called and then submitted. Using ADF, the Struts controller manages the communication of data from the Model layer to the View layer. Struts also includes an architecture and a library of elements to support that architecture as well as a number of tag libraries designed to simplify the interaction between page elements and Struts controller functionality.

 

Model-View-Controller

Oracle’s Application Development Framework (ADF) is based on the J2EE design pattern Model-View-Controller (MVC). The Model-View-Controller design pattern defines three main layers of application code:

·         The Model layer represents the data and values portion of the application.

·         The View layer represents the screen and user interface components.

·         The Controller layer handles the user interface events that occur as the user interacts with the interface (view), controls page flow, and communicates with the model layer.

Conceptually, these layers are independent so that code in one layer can be switched to another technology and still use the other two layers without modification. For example, if you build your view layer on JSP technology, you could switch ADF UIX into the application and retain the same model and controller layers. In practice, completely separating layers is difficult to achieve. There are two different approaches to the Model architecture in the MVC design pattern.

 

Model I vs. Model II

Using the traditional or “Model 1” architecture, the user interface controls all application logic. There is no separation between application components and how they interact. The Java code is embedded in HTML code and JSP page(s). Applications built using this approach are often difficult to develop, debug and maintain.

Various controller technologies have been developed to separate much of the logic from user interface development. Using this approach, the display code is separated from the page flow control code and results in what is called “Model 2” architecture. This Model 2 architecture involves servlets running in the application server, which control the page flow with any necessary logic. Using this strategy for creating JSP pages, developers only need to write minimal display logic (using JSTL or Struts tags) designed to interact with the controller implementation. Struts is the most popular of the available controller technologies that promote Model 2 architecture.

 

Struts Concepts

The Struts architecture contains a number of elements. In traditional development environments, all of these elements would have to be maintained by hand. JDeveloper 10g handles most of the complexity using graphical drag-and-drop tools. Struts uses a state transition engine (STE) metaphor for page control using JSP or HTML pages that are obvious STE nodes. It is also sometimes necessary to have STE nodes that are not associated with displayed pages to perform some programmatic function. To accomplish this, Struts also includes actions, which act as STE nodes. Forwards are the links between nodes in Struts.

The following are brief descriptions of the elements used by JDeveloper 10g to create Struts applications.

 

Action and Forward Tags

Action tags are used to change control in an application. These tags may have a number of properties and other tags nested inside of them. An action may also have many forward tags defined within it. Forward tags actually change the control based on a parameter passed from the application. Each forward tag provides an alternative place to which the action can branch. Forward tags can point to other action tags for more processing, or displayable pages to continue the application flow.

A forward tag has two parameters: name and path. The forward's name parameter represents the expected value of the passed parameter (for example, “success” or “failure”). The path parameter indicates where control will be passed (to another action or another page). The action tag may also have a property that points to a Java file (called the action class) for more complex control.

 

Action Class

Action classes consist of any custom Java classes that extend the Struts class org.apache.struts.action.Action. Each Struts action may have an action class associated with it. The most common use of an action class is to support complex page flow logic. Java code placed in an action class can help implement any business logic needed between pages. For example, it is possible to execute a stored procedure and use the results to decide on an appropriate branch page. Implementing an action class allows developers to add custom functionality to their applications.

The Struts action class includes a method called “execute.”  This method is where the custom code to be executed is placed. Struts developers often write complex data validation in the action classes although, in JDeveloper 10g,, most of this logic is written in the ADF BC entity objects located in the business services layer.

 

ActionForm Class

An ActionForm class (also called a FormBean) is a Java class that caches data as navigation moves from to page to page. It also handles the persistence requirements of the application within the session. Traditionally, Struts developers place simple validation, such as checking for mandatory fields that have been left blank, in the ActionForm class.

Custom ActionForm classes are not usually used in JDeveloper 10g. Using ADF BC, the ADF framework generates code to replace the ActionForm class dynamically. The business services layer can be used to implement validation and persistence requirements. The ADF Model layer bolts the business services to the Struts framework automatically. ActionForms are Java classes referenced within form-beans tags in the struts-config.xml file.

 

struts-config.xml File

The core of Struts is the struts-config.xml file. This XML file is where all of the Struts action tags, form-bean tags, and message resources tags are defined. The action tags include references to the forward tags that define the possible paths to which the controller can send the application. It is the job of the action classes to select the appropriate forward for any given situation in the page flow.

The struts-config.xml file is divided into several sections:

·         The form-bean area, at the top of the file, lists all of the ActionForm classes in the application. In Oracle ADF, the form-bean area of the struts-config.xml file becomes a single line that interfaces with the UIModel.xml files, forming Oracle's ADF databinding.

·         The second section is the action-mappings area. This section lists all of the action tags, what action class (if any) is called when the action is called, and the possible forward tags for a given action tag. ADF adds an element called a data action. A data action is similar to a generic action, but it extends the oracle.adf.controller.struts.actions.DataAction class. In this class, Oracle has provided a number of methods that automatically connect to data controls. These methods can be overridden to incorporate any necessary code needed to control the application.

As an example, the following file fragment is based on Oracle's ADF (line numbers were added for reference purposes and are not part of the code):

01: <struts-config>
02:   <form-beans>
03:     <form-bean name="DataForm"
04:       type="oracle.adf.controller.struts.forms.BindingContainerActionForm"/>
05:   </form-beans>
06:   <action-mappings>
07:     <action path="/browseDeptDA
08:         className="oracle.adf.controller.struts.actions.DataActionMapping"
09:         type="view.BrowseDeptAction" name="DataForm">
10:       <set-property property="modelReference" value="browseDeptDPUIModel"/>
11:       <forward name="success" path="/browseDeptDP.do"/>
12:     </action>
13:     <action path="/browseDeptDP"
14:         className="oracle.adf.controller.struts.actions.DataActionMapping"
15:         type="oracle.adf.controller.struts.actions.DataForwardAction"
16:         name="DataForm"
17:         parameter="/browseDeptDP.jsp">
18:       <set-property property="modelReference" value="browseDeptDPUIModel"/>
19:     </action>

 

In the preceding code, note that the ADF binding class (line 04) that replaces the traditional ActionForm class is referenced in the form-beans tag (oracle.adf.controller.struts.forms.BindingContainerActionForm). Following that section, there are two action tags (lines 07 and 13) with their associated action classes. These tags are being created as data actions from ADF and automatically bind themselves back to the ADF Model layer via the property references (className, type, and name).

Notice the “.do” in the sample code (in the path property of the forward tag on line 11). The path property in the forward tag acts like a method on the item that it suffixes (/browseDeptDP, in this example). When the Struts controller encounters a “.do” reference, it acts as an internal “go to” for the Struts controller and executes the matching action tag that has the path value with the same name as the “.do” item. For example in this code:

      <forward name="success" path="/browseDeptDP.do"/>

the forward tag indicates that the following should be executed:

<action path="/browseDeptDP" ...>
    </action>

 

Interaction of Struts Elements

The following sample sequence of steps helps to explain the concepts described above, using a hypothetical Struts application that needs to display data from the database:

1.       The action class requests information from the database.

2.       The database returns the data to the action class.

3.       The action class passes the data to the DataForm class.

4.       The DataForm class passes the data to the JSP page.

5.       If there are any edits, the page passes them back to the ActionForm class, which may perform simple validation. If that validation fails, the application control returns to the page to allow the user to correct the data.

6.       If validation succeeds, the data is passed back to the action class. The action class executes any complex validation and then decides where to pass control.

7.       The control is passed via the forward tags to other action tags or another viewable page.

8.       Finally the action class will send any updated data back to the database.

Figure 1 shows how these elements interact.

Figure 1: Interaction of Struts elements

JDeveloper 10g and Struts

JDeveloper has done much more than provide a graphical user interface to write Struts code. ADF has extended and simplified the framework to assist developers in building Struts applications. In Oracle 9i JDeveloper, it was necessary to write a lot of code by hand and it was often difficult to get things working properly. Moving to 10g, development became much easier, but also very different. JDeveloper 10g extends the base Struts functionality and binds it closely to Oracle ADF.

Using ADF business services, the Struts components are automatically configured to interact with the business services being created. Struts development really begins after the business services project is built. JDeveloper 10g has extended many traditional Struts elements to provide the ability to develop code faster and make it more maintainable.

In traditional Struts development, pages, action classes, and ActionForm classes are built using the code editor of your choice. In JDeveloper 10g Struts development, a visual page-flow editor is used to define pages, data actions, and forwards using a drag-and-drop interface. Although most of the code is generated, it can be modified at any time by switching to the source code tab located at the bottom of the screen. This approach allows developers to concentrate on the page flow logic while JDeveloper handles the drudgery of coding the struts-config.xml file.

As you build Struts applications, control passes to pages or data actions in a way similar to that of a state transition engine. This is an excellent way to think about development, and JDeveloper implements this philosophy brilliantly.

 

Struts Elements in JDeveloper 10g

The primary tools used when creating Struts applications in JDeveloper are the Page Flow Diagram, the Component Palette, and the Data Control Palette. The following are the Struts components available for use on the Page Flow Diagram, accessed by selecting the Struts Page Flow page of the Component Palette shown in Figure 2.

 

Figure 2: JDeveloper Struts Page Flow Component Palette

Page

The Page component allows you to create a JSP page on the diagram. The Page component will not be needed when using ADF and is only included for pages that do not interact with any business service. Double clicking the page icon on the diagram, causes JDeveloper to create the JSP file and navigate to the visual editor view of that file.

 

Data Page

A data page is a user interface page (JSP page or UIX file) that is enabled to use ADF. It contains the functionality of both a data action and a Struts page. Data page components can be dropped onto a data page and the framework will take care of binding them to the ADF business services components such as ADF BC. The strength of this element is its compact structure in which only simple data binding and page flow are required. However, the separate data action class must be used when more complex logic is required.

It is customary to create one data page for each unique screen in an application. Typically there will be one page for a multi-record display and a separate page to edit a single record. When a data page is created, JDeveloper generates the following code:

<action path="/dataPage1"
className="oracle.adf.controller.struts.actions.DataActionMapping"
type="oracle.adf.controller.struts.actions.DataForwardAction"
name="DataForm"
parameter="unknown"/>

The path attribute designates the name of the data page. The generated user interface page will use this name. For example, the JSP page generated in this example would be called “dataPage1.jsp.”

The className and name attributes connect the data page to ADF business services. These properties need never be modified.

 

Action

The Action element defines how the incoming HTTP request will be handled by the Struts controller, including interaction with the data model and page navigation. When an action icon is placed on the Page Flow Diagram, it will display with an information (exclamation point) icon. This means that information defining the action class for that action has not yet been entered. Double clicking the action to associate it with an action element causes the indicator to disappear.

 

Data Action

A Data Action tag contains properties set so that it uses the ADF framework. A data action is frequently used to query data. The default behavior of the framework passes the data to the path defined in the forward tag (named “success” by default) for the given data action tag. A data action can also navigate from one element to another based upon some condition.

In simple applications, ADF makes it unnecessary to use data actions very often. Applications including quite a lot of functionality can be built using only a few components. When building more complex applications, it is frequently necessary to go beyond what the framework provides by default.

In very complex applications, data actions are a common element type in the Page Flow Diagram. There can be separate data actions for creating a record, deleting a record, editing a record, querying data for display in a multi-record block, and so on.

It is possible to query data and display it in a single data page; however, using this strategy means that the additional control that a data action provides is lost because the ability to override the default behavior of the data action class is lost. This occurs because the data page tag is of type “DataForwardAction,” where the “DataAction” type is used for the data action tag. For this reason, it may be preferable to use a data action for each data page in the Page Flow Diagram where complex logic may be needed.

Dropping a data action onto a Page Flow Diagram causes the following code to be placed in the action mapping area of the struts-config.xml file:

<action path="/dataAction1"
  className="oracle.adf.controller.struts.actions.DataActionMapping"
  type="oracle.adf.controller.struts.actions.DataAction"
  name="DataForm"/>

This entry creates a Struts action tag called “dataAction1” and prepares it to be associated with an ADF element because of the reference to “DataForm” in the name attribute. DataForm is a JavaBean that is part of the ADF Struts framework. The DataForm is a reference to the class (DataActionMapping) that creates the automatic bindings between ADF BC and Struts. This will allow data to be passed to and from the business service layer.

The clause type="oracle.adf.controller.struts.actions.DataAction" is the Oracle default data action and causes the other ADF-related properties to be correctly interpreted. Once the Struts action is created, double clicking it generates an associated data action class, which can be used to override or extend any of the ADF default behavior.

 

Forward

The Forward component is a standard Struts element that links any two data actions, data pages, or page forwards. A forward can form a link between components whether they are of the same type or not. A forward is a name-destination pair that resides within the source component. The name represents the name of the link between the components and the destination (path) is the name of the component to which the forward link navigates.

A forward represents a change of control in the program logic. It is the Struts equivalent of a “goto” or a hyperlink. Drawing a forward named “success” from a component called “A” to one called “B,” adds the following code to the struts-config.xml file within the declaration of the “A” component.

    <forward name="success" path="/B.do"/>

 

Page Link

A Page Link is a Struts element corresponding to the standard Struts HTML link tag that calls a separate component. Page links always start in a page (or data page) and the destination is either a data page (or page) or a data action. Page links do not impact the struts-config.xml file, but they are frequently used when building web applications.

Placing a page link in the Page Flow Diagram between two pages “A” and “B” adds the following code to the user interface page for “A” (assuming the use of JSP technology):

  <html:link page="/B.do">
      <bean:message key="link.B"/>
  </html:link>

The link page tag tells the page where to go and the message tag indicates where to find the label text (the key) for the link in the .properties file.

 

Page Forward

A page forward is a simple link to a page. When you drag a Page Forward onto the diagram, the following code is created:

  <action path="/page1" forward="unknown"/>

When you double click the component to create a user interface file (for example, a .jsp file), JDeveloper will add the name of the file to the forward attribute.

It may seem confusing to use both forwards and page forwards. A forward is a simple link to a page or data action. You can have multiple forwards in an action. A page forward is just an action tag with a single forward with no additional properties specified. It is usually associated with a JSP page.

 

Note

In JDeveloper, you can place text on a diagram to annotate your diagram. Notes have no impact on the functionality of your code and do not appear in the struts-config.xml file. Text in a note can be resized, moved, or deleted.

 

Attachment

An attachment is a line that connects a note to any other element (even another note) so you can associate the note with a particular element on the diagram. Notes do not appear in the struts-config.xml file.

 

What is the Real Page Flow for an Application?

It is an oversimplification to think that the struts-config.xml file contains the page flow and that the action classes contain additional called program code. The struts-config.xml contains the definition of some of the page flow but the real situation is a bit more complex. First, the struts-config.xml file does not contain the complete page flow logic. It does contain the “nodes” (pages and action tags) of the page flow, and the forward tags that represent transitions, but the struts-config.xml file explicitly does not contain the logic to choose which forward tag should be selected when there is more than one defined in a particular action tag. That logic is always contained in the action class.

Second, it is possible to circumvent the implied flow in the struts-config.xml file. This practice should be avoided because the external link is not contained within the struts-config.xml file and this fragments the page flow definition. A sample page flow is shown in Figure 3.

Figure 3: Sample Struts Page Flow diagram

Most of the transitions between nodes are represented as forward tags within the action in the struts-config.xml file, but other transitions may be executed in the code (such as in the JSP pages) that do not appear in the struts-config.xml file.

Finally, if any action tag has more than one forward tag associated with it, the logic to determine which forward to use must be written in the action class associated with the action tag. Therefore, to examine the complete page flow, look at the struts config.xml file, in the code in the action classes, and in the code in the application pages.

 

Tips

JDeveloper 10g is a deep and complex product. Before building applications with it, it is important to have the right hardware and get some guidance from others who have been building production applications with JDeveloper.

 

Required Hardware

In order to develop effectively using JDeveloper, the following hardware is strongly recommended:

·         Dual 20 inch monitors – You often need many things open on the screen at once. With a small monitor, you will need to toggle back and forth between many windows.

·         >=1 GB memory (even if you are not running the database) ; 2 GB is good;  4 GB is ideal.

·         > 2 GHz processor

Without these minimums, development may be tedious at best, next to impossible at worst if the memory requirements are not adequate.

 

Tips & Techniques

Based on our experiences building applications with JDeveloper, you should keep the following tips and techniques in mind when building your own applications:

1.       Cut and paste code with caution. In many cases, you can use the wizards. If you do cut and paste code, be aware that most data operations are located in two places: the XML and Java or HTML code. You must be sure that the changed code appears in both places.

2.       Don’t rename items. The renamed item may not propagate to all of the relevant places in the code. Even using the Remove functionality does not always produce the desired results.

3.       Drag and drop can be used to add elements but it will never delete them completely.  In a JSP, you must delete from both the screen and the Structure pane. The bindings area does not always clean up neatly when items are deleted.

4.       Save often (certainly prior to each running). Make backups of the whole directory in which you are working.

5.       Use the naming convention “event_... “ in forward tags in the struts_config.xml file. This saves coding since ADF auto looks for events named this way (uses “line” name).

6.       Do not use HTML components when creating Struts applications. They will not bind properly. Instead, use the JDeveloper Component Palette “Struts HTML” list of components.

Using these tips will give you a head start in building applications successfully and help you avoid some annoying and time consuming mistakes.

 

Conclusions

There are many different elements in the Struts framework. Even with the support from Oracle's ADF framework, it can still be confusing when building your first few applications.

There are always multiple ways of building any application. You can use different combinations of Struts components to accomplish the same goals. In general, you will mainly use data actions and data pages. Standard pages can be used when there is no data interaction. Page forwards are used when creating “child” data pages (for example, a new or edit record page connected to a browse data page). Components are connected using a forward to associate the transition with a button or program logic. Page links handle transitions using a link on the page. A simple Struts application created in JDeveloper is shown in Figure 4.

Figure 4: Sample Struts Application

Building J2EE applications remains a challenging task with a steep learning curve. Some portions of JDeveloper are still evolving, specifically the WYSIWYG graphical Struts designers and visual editors, which are solid efforts that continue to mature quickly. JDeveloper 10g has made it easier for development organizations to make the transition from fourth-generation language (4GL) tools such as Oracle Forms Developer into the J2EE space. The 10g release deserves high marks for supporting the J2EE/Java development vision.

 

About the Author

Dr. Paul Dorsey is the founder and president of Dulcian, Inc. (www.dulcian.com) an Oracle consulting firm specializing in business rules and web based application development. He is the chief architect of Dulcian's Business Rules Information Manager (BRIM®) tool. Paul is the co-author of seven Oracle Press books on Designer, Database Design, Developer, and JDeveloper, which have been translated into nine languages.  He is President of the New York Oracle Users Group and a Contributing Editor of IOUG's SELECT Journal.  In 2003, Dr. Dorsey was honored by ODTUG as volunteer of the year, in 2001 by IOUG as volunteer of the year and by Oracle as one of the six initial honorary Oracle 9i Certified Masters.  Paul is also the founder and Chairperson of the ODTUG Business Rules Symposium, (now called Best Practices Symposium), currently in its sixth year, and the J2EE SIG (www.odtug.com/2005_J2EE.htm).

 

 



[1] Some of the material in this paper is adapted from the Oracle JDeveloper 10g Handbook (Faderman, Koletzke, Dorsey, Oracle Press, 2004)