PowerBuilder Tips, Tricks, and Techniques

Berndt Hamboeck

Subscribe to Berndt Hamboeck: eMailAlertsEmail Alerts
Get Berndt Hamboeck: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Related Topics: Apache Web Server Journal, Java Developer Magazine

Apache Web Server: Article

PowerJ 4.0 - Struts Development

PowerJ 4.0 - Struts Development

Struts is an open source initiative from the Jakarta Project written in Java. Sponsored by the Apache Software Foundation, the project's goal is to provide an open source framework that's useful for building Web applications with Java servlet and JavaServer Pages (JSP) technology. Struts encourages application architectures based on the Model-View-Controller (MVC) design paradigm.

In the MVC design pattern, application flow is mediated by a central controller that delegates requests to an appropriate handler. The handlers are tied to a Model and act as an adapter between the request and the Model. The Model represents or encapsulates an application’s business logic or state. Control is usually forwarded back through the Controller to the appropriate View. The forwarding can be determined by consulting a set of mappings, usually loaded from a database or configuration file. This provides a loose coupling between the View and Model that can make an application significantly easier to create and maintain.

The Model
The Model portion of an MVC-based system can be subdivided into concepts – the internal state of the system and the actions that can be taken to change that state. In grammatical terms, think about state information as nouns (things) and actions as verbs (changes to the state of those things).

Generally, your application represents the internal state of the system as a set of one or more JavaBeans, with properties that represent the details of the state. Depending on your application’s complexity, these beans may be self-contained (and somehow know how to save their state information persistently) or facades that know how to retrieve information from external sources (such as a database) when it’s requested. Entity Enterprise JavaBeans (EJBs) are also commonly used to represent internal state.

Large-scale applications will often represent the possible business logic actions in a system as methods that can be called on the beans that maintain the state information. For example, you might have a shopping cart bean stored in session scope for each current user, with properties that represent the current set of items the user has decided to purchase. This bean might also have a checkOut() method that authorizes the user’s credit card and sends the order to the warehouse to be picked up and shipped. Other systems represent the available actions separately, perhaps as session EJBs.

In some smaller scale applications the available actions might be embedded within the Action classes that are part of the Controller role. This is appropriate when the logic is very simple or where reuse of the business logic in other environments is not contemplated. The Struts framework supports any of these approaches, but recommends separating the business logic (what to do) from the role that Action classes play (deciding what to do).

The View
The View portion of a Struts-based application is generally constructed using JSP technology. JSP pages can contain static HTML (or XML) text called "template text," plus the ability to insert dynamic content based on the interpretation (at page request time) of special action tags. The JSP environment includes a set of standard action tags, such as <jsp:useBean>, whose purpose is described in the JSP specification. In addition, there’s a standard facility to define your own tags, which are organized into custom tag libraries.

Struts includes an extensive custom tag library that facilitates creating fully internationalized user interfaces that interact gracefully with ActionForm beans, which are part of the Model portion of the system.

In addition to JSP pages and the action and custom tags they contain, it’s often necessary for business objects to be able to render themselves in HTML (or XML), based on their current state at request time. The rendered output from such objects can be easily included in a resulting JSP page by using the <jsp:include> standard action tag.

The Controller
The Controller portion of the application focuses on receiving requests from the client (typically a user running a Web browser), deciding what business logic function is to be performed, and then delegating responsibility for producing the next phase of the user interface to an appropriate View component.

In Struts, the primary component of the Controller is a servlet of ActionServlet class. This servlet is configured by defining a set of mappings. Each mapping defines a path that’s matched against the request URI of the incoming request and the fully qualified class name of an Action class (a Java class extending the Action class) that’s responsible for performing the desired business logic and then dispatching control to the appropriate View component to create the response.

Struts also supports the ability to use ActionMapping classes that have additional properties beyond the standard ones required to operate the framework. This allows you to store additional information specific to your application and still utilize the remaining features of the framework. In addition, Struts lets you define logical "names" to forward control to so an action method can, for example, ask for the "loginfailure" page without knowing what the actual name of the corresponding JSP page is. These features greatly assist you in separating the control logic (what do I do next?) from the view logic (what is the name of the corresponding page?).

The primary functionality provided by Struts includes request dispatching, tag libraries to accelerate GUI development, internationalization, and automatic form population. Struts can be used in application development as the underlying architecture on which you develop your Web-based applications.

Installing Struts
The best place to download Struts is at http://jakarta.apache.org/builds/jakarta-struts/release/v1.0. Installation is pretty easy; just unzip your downloaded file, jakarta-struts-1.0.zip, to c:\.

