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.
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:
-
Actionbeans -
ActionServlet -
ActionFormbeans and custom tags.
Figure 1. MVC and the 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
ActionFormsubclass. - 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:
- Go to the Window Start menu.
- 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:
- Select New => Projects => Enterprise Application Project .
- Choose Create 1.3 J2EE Enterprise Application Project . Press Next .
- Uncheck all three subprojects: Application Client project, EJB project, and Web project.
-
Enter
StrutsEARfor the project name. - Click Finish .
Create a Web project and add Struts support:
- Select New => Projects => Web => Web Project .
-
Enter
StrutsSampleWebfor the Web project. - Select the Add Struts support checkbox. Click Next .
- Select Existing Enterprise Application Project.
- Browse for the newly created EAR project. Click Next twice.
-
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
ActionFormis 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.HashMapor other Collection types are supported. This is discussed later in the article . - Click Finish .
Figure 2. Overriding default settings in a Web project creation Wizard
Examine the Struts file structure in Figure 3.
Figure 3. Web project with Struts support
You will modify the following files later:
-
ApplicationResources.propertiesis the resource bundle for the Struts application. Locale specific and error messages are placed in this properties file. -
struts-config.xmlis the xml configuration file for Struts. WebSphere Studio provides a GUI editor for this file.
For now:
-
Examine the
web.xmlfile. - Expand the StrutsSampleWeb project and double click on Web Deployment Descriptor to open to the editor.
- 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:
- Expand the StrutsSampleWeb project until you see the /Web Content folder. Right click on /Web Content .
- Select New => JSP File .
-
Enter
submitpage.jspin the Name . - Choose Struts JSP as the Model from the dropdown box.
- 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 .
- Click Finish .
Figure 4. 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:
- Right click on /Web Content .
- Select New => JSP File .
-
Enter
confirm.jspin the Name field. - 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.
- In the Web Perspective, right click on the /Java Source folder under the StrutsSampleWeb project.
-
Select
New => Other => Web
. Expand
Web => Struts
. Select
ActionForm Class
and click
Next
Figure 5. Starting the Struts ActionForm Class Wizard
. -
Enter
com.ibm.sample.strutsas the Java Package name. -
Enter
SubmitFormas the class Name . Click Next . -
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
. - Click Next .
-
Change
customer.nameto customer (without the quotes) and change its type to Customer . -
Change
topping(Pepperoni)to toppings (note the plural) and its type to java.util.HashMap . -
Change
String[]to String type.
Figure 7. Modifying the accessors
-
Add
namewith the String type. -
Add
addresswith the String type. -
Click
Next
. The
ActionServletuses the struts-config.xml file to determine whichActionclass and its associatedActionFormclass to forward the control. This page automatically defines thesubmitForm ActionFormbean in the Struts configuration xml file.
Figure 8. Configuring the mapping for ActionForm in struts-config.xml
- 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
:
- In the Web Perspective, right click on /Java Source folder under the Web project.
- Select New => Class .
-
Enter or browse
com.ibm.sample.strutsas the Package name. -
Enter
Customeras the class Name . - Click Finish .
- 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:
- In the Web Perspective, right click on the /Java Source folder under the Web project.
- Select New => Other => Web => Struts => Action Class .
-
Enter
com.ibm.sample.strutsas the Package name. -
Enter
SubmitActionas the class Name. Press Next . -
In the Forwards section, press
Add
to add a forwards with the
Name
successwith/confirm.jspas the Path. - Choose submitForm as the Form Bean Name.
- Choose session as the Form Bean Scope.
- Click Finish .
Figure 9. 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);
}
}
|
At this point, you have completed the example and you can run it. To run the submitpage.jsp in a WebSphere Test Environment V5:
- Right click on submitpage.jsp => Run on Server .
- Make sure the WebSphere Test Environment v5 Server is selected. Press OK .
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:
- Open the struts-config.xml file in the editor. This file is located in the /Web Content folder.
-
The
Actionand theActionFormbean 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. -
In the Actions page of the struts-config.xml editor, select
/submit
and enter
/submitpage.jspin 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
Graphical representation of Struts application
WebSphere Studio allows you to create Web diagram to represent a Struts application graphically.
- In the Web Perspective, right click on /Java Source folder under the Web project.
- Select File => New => Other => Web => Struts => Web Diagram .
-
Enter
submitDiagramas the File name . -
Press
Finish
. A file named
submitDiagram.gpgis created under the /Java Source folder. - Go to the Web Structure view. This view is on the same stack as the Outline view.
- Expand on <default module> => Actions => /submit .
- Drag the icon with /submit onto the diagram.
- Right click on the icon on the diagram => Draw => Draw All From .
- 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 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.
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 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.




