IBM WebSphere Developer Technical Journal: Writing a Simple Struts Application using WebSphere Studio V5

This article describes how to create a simple Struts example using the built-in support in WebSphere Studio Application Developer 5.0.

Colin Yu, WebSphere Studio Application Developer Support Team, IBM Canada Toronto Lab

Colin Yu is a technical designer on the WebSphere Business Scenarios team at the IBM Toronto Lab. Colin received a Bachelor of Engineering degree in 1995 and a Master of Applied Science degree from the University of Waterloo, Ontario in 2000. Colin is an IBM Certified Enterprise Developer and Systems Expert on WebSphere Application Server, and an IBM Certified Solution Developer on WebSphere Studio Application Developer and VisualAge for Java. You can reach Colin at coliny@ca.ibm.com.



Jane Fung, WebSphere Studio Application Developer Technical Support Team , IBM Software Solutions Toronto Lab, Canada., 2003

Jane Fung works with the WebSphere Studio Application Developer Technical Support Team at the IBM Software Solutions Toronto Lab, Canada. You can reach Jane at jcyfung@ca.ibm.com.



10 February 2003

Introduction

Struts is an open source framework sponsored by the Apache Software Foundation. You can use it to maintain and expand Web applications. IBM ® WebSphere® Studio Application Developer Version 5.0 (hereafter called WebSphere Studio) has built-in Struts support for Struts 1.02 and 1.1 (beta 2). The Struts Configuration editor in WebSphere Studio allows easy modifications of the struts-config.xml file. This article describes how to create a Struts example using the built-in support in WebSphere Studio.


Struts

The Struts framework is written entirely in Java using standard J2EE APIs. In addition, it uses several well-known J2EE design patterns, such as Model-view-controller and FrontController.

Model-view-controller (MVC)

Model-view-controller (MVC) is a design pattern that defines a clear separation between the following three application tiers:

  • The model is the set of data and business rules for the application. This is commonly called the application's business logic.
  • The view is the application's user interface.
  • The controller defines the way that an application interacts with user input and the model. This is called the application logic.

By promoting a clear separation between tiers, MVC allows loose coupling between components that comprise each tier. This allows more flexibility and code reuse. For example, if you develop several user interfaces for one application, you need to develop the view component because of the loosely coupled application tiers.

The Struts framework is the View and Controller components of MVC. The following shows how Struts maps to the MVC framework. Struts has three major components:

  • Action beans
  • ActionServlet
  • ActionForm beans and custom tags.
Figure 1. MVC and the Struts framework
MVC and Struts framework

Action beans and ActionServlet
Struts provides a single ActionServlet ( org.apache.struts.action.ActionServlet ) to handle all browser requests. This type of framework is called the FrontController pattern. Each browser request is handled by the Struts Action subclass (subclass of org.apache.struts.action.Action ). Each browser request is mapped to an Action subclass in the struts-config.xml file. The ActionServlet loads the mapping during initialization. To configure the Web project to pass all browser requests to the ActionServlet , map all URIs that end with .do (for example, *.do) to the ActionServlet in the Web deployment descriptor. You can then provide the actual Action subclass mappings in the Struts configuration file for individual request URI, such as /submit.do.

ActionForm beans
Browser requests can come with parameters. When a user submits a HTML form, the Struts framework encloses the parameters in an org.apache.struts.action.ActionForm bean. You can also use the ActionForm bean to pre-populate a form with default values that are obtained from database or other backend systems. If the user enters incorrect values in the form, the ActionForm may perform validations. You can re-display the form with the previous input.

Custom tags
Struts provides a large set of JSP custom tags that support the ActionForm beans. The custom tags support:

  • Pre-population of a HTML form with values taken from an ActionForm subclass.
  • Internationalization, such as providing text that is determined by the user's locale.
  • Logic, such as showing a different title for a page based on how it is used.

Struts is a versatile framework that you can easily use with WebSphere Studio. Let's start our first Struts example.


Writing a simple Struts application

Prerequisites

Start WebSphere Studio Version 5.0:

  1. Go to the Window Start menu.
  2. Select Programs => IBM WebSphere Studio => Application Developer 5.0.

Step 1: Starting a new Struts Web Project

Create a 1.3 EAR project without the EJB / Client or Web:

  1. Select New => Projects => Enterprise Application Project .
  2. Choose Create 1.3 J2EE Enterprise Application Project . Press Next .
  3. Uncheck all three subprojects: Application Client project, EJB project, and Web project.
  4. Enter StrutsEAR for the project name.
  5. Click Finish .