Our First Struts Application
A classic example of the Struts framework is the logon application. This example consists of the following Model-View-Controller (MVC) components.

Model
The model portion of the logon application consists of a subclass of org.apache.struts.action.Action that processes the request and handles all business logic (LogonAction.java). The model then passes control back to the view portion.

View
The view portion consists of three JSP pages:

  1. Input page for logon information (logon.jsp)
  2. Success page to acknowledge successful user login (success.jsp)
  3. Failure page (failure.jsp)
No logic is executed within these pages; they’re purely view pages created using basic HTML/JSP and Struts custom tags for forms. The view also includes a JavaBean that extends the ActionForm class to provide a class interface to the form data (LogonForm.java).

Controller
The controller for the logon application is the same controller used for all Struts applications. It’s a servlet of type org.apache.struts. action.ActionServlet.

Let’s Start
Create a directory to store your PowerJ workspace (C:\struts-login). In PowerJ, create a new workspace called struts-login (File —> New Workspace). Start EAServer 4.0 and make sure you have a working application server profile in PowerJ (Tools —> Application Server Profile).

Create the View Portion
The Logon Page

Create a new JSP 1.2 component (File —> New… from within Workspace View). Follow the wizard, entering in the following information and accepting the default when nothing is specified:

  • Target name: logon
  • JSP page name: logon
  • Configure deployment options now: checked (default)
  • Web application: struts-login
Open the generated logon.jsp file and change the appropriate code. Your workspace should now look like Figure 1.

What Happens Here?

<%@ page language="java" %>
<%@ taglib
uri="/WEB-INF/struts-form.tld"
prefix="form" %>

<form:form action="logon.do">

Username: <form:text property="username" /><br>
Password: <form:password property="
password" /><br>

<form:submit value="Logon" />
</form:form>

First we import the Struts tag library, as we’ll use the form tags associated with it to map our input page to the model portion of the logon application:

<%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-form.tld" prefix="form" %>

Then we use the <struts:form> command from the tag library.

<form:form action="logon.do">

Username: <form:text property="username" /><br>

Password: <form:password property="password" /><br>

<form:submit value="Logon" />
</form:form>

The form tag renders an HTML <form> element based on the specified attributes. It also associates all the fields within this form with a session-scoped form bean (LogonForm.java). This bean is used to provide initial values for all the input fields that have names matching the property names of the bean. If an appropriate bean is not found in the session, a new one will be created automatically.

The action parameter is the same as the action attribute in a normal form. In this example it points to the action (that we have yet to create) that will reside in action.xml under the logical name "logon".

The text tag renders an HTML <input> element of type "text". In this case the number of character positions to occupy on the browser’s screen has been specified as well. When this page is executed, the current value of the username property of the corresponding bean is the value returned by getUsername().

The password tag is used in a similar fashion. The difference is that the browser echoes asterisk characters instead of the input value as the user types the password.

Struts defines HTML tags for all the input fields that are shown Table 1.

To copy Struts files to your project, press the right-mouse button on your WAR (logonAll) and choose New Folder. Name it Web-Inf and create two new folders under it: classes and lib. Import (use RMB on the folder and click on Add File…) the file C:\jakarta-struts-1.0\lib\struts.jar into the lib folder, then import the tag library descriptor. A TLD is an XML document that describes a tag library. It contains information about the library and about each tag contained in the library. TLDs are used by a Web container to validate the tags and by JSP page development tools. Place the file C:\jakarta-struts-1.0\lib\struts-form.tld into the Web-Inf folder.

Tip: Enable Show All Files on the logonAll WAR target to see the JAR file (see Figure 2).

The Form Bean
Most Web developers build forms using the standard capabilities of HTML, such as the <input> tag. Users now expect interactive applications to have certain behaviors, and one of these expectations relates to error handling – if users make an error, the application should allow them to fix only what needs to be changed and not have to reenter any more information on the current page or form.

Fulfilling this expectation is tedious and cumbersome when coding with standard HTML and JSP pages. With Struts this can be done easily because of your form bean.

There’s a good example in the Struts documentation on how to handle errors during logins. We use our form bean only for storing the values entered by the form.

Create a new Java Classes Target (File —> New… from within Workspace View). Follow the wizard, entering the following information and accepting the default when nothing is specified:

  • Depending target on this target: check logonAll
  • Target name: logonClasses
Set the build options for target logonClasses (in a Web archive all classes have to reside in the Web-Inf/classes folder), (see Figure 3).

Add C:\jakarta-struts-1.0\lib\struts.jar to the Build Options Classpath (see Figure 4). Create a new Standard Class (RMB logonClasses Target —> New… from within Workspace View). Follow the wizard, entering in the following information and accepting the default when nothing is specified:

  • Package name: logon
  • Class name: LogonForm
  • Extends: ActionForm
