[ Team LiB ] Previous Section Next Section

Back End Programming Using the Struts Framework

The brunt (if not all) of the Java programming when using the Struts guidelines happens in the back end. In this case, back end means outside of the presentation layer JSPs or servlets. This section covers the necessary objects required for a basic Struts application to run, starting with the action classes used for the business logic and continuing through the objects and methods used by the action class. This section also covers the ActionForm and its related classes, including error handling.

Action Classes

After the configuration of the web.xml and struts-config.xml files is complete, attention turns to the actual Java coding of the application. The first step is to write an action class that extends org.apache.struts.action.Action and to override the execute method. The execute method is called every time the action class is called. Remember that the action class is mapped to a path within the <action> tag in struts-config.xml. The following is a skeleton of an action class:


import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import javax.servlet.*;
import javax.servlet.http.*;

public class LoginExec extends Action {

public ActionForward
       execute(ActionMapping mapping,
               ActionForm form,
               HttpServletRequest request,
               HttpServletResponse response) throws Exception {
//Code inserted here
}
}//end of LoginExec

Four parameters are passed in to the execute method: ActionMapping, ActionForm, HttpServletRequest, and HttpServletResponse. The first two are special classes used by Struts to link the Struts application to the mappings and also to validate that form data is correct. The latter two are the same classes that are passed in during servlet and JSP programming and contain the input (HttpServletRequest) and output (HttpServletResponse) of the servlet. The method returns an ActionForward object that tells the Struts application to redirect or forward the servlet based on actions within the execute method. Let's now explore these Struts classes further.

Using the ActionMapping Class

The ActionMapping class encapsulates the struts-config.xml file for the specific action path called. This link enables the programmer to specify which of the <forward/> tags to use. Using the following example from the struts-config.xml file within the action named login,


<forward name="listorder" path="/orderlistentry.do"/>

the mapping class can be used to forward to another action called orderlistentry. Using the name parameter in the preceding line, we can call this directly using the findFoward() method:


return mapping.findForward("listorder");

To return to the original input page, which would be used to display new information such as an error, we can use the getInputForward() method as shown here:


return mapping.getInputFoward();

The ActionMapping class ties the action mappings to the action servlet and is a crucial part of making Struts work within your Web application.

Using the ActionForm Class

The purpose of the ActionForm class is to validate or change information being sent from the JSP page. An action form class is linked to the action in struts-config.xml in several places. First, it's defined with the <form-bean> tag:


<form-bean      name="login"
                type="myApp.FormBeans.LoginForm"/>

Then, within the <action> tag, the name parameter links this particular ActionForm to the action class and the scope parameter sets the persistence of the bean:


<action
          name="login"
          scope="session"
          >

If the properties in the JSP are set up correctly, the action class will contain all the values input by the user.

To write a new ActionForm class, first extend the Struts ActionForm and create the properties you want set. The following is a sample definition of an ActionForm class:


package myApp.FormBeans;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;

public final class LoginForm extends ActionForm {
     // password.
    private String password = null;

     //The customerno.
    private String customerNo = null;
//More Methods
}

Then create set and get methods on these properties. The name after the set and get must match those properties in the Struts JSP pages where they are used. For example, if password is used on the JSP page, setPassword(String p) and getPassword() are used:


...
public String getPassword() {
       return this.password;
  }
public void setPassword(String p){
            this.password = p;
  }
public String getCustomerNo(){
       return this.customerNo;
  }
public void setCustomerNo(String c){
       this.customerNo = c;
  }

After the properties from the page are set up, the reset() method should be overridden to reset all the data back to its original state. The following code example shows this being done:


public void reset(ActionMapping mapping, HttpServletRequest request) {

        this.password = null;
        this.customerNo = null;
}

Optionally, the validate method can be overridden to check the input that has been set from the HttpServletRequest. This can be done automatically if the validate attribute inside the <action> parameter within the struts-config.xml file is set to true. If the validation contains errors, the original page will be redisplayed with the errors. This method can return either null or an empty ActionErrors object when there are no errors. In these cases, Struts will forward to the page specified in the action. The default method returns null. The following code shows an example of a validate method:


public ActionErrors validate(ActionMapping mapping,
                                 HttpServletRequest request) {
        ActionErrors errors = new ActionErrors();
        if ((customerNo == null) || (customerNo.length() < 1))
          errors.add("customerNo", new ActionError("error.customerno.required"));
        if ((password == null) || (password.length() < 1))
            errors.add("password", new ActionError("error.password.required"));
        return errors;
    }

The validate() method is a powerful tool in error validation. The method returns ActionErrors, which is a standard format for all errors in Struts.

Programming Struts Errors

Error handling is one of the most cumbersome and time-consuming activity performed by programmers. The Struts framework provides a standard way of handling errors within the entire application and displaying them to the front-end JSP screen. This is done through the ActionErrors and ActionError classes.

The ActionErrors class keeps all the Struts errors and organizes them based on a key name. This allows Struts to save multiple errors for each key for display later on the JSP page. An ActionErrors.add() method is used to add an error to the application, which is done by passing the add method a String key value and an ActionError. The ActionError class represents one error and the text associated with it. The associated text is usually stored in the resource properties file that's configured in the application parameter of the Struts servlet registration in the web.xml file. This allows for standard Java internationalization. The following is an example of creating an ActionErrors holder and adding a new ActionError to it:


ActionErrors errors = new ActionErrors();
        errors.add("result", new ActionError("error.invalid.login"));

The preceding example corresponds to this property:


error.invalid.login = An invalid username or password was entered.

The error message could contain data. It's possible to insert custom text in regions of a text message by adding special placeholders in the actual text of the application properties file. Given the line


error.invalid.login = {0} was entered and it is invalid

A new ActionError with replacement text would look like this:


new ActionError("error.invalid.login", "Garbage");

The associated error would then replace the {0} character with the text Garbage.

The ActionError object has constructors with zero and up to four parameters. If you need more than that, or a different object type rather than String is needed, you can use the following constructor to allow unlimited text replacement with objects:


ActionError(String key, Object [] params);

NOTE

The parameters in the object array of the ActionError constructor do not have to be Strings. They can be the wrapper class of any basic type using the same conventions as the MessageFormat class: http://java.sun.com/j2se/1.4.1/docs/api/java/text/MessageFormat.html.


The following example uses first an Integer value and then a date:


ActionError("dateError", new Object[new Integer(2)]

Within the action class, after errors are created, they must be saved for display in the forwarding page. This is done by using the action.saveErrors() method. This saves the errors to the application and allows the JSP's screens to capture the error.


super.saveErrors(request, errors);

The error capabilities built into Struts enable programmers to handle errors in a standard way, which saves time when developing without standard error catching.

Database Connectivity

Struts also allows database connections to be stored. Within the action class, a protected field named servlet is an ActionServlet. The method findDataSource() is used to retrieve the data source from the struts-config.xml file. The parameter represents the key attribute from the <datasource> tag. If you specify null for this, the default connection is retrieved. The following sample code opens a connection based on the myDatabase entry in struts-config.xml:


try {
   javax.sql.DataSource dataSource =
     servlet.findDataSource("myDatabase");
   java.sql.Connection myConn =
     dataSource.getConnection();

   //do what you wish with myConnection
 } catch (SQLException sqle) {
   ...
 } finally {

   //always close connection
   try {
     myConn.close();
   } catch (SQLException e) {
   }
 }

NOTE

Note that Struts provides data sources, but not pooling, load balancing, or failover of database connections. Refer to Chapter 10, "Managing Database Connectivity Using JDBC," for more information about WebLogic Server data sources.


This section has dealt with the backend programming needed for Struts-based applications. Action classes are written to perform the functionality. Helper classes such as ActionForm and ActionMapping are used to perform valuable Struts-related activities, such as auto validation and forwarding to the new page or action servlet for display. Errors are stored within the ActionErrors class for later use, and database connections can be stored locally and accessed when needed. All the backend features are then tied into the struts-config.xml file for ease of configuration.

    [ Team LiB ] Previous Section Next Section