Create a Web project and add Struts support:

  1. Select New => Projects => Web => Web Project .
  2. Enter StrutsSampleWeb for the Web project.
  3. Select the Add Struts support checkbox. Click Next .
  4. Select Existing Enterprise Application Project.
  5. Browse for the newly created EAR project. Click Next twice.
  6. In the Struts Setting page, Select Override default settings and choose 1.1 (beta 2) in the drop down box as shown in Figure 2. As mentioned earlier, the Struts ActionForm is automatically populated with the HTML form data when the form is submitted. In Struts 1.0.1, only simple Java types are supported. However, in Struts 1.1 (beta 2), java.util.HashMap or other Collection types are supported. This is discussed later in the article .
  7. Click Finish .
Figure 2. Overriding default settings in a Web project creation Wizard
Overriding default ssettings in a Web project creation Wizard

Examine the Struts file structure in Figure 3.

Figure 3. Web project with Struts support
Web project with Struts support

You will modify the following files later:

  • ApplicationResources.properties is the resource bundle for the Struts application. Locale specific and error messages are placed in this properties file.
  • struts-config.xml is the xml configuration file for Struts. WebSphere Studio provides a GUI editor for this file.

For now:

  1. Examine the web.xml file.
  2. Expand the StrutsSampleWeb project and double click on Web Deployment Descriptor to open to the editor.
  3. Go to the Servlets page. Note the following:

Note that in the Initialization section, validate is set to true. The ActionServlet uses the XML parser to validate and process the configuration file. It has nothing to do with the form validation that you will see later in this article .

How does *.do get to the correct Action class?

As mentioned earlier, the ActionServlet and the Action class are the core of the Controller tier in the MVC model. The controller is responsible to process user requests, route requests to business logic, and select the view to respond to users (see Struts User Guide, section 4.4 ). When the form submits to submit.do , the Struts ActionServlet selects the correct Action class to use based on the <action-mapping> in the struts-config.xml file.

The Struts Action subclass is responsible to process the user data. In the example, create a Struts Action subclass called SubmitAction . It consists of actions, such as reading and processing form data. Each form is associated with an instance of the Struts ActionForm subclass. Create this form class that extends the ActionForm class. SubmitForm, which is a subclass of ActionForm , is created with getters and setters of the fields. Getters and setters are mandatory in ActionForm subclasses.

How does the SubmitForm come into play?

Every Struts Action class must associate with a Struts ActionForm class. You can define the SubmitForm class in the FormBean page of the struts-config.xml editor in WebSphere Studio. You can then associate it with the SubmitAction mapping in the struts-config.xml file. When a request is submitted, the ActionServlet automatically populates the SubmitForm with the data from the actual form on the Web browser. In the SubmitAction class, use SubmitForm f = (SubmitForm) form to access the form's data.

Step 2: Building a JSP form using Struts taglib

Struts provides a number of HTML tags for input fields and hyperlinks for the JSP form. Here is a list of the common ones:

  • Checkboxes - <html:checkbox property="name"/>
  • Hidden fields - <html:hidden property="name"/>
  • Password input fields - <html:password property="name"/>
  • Radio buttons - <html:radio property="name"/>
  • Reset buttons - <html:reset/>
  • Options (drop down box)
  • Submit buttons - <html:submit/>
  • Text input fields - <html:text property="name"/>
  • Textarea input fields - <html:textarea property="name"/>

In most of the HTML tags, Javascript events are supported, such as onmouseclick, onmouseover, and so on. For more information, see HTML Bean API .

Let's create a JSP page for this example. In the Web Perspective, create a JSP page with Struts model:

  1. Expand the StrutsSampleWeb project until you see the /Web Content folder. Right click on /Web Content .
  2. Select New => JSP File .
  3. Enter submitpage.jsp in the Name .
  4. Choose Struts JSP as the Model from the dropdown box.
  5. Click Next and notice that only the taglib for HTML and Bean are added. If you want to use the taglib from the other tag libraries, such as the Logic taglib, select Add Tag Libraries and choose /WEB-INF/struts-logic.tld .
  6. Click Finish .
Figure 4. JSP creation wizard - Struts Tag Libraries
JSP creation wizard - Struts Tag Libraries

Modify the submitpage.jsp page with the following code in the source editor and save it:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

<html:html locale="true">

<HEAD>
<%@ page
language="java"
contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"
%>
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="IBM WebSphere Studio">
<META http-equiv="Content-Style-Type" content="text/css">
<LINK href="theme/Master.css" rel="stylesheet"
	type="text/css">