Now change the source code for LogonForm.java (see Listing 1).

The Success and Failure Page (logon/success.jsp)
The Success page displays a simple message advising the user of a successful logon; the Failure page displays a simple message advising the user of a failed logon.

Create another JSP page in your logon JSP 1.2 component by clicking on logon JSP 1.2 component, choosing New…, and naming it success.jsp; then copy and paste the code into the page. Repeat these steps for the failure.jsp page. Now you should have generated all necessary files for the View (see Figure 5).

  • The Success Page (success.jsp)

    <%@ page language="java" %>
    <html>
    <head>
    <title>Successful Logon</title>
    </head>

    <body>

    You have successfully logged on.
    </body>
    </html>

  • The Failure Page (failure.jsp)

    <%@ page language="java" %>
    <html>
    <head>
    <title>Logon Failure</title>
    </head>

    <body>

    You have incorrectly logged on.
    </body>
    </html>

    Create the Model and the Controller
    Now that you understand how to construct the View components of your application, it’s time to focus on the Model and Controller components. Struts includes a servlet that implements the primary function of mapping a request URI to an Action class. Therefore, your primary responsibilities related to the Controller are to write an Action class (i.e., an extension of the Action class) for each logical request that may be received. Write the action mapping configuration file (in XML) used to configure the controller servlet. Update the Web application deployment descriptor file (in XML) so your application can include the necessary Struts components.

    Create the Action Class
    The goal of an Action class is to process this request and then to return an ActionForward object that identifies the JSP page (if any) to forward control to generate the corresponding response.

    Create a new Java Classes Target (RMB logonClasses Target —> New… from within Workspace View) in the logonClasses target:

    • Package name: logon
    • Class name: LogonAction
    • Extends: Action
    Now change the source code for LogonAction.java (see Listing 2).

    Create the Mapping File
    To operate successfully, the Struts controller servlet needs to know several things about how each request URI should be mapped to an appropriate Action class. The required knowledge has been encapsulated in a Java interface named ActionMapping, and the most important properties are:

    • Type: The fully qualified Java class name of the Action implementation class used by this mapping
    • Name: The name of the form bean defined in the config file that this action will use
    • Path: The request URI path that’s matched to select this mapping; (I’ll provide examples of how matching works later in the article)
    • Unknown: Set to true if this action is configured as the application’s default to handle all requests not handled by another action; only one action can be defined as a default within a single application
    • Validate: Set to true if the validate() method of the action associated with this mapping should be called
    Now we have to create an XML file called struts-config.xml to be placed into the Web-Inf folder.

    Create a new Any CodeFile (RMB Web-Inf folder —> New… from within Workspace View) in the logonAll target (see Listing 3).

    First the form bean is defined. A basic bean of logon.LogonForm class is mapped to the logical name "logonForm". This name is used as a session or request attribute name for the form bean.

    The "global-forwards" section is used to create logical name mappings for commonly used JSP pages. Each of these forwards is available through a call to your action mapping instance: actionMappingInstance.findForward("logicalName").

    There is a mapping that matches the path /logon (because the example application uses extension mapping, the request URI you specify in a JSP page would end in /logon.do). When a request matching this path is received, an instance of the LogonAction class is created (the first time only) and used. The controller servlet will look for a session-scoped bean under key logonForm, creating and saving a bean of the specified class if needed.

    The forward elements are used to take the appropriate action after verifying the username and password.

    The Deployment Descriptor
    A deployment descriptor is an XML text-based file with an .xml extension that describes a component’s deployment settings.

    First we configure the tag library on the target logonAll (see Figure 6). We have to add the Struts-Controller Servlet to the deployment descriptor, which you can find in your struts.jar file. Within PowerJ you can’t edit the web.xml file directly, but PowerJ merges all XML files with the same DTD into the web.xml for deployment.

    We have to create a file called myweb.xml, which must be placed into the Web-Inf folder. Create a new Any CodeFile (RMB Web-Inf folder —> New… from within Workspace View) in the logonAll target (see Listing 4).

    Deploy and Test Your Application
    Enter the same username and a password into http://localhost:8080/struts-login/logon.jsp and see how your success.jsp page is fired. If you enter different values, you’ll see your failure.jsp file.

    Resources

  • More Stories By Berndt Hamboeck

    Berndt Hamboeck is a senior consultant for BHITCON (www.bhitcon.net). He's a CSI, SCAPC8, EASAC, SCJP2, and started his Sybase development using PB5. You can reach him under [email protected]

    Comments (0)

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.