<TITLE>Pizza Order Page</TITLE>
</HEAD>

<BODY>
	<P><h1>Pizza Order Page </h1></P>

		<html:form action="/submit.do">

		Name: <html:text property="customer.name"/><br>
		Address: <html:text property="customer.address"/><br>

                Size: <html:radio property ="size" value="S"/>Small
		<html:radio property ="size" value="M"/>Medium
		<html:radio property ="size" value="L"/>Large

		Toppings: <br>
		Pepperoni<html:checkbox property="topping(Pepperoni)"/><br>
		Onion<html:checkbox property="topping(Onion)"/><br>
		Mushroom<html:checkbox property="topping(Mushroom)"/><br>
		Hot Pepper<html:checkbox property="topping(Hot Pepper)"/><br>
		Bacon<html:checkbox property="topping(Bacon)"/><br>

		<html:select property ="type">
		<html:option value="a">Delivery</html:option>
		<html:option value="b">Pickup</html:option>
		</html:select>

				<html:submit/>
				<html:reset/>
		</html:form>
</BODY>
</html:html>

Ignore the warning message in the task list about submit.do not existing. Create a /confirm.jsp page for the Struts Action class for forwarding.

In the Web Perspective, create the confirm.jsp page:

  1. Right click on /Web Content .
  2. Select New => JSP File .
  3. Enter confirm.jsp in the Name field.
  4. Click Finish .

Modify the JSP file with the following code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<html:html>
<HEAD>
<%@ page
language="java"
contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"
%>
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="IBM WebSphere Studio">
<META http-equiv="Content-Style-Type" content="text/css">
<LINK href="theme/Master.css" rel="stylesheet"
	type="text/css">
<TITLE></TITLE>
</HEAD>

<BODY>
<P>Thank you <%=request.getAttribute("name")%></P>
</BODY>
</html:html>

In the submitpage.jsp, the customer.name property refers / to a field inside an object. topping(Pepperoni) property is a key/value pair of java.util.HashMap . Nested properties are supported by the Struts 1.1 (beta 2) HTML taglib.

Step 3: Creating an Struts ActionForm SubmitForm class

You must define a subclass that extends the Struts ActionForm class. It must have setters and getters for all the form fields. As mentioned earlier, the ActionForm class is pre-populated with form data when the form is submitted. The ActionForm class may optionally have a validation method and a reset method for validating the form input, and resetting the form, respectively. They are discussed later in the article .

If your application has a form that spans across multiple Web pages, use only one ActionForm . Define a single ActionForm bean that contains properties for all the fields, no matter which page the field is actually displayed on. Likewise, submit the various pages of the same form to the same Action class. Using this design, the Web site designer can rearrange fields without changes to the business logic.

Create a Java class that extends org.apache.struts.action.ActionForm in the /Java Source folder under the Web Project.

  1. In the Web Perspective, right click on the /Java Source folder under the StrutsSampleWeb project.
  2. Select New => Other => Web . Expand Web => Struts . Select ActionForm Class and click Next
    Figure 5. Starting the Struts ActionForm Class Wizard
    Starting the Struts ActionForm Class Wizard
    .
  3. Enter com.ibm.sample.struts as the Java Package name.
  4. Enter SubmitForm as the class Name . Click Next .
  5. This page allows you to select the fields that you want for setters and getters. Expand the tree as shown in Figure 6. Select these items: customer.name, size, topping(Pepperoni) and type
    Figure 6. Selecting new accessors (getters and setters) for the HTML form
    Selecting new accessors for the HTML form
    .
  6. Click Next .
  7. Change customer.name to customer (without the quotes) and change its type to Customer .
  8. Change topping(Pepperoni) to toppings (note the plural) and its type to java.util.HashMap .
  9. Change String[] to String type.
    Figure 7. Modifying the accessors
    Modifying the accessors
  10. Add name with the String type.
  11. Add address with the String type.
  12. Click Next . The ActionServlet uses the struts-config.xml file to determine which Action class and its associated ActionForm class to forward the control. This page automatically defines the submitForm ActionForm bean in the Struts configuration xml file.
    Figure 8. Configuring the mapping for ActionForm in struts-config.xml
    Configuring the mapping for ActionForm in struts-config.xml
  13. Click Finish .

The ActionForm contains all the fields that are in the form, and each must have a getter and a setter. You need to manually change the implementation of the getters and setters of the Customer object and the toppings HashMap. Modify the code in bold in the SubmitForm you just created as follows:

package com.ibm.sample.struts;

import java.util.HashMap;

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 class SubmitForm extends ActionForm {
	private Customer customer = new Customer();
	private String size = null;
	private java.util.HashMap toppings = new java.util.HashMap();
	private String type = null;
        private String name = null;
	private String address = null;

	public String getSize() {
		return size;
	}
	public HashMap getToppings() {
		return toppings;
	}
	public void setSize(String size) {
		this.size = size;
	}
	public void setToppings(HashMap toppings) {
		this.toppings = toppings;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public Customer getCustomer() {
		return customer;
	}
	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
	public String getAddress() {
		return customer.getAddress();
	}
	public String getName() {
		return customer.getName();
	}
	public void setAddress(String address) {
		customer.setAddress(address);
	}
	public void setName(String name) {
		customer.setName(name);
	}
	public void setTopping(String key, Object value) {  //*new* method
       	        toppings.put(key, value);
	}
	public Object getTopping(String key) {  //*new* method
		return toppings.get(key);
	}
	public void reset(ActionMapping mapping, HttpServletRequest request) {
		this.customer = new Customer();
		name = new String();
		address = new String();
		size = new String();
		toppings.clear();
		type = new String();

Because the SubmitForm uses the Customer bean, create a java class called Customer under the package com.ibm.sample.struts :

  1. In the Web Perspective, right click on /Java Source folder under the Web project.
  2. Select New => Class .
  3. Enter or browse com.ibm.sample.struts as the Package name.
  4. Enter Customer as the class Name .
  5. Click Finish .
  6. Enter the following code for the class:
package com.ibm.sample.struts;

public class Customer {

	private String name;
	private String address;

	public String getAddress() {
		return address;
	}
	public String getName() {
		return name;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public void setName(String name) {
		this.name = name;
	}
}

To map an input text field from the form to the name field of the customer object, use <html:text property="customer.name"/> in the HTML tag. To access the key/value pair of a HashMap or any Collections, use property="toppings(key)" in the HTML tag, where toppings are the HashMap name in the example. Note: Only Struts 1.1 (beta 2) supports the usage of HashMap or other Collections properties.

When the reset button is pressed, the reset() method is called.

Step 4: Creating an Action SubmitAction class

The Struts Action class is the application logic. It makes JDBC calls, invokes other business beans, invokes EJBs, and so on. It is recommended to separate the business logic from the other beans than to have it embedded in this Action class. This class calls beans that have the business logic. You should implement the execute() method. It returns an ActionForward object that identifies the next page, such as a JSP page.

public ActionForward execute (ActionMapping mapping, ActionForm form, 
                              HttpServletRequest request, HttpServletResponse response)

The execute() method has access to the form data that you can use. Because all requests are routed to one instance of your Action class, make sure your code can operate correctly in a multi-threaded environment. When returning an ActionForward that identifies a JSP page, define a logical name for the JSP page in the struts-config.xml editor. For example, define the name success for /confirm.jsp . In the execute() method, the line return (mapping.findForward("success")); forwards the control to the /confirm.jsp page.

Create an Action class named SubmitAction under the /Java Source folder:

  1. In the Web Perspective, right click on the /Java Source folder under the Web project.
  2. Select New => Other => Web => Struts => Action Class .
  3. Enter com.ibm.sample.struts as the Package name.
  4. Enter SubmitAction as the class Name. Press Next .
  5. In the Forwards section, press Add to add a forwards with the Namesuccess with /confirm.jsp as the Path.
  6. Choose submitForm as the Form Bean Name.
  7. Choose session as the Form Bean Scope.
  8. Click Finish .
Figure 9. Create Action Class Wizard
Create Action Class Wizard

Enter the following code in the SubmitAction class:

package com.ibm.sample.struts;

import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import org.apache.struts.action.Action; 
import org.apache.struts.action.ActionError; 
import org.apache.struts.action.ActionErrors; 
import org.apache.struts.action.ActionForm; 
import org.apache.struts.action.ActionForward; 
import org.apache.struts.action.ActionMapping;

/** 
 * @version 1.0 
 * @author 
 */ 
public class SubmitAction extends Action {

          /** 
          * Constructor 
          */ public SubmitAction() {

               super();

} 
public ActionForward execute( 
     ActionMapping mapping,
     ActionForm form, 
     HttpServletRequest request,
     HttpServletResponse response) 
     throws Exception {

     ActionErrors errors = new ActionErrors(); 
     ActionForward forward = new ActionForward(); 
     // return value
     SubmitForm submitForm = (SubmitForm) form;

     try {

          // Getting the value from the form 
          String name = submitForm.getCustomer().getName();
          System.out.println ("The name is: " + name);
          request.setAttribute("name",name);

     } catch (Exception e) {

               // Report the error using the appropriate name and ID.
               errors.add("name", new ActionError("id"));

     }

     // If a message is required, save the specified key(s)
     // into the request for use by the <struts:errors> tag.

     if (!errors.empty()) { 
          saveErrors(request, errors); 
      }
     // Write logic determining how the user should be forwarded.   
     forward = mapping.findForward("success");

     // Finish with 
     return (forward);

   } 
}

Step 5: Running the sample

At this point, you have completed the example and you can run it. To run the submitpage.jsp in a WebSphere Test Environment V5:

  1. Right click on submitpage.jsp => Run on Server .
  2. Make sure the WebSphere Test Environment v5 Server is selected. Press OK .

Step 6: Validation

You can validate in the Struts ActionForm . When a form is submitted, the validate() method in the SubmitForm is implemented. Add the following validate() method to the SubmitForm :

public ActionErrors validate(
	ActionMapping mapping,
	HttpServletRequest request) {

	ActionErrors errors = new ActionErrors();

	if ((customer.getName()==null)|| (customer.getName().equals(""))) {
		// if the name is empty --> errors
			errors.add("Name", new ActionError ("error.customer.name"));
					System.out.println("errors....");
	}
	return errors;
}

After saving the SubmitForm class, notice that the ActionError compilation errors are not resolved. Right click on ActionError => Source => Organize imports.

The error.customer.name property is obtained from the resource bundle. Open ApplicationResources.properties from the /Java Source folder into an editor. Add the following lines to the properties file:

# Optional header and footer for <errors/> tag.
title=Pizza Store
errors.header=<hr><h3>Errors</h3><ul>
errors.footer=</ul><hr>
error.customer.name=<li>Name is empty

When the errors are displayed in the JSP page, it is enclosed with <hr><h3>Errors</h3><ul> and </ul>. You must define the header and footer for the error messages using errors.header and errors.footer. When errors are detected, they are returned to the form with input values preserved.

You need to add the <html:errors/> line in the JSP file so that the errors show up. In the submitpage.jsp file, enter the line <html:errors/> at the beginning of the file, right before the <html:form>.

Modify the /input field in the struts-config.xml editor:

  1. Open the struts-config.xml file in the editor. This file is located in the /Web Content folder.
  2. The Action and the ActionForm bean are configured by the Struts creation wizards, except for the input field in the Actions page. This field is necessary for the validation to work properly.
  3. In the Actions page of the struts-config.xml editor, select /submit and enter /submitpage.jsp in the Input field. Save the changes.

You can place error messages and other messages in the ApplicationResources.properties file. For example, you can use <bean:message key="title"/> to display the title in the JSP, where the content is obtained from the resource bundle.

The resource bundle also supports internationalization (i18n - there are 18 characters between i and n ). You can create ApplicationResources_xx.properties for other languages whose ISO language code is xx.

Running the sample again with validation

Since we made changes to the Web project, let's restart the server and try the sample again. To restart the server, go to the server view, right click and select Restart .

If you leave the name empty after you submit, it returns to the form page with the error message listed in the properties file.

Figure 10. Running the sample with validation
Running the sample with validation

Graphical representation of Struts application

WebSphere Studio allows you to create Web diagram to represent a Struts application graphically.

  1. In the Web Perspective, right click on /Java Source folder under the Web project.
  2. Select File => New => Other => Web => Struts => Web Diagram .
  3. Enter submitDiagram as the File name .
  4. Press Finish . A file named submitDiagram.gpg is created under the /Java Source folder.
  5. Go to the Web Structure view. This view is on the same stack as the Outline view.
  6. Expand on <default module> => Actions => /submit .
  7. Drag the icon with /submit onto the diagram.
  8. Right click on the icon on the diagram => Draw => Draw All From .
  9. Double click on the icons to go to the editor. For example, double clicking on the /submit icon brings you to the struts-config.xml editor.
Figure 11. Struts Web diagram
Struts Web diagram

Conclusion

Struts is a powerful framework that encourages flexibility and detached coupling between three application tiers. Using Struts in your application simplifies future maintenance and allows the Web site to expand easily. WebSphere Studio Version 5.0 provides an easy-to-use Struts plug-in to help you maintain and expand your Web sites.

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=13356
ArticleTitle=IBM WebSphere Developer Technical Journal: Writing a Simple Struts Application using WebSphere Studio V5
publish-date=02102003