STRUTS: A Mature MVC Framework for Web Applications

Russell Giebelhaus
Edmonton Java Users Group October 16, 2002

This presentation will
Describe the Model 2 MVC pattern Demonstrate how Struts works. Show the main features of the Struts1.1-Beta2 release. Explore how implementing Struts affects
• Development effort • Future site maintenance.


What Struts is not…
A portal or multi-channel server It does not provide:
Security Access Control Individual tailored custom views Data access Using Struts does not hinder implementing these features.

So, what is Struts?
Open-Source Jakarta project Started in 2000 by Craig McClanahan Currently at Version 1.1 – Beta 2 Implementation of the Model 2 – MVC Architecture


The MVC Pattern
MVC Pattern history
In the beginning – JSPs MVC Model 1 MVC Model 2 Pattern
• The motivation for the Struts Framework


In The Beginning - JSPs
<html><head> <title>Add user</title> </head><body> <% String error = ""; String user = request.getParameter("userName")) //is there user data from form submission if (user != null) { //...access the database and add user //...catch any errors } //check for errors if (error.length() == 0) { %> <!-- redirect to index page --> <jsp:forward page="index.jsp" /> <% } <font color=red><%=error%></font><br> <h3>Enter username to add:</h3> <form action="form.jsp"> <input type="text" name="userName" value=<%=user%></input> <input type="submit" value="Submit"> </form> </body></html>

In The Beginning – JSP 1.1
Clean up the JSP page
JSP tags
• No more Java code in the HTML • Helps to separate page designer and Java programmer roles.

Use the include mechanism to separate HTML components and Javascript


Classic MVC (Model 1)
Event View Controller

Get Model State Change Notification


Good model for Java GUIs Web challenges:


web’s stateless behaviour view uses different technology than model or controller

MVC Model 2
Designed for the Web Architecture
Event HTTP Request

Controller Servlet

Client Browser

Model (JavaBean)
Get Provided by a backend service

Update HTTP Response

View JSP


Development Role Separation
3 distinct areas
Web Application
Event HTTP Request

Business Layer

Controller Servlet

Application Framework EJBs JDO CORBA

Client Browser

Model JavaBean

Update HTTP Response

View Layer


Style Sheets Custom Tags

Persistent Storage

Struts MVC 2 Implementation
Struts Components
Event HTTP Request



Business Logic

Client Browser

Forward Creates/Sets

Resource Bundle

Update HTTP Response


Get <Tag>


Controller Components
Struts supplied All client requests go through here Automatically populates a JavaBean (ActionForm) with request parameters Handles Locale and multi-part form requests Determines which Action or JSP to dispatch to


Controller Components
User defined Must extend org.apache.struts.action.Action Override the execute() method Acts as a coordinator to the Business Layer Gets data and determines which view to render next


Example Action execute method
public ActionForward execute(ActionMapping mapping, ActionForm form, Exception { //get the data for display BusinessDelegate delegate = BusinessDelegate.getInstance(); DataBean bean = delegate.getTableData(); //put the bean (model) in the request for display request.setAttribute(“tableData", bean); // Forward control to the specified success URI return (mapping.findForward("view/tabledata")); //defined in strutsconfig.xml }

HttpServletRequest request, HttpServletResponse response) throws

struts-config.xml file
Contains the configuration data to hook all the pieces together. Introduces a level of indirection to isolate the back end code (Actions and JSPs) Four main types of information: Message resource bundle declaration
For internationalization Describes where to find the ‘’ file
<message-resources parameter="resources.application"/>

struts-config.xml (cont’d)
Global forwards
These are links to other pages that are referenced in other jsps or Actions. Provides a level of indirection, so that a path change only has to updated one place.
<global-forwards> <forward name="data" path="/" /> <forward name="simpleform" path="/pages/simpleForm.jsp" /> </global-forwards>

struts-config.xml (cont’d)
Action Mappings
Defines a mapping between a logical Action name and the physical Action class (path, type) Specifies an associated ActionForm (name) Declares the input page (input) to return to if errors occur Defines local forwards (forward tag). Can also use forwards defined in the global-forwards section.

struts-config.xml (cont’d)
Action Mappings (cont’d)
<action-mappings> <action path="/MySubmitAction“ type="com.sample.form.simple.SubmitAction" scope="request" input="/pages/simpleForm.jsp"/> name="darnSimpleFormBean" validate="true" /> <forward name=”userdata" path="/pages/datadisplay.jsp" </action> </action-mappings>

Direct Action references end in .do http://…/

struts-config.xml (cont’d)
Bean Declarations
Used by the ActionServlet Controller when it automatically populates an ActionForm Tells the Controller where to physically locate the referenced ActionForm
<form-beans> <form-bean name="darnSimpleFormBean" type="com.sample.form.simple.SimpleFormBean"/> </form-beans>

User Defined Any JavaBean
Must have a public empty constructor and getters/setters for the data elements

Can be implemented as any data element (JDO, EJB, CORBA, etc.)
However, one should always decouple the client application from the specific business layer implementation
• Use Data Transfer Objects (Value Objects)

User defined Uses the following:
Java Server Pages, HTML JavaScript, StyleSheets Struts Tags and Custom Tags Resource Bundles JavaBeans (model) ActionForms


Struts Tag Libraries
Bean – accesses javabeans and resources Logic – manages conditionals Nested – lets base tags relate to each other HTML – creates input forms Template – original page templating system Tiles – new advanced templating system


Bean Tags
Outputs a message stored in a resource bundle Provides the mechanism for internationalization

Outputs a value from the given bean Provides formatting attribute DataBean
<br> <bean:message key="number.rows.label.key"/> <bean:write name="tableData" property="numberOfRows" /> (reference: ‘tableData’) int numberOfRows

Number of Rows: 4

Logic Tags
Conditional statements to determine output text Examples: (empty, greaterThan, lessThan, present, iterate)
Iterate allows looping over Collections


Logic Tags (cont’d)
DataBean (reference: ‘tableData’) int numberOfRows List dataList
1 many

RowElement String columnOne String columnTwo

<logic:iterate name="tableData" property="dataList" id="arow"> <tr><td> <bean:write name="arow" property="columnOne"/> </td><td> <bean:write name="arow" property="columnTwo"/> </td></tr>

Nested Tags
An extension of the base tags Allows tags to be aware of the tags around them This relationship is based on the association of the beans themselves Lets fewer attributes be defined
Person String name int age Address home Address String city String province String postalCode



Nested Tags (cont’d)
<html:form action="/SubmitAction"> Person...<br> Name: <html:text name="customer" property="name" /><br> Age: <html:text name="customer" property="age" /><br> Address...<br> City: <html:text name="customer" property="" /><br> Province: <html:text name="customer" property="home.province" /> </html:form>


Nested Tags (cont’d)
With Nested Tags:
<html:form action="/SubmitAction"> Person...<br> /><br> Name: <nested:text property="name" Age: <nested:text property="age" /><br> <nested:nest property="home"> Address...<br> City: <nested:text property="city" /><br> Province: <nested:text property="province" /> </nested:nest> </html:form>

Html Tags
Used to create input forms Tags are available for all of the HTML form input types.
<html:form action="/SimpleSubmitAction"> <bean:message key=""/> <html:text property="name"/><br> <bean:message key="simple.form.number.prompt.key"/> <html:text property="number"/><br> <html:submit><bean:message key="submit.key"/></html:submit> <html:reset><bean:message key="reset.key"/></html:reset> <html:cancel><bean:message key="cancel.key"/></html:cancel>


ActionForm (Form-Beans)
User defined JavaBean extend org.apache.struts.action.ActionForm Need to associate one FormBean with each Action that processes form data in struts-config Automatically gets populated by controller when a form has been submitted.
• Must be a direct mapping between an HTML form element name and the attribute in the ActionForm

HTML Tag – ActionForm Mapping
Action - ActionForm relationship defined in strutsconfig.xml

AFormBean <ActionForm> String name String number
Direct naming relationship

<html:form action="/SimpleSubmitAction"> <html:text property="name"/><br> <html:text property="number"/><br> <html:submit><bean:message key="button.submit"/></html:submit> </html:form>

<bean:message key=""/>

<bean:message key="simple.form.number.prompt.key"/>


Form Validation & Error Handling
2 ways to validate the form
Override validate() method in ActionForm Use the Struts-Validator package

Error Handling
Struts provides easy error handling with the ActionErrors and ActionError classes.


Form Validation – 1st Method
Override ActionForm validate() method
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); //validate the name field if (( == null) || ( < 1)) { errors.add(“inputerror", new ActionError("")); } //validate the number field if ((this.number == null) || (this.number.length() < 1)) { errors.add(“inputerror", new ActionError("error.number.required.key")); } return errors; //return null or empty ActionErrors if no errors found }

Error Handling
Use of ActionErrors class
Create list of errors and add to ActionErrors Up to four parameters can be embedded in an error message. Errors are displayed in the jsp page:
<html:errors property=“inputerror”/>

Resource bundle properties determine how displayed errors look:
errors.header=<UL> errors.prefix=<LI> errors.suffix=</LI> errors.footer=</UL>

Form Repopulation
Struts automatically takes care of repopulating the form


Form Validation – 2nd Method
Struts Validator package Generates both the client side (JavaScript) and Server side validation code Comes with several pre-built validation routines Required Date
Length Data type Range Credit card number Email address

Can define more routines using regular expressions

Duplicate Form Submission
After submitting a form, the user can press the Back button and submit the same form again. In some workflows this creates problems (ie. Banking transactions) Use the Token feature in Struts to prevent this from happening


Duplicate Form Submission
In the Action that displays form:
//mark form token start saveToken(request);

In the Action the processes form data:
if (!isTokenValid(request)) { // duplicate submit, return error message } //token is valid resetToken(request); //....process form....

A templating tag library Provides abstraction between the
Components of a web page (tiles)
• Header, menu, body, footer, etc.

Layout of the web page
• Defines how the tiles are arranged on the page

Allows for greater reuse of tiles Allows developer to easily change the web site look and feel

Tiles - Components
Header Tile Menu Tile

Body Tile

Footer Tile

Tiles – Sample Layout.jsp
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%> <%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles"%> <html:html locale="true"/> <body> <tiles:useAttribute name="titleKey" id="title"/> <h2><bean:message name="title" scope="page"/></h2> <tiles:insert attribute="header"/> <tiles:insert attribute="menu"/> <hr> <tiles:insert attribute="body"/> <tiles:insert attribute="footer"/> </body> </html:html>

Tiles – Definition.xml
<tiles-definitions> <definition name="main.default" path="/layouts/layout.jsp"> <put name="titleKey" value="main.title"/> <put name="header" value="/common/simpleHeader.jsp"/> <put name="menu" value="/common/mainMenu.jsp"/> <put name="body" value="/welcome.jsp"/> <put name="footer" value="/common/copyright.jsp"/> value can be: </definition> •jsp page </tiles-definitions> •another tile definition

Tiles – Extending a Definition
<tiles-definitions> <definition name="logon" extends="main.default"> <put name="titleKey" value="logon.title"/> <put name="menu" value=""/> <put name="body" value="/logonform.jsp"/> </definition> </tiles-definitions>


Tiles - Possibilities
Dynamically generate the pages
Change any attributes on the fly Load different tiles according to Locale Load different tiles according to a key – make site multi-channelled (personalized)


Other Features in Struts
File uploading
Multi-part form handling not defined in J2EE spec Struts provides implementation for doing this

Dynamic ActionForms
Can define ActionForms in struts-config.xml No need to create an actual bean for each form

Allows for multiple struts-config.xml files Large development teams can work on same project

DataSource definition
Able to define datasources in the struts-config.xml

Struts - Tools
Xdoclet (WebDoclet subproject)
Generates the struts-config.xml file from tags in the JavaDoc of the ActionForm and Action classes

Struts-config.xml editors
Plugins to various IDEs (Jbuilder, Eclipse, etc)

Full project code generators
From a given database schema creating the database accessors, Actions, struts-config.xml, and jsps to create, update and view the data.

Check for current tool list

When Not To Use Struts
Struts gives a project increased flexibility, re-usability, and division of roles. But, comes at the cost of added complexity For medium to large projects it helps to manage the overall complexity For smaller projects may create too much complexity
Ask questions about the future of the project:
• How much might the project grow • How open to change must it be

Future Directions of the Struts Project
Workflow Management System
Will allow controlling multiple page business processes through a central, rules-based system Commercial products currently let developers define workflow rules – the Struts workflow management will be similar

Incorporation into the JSP Standard Tag Library

Model 2 MVC is a excellent architecture for developing robust Web applications
Page oriented approach is simple, but fails as the application grows. Model 2
• Lets team members specialize their efforts • Takes care of mixing various technologies


Summary (cont’d)
Struts provides a mature Model 2 implementation
Has been developed over the past 2 years with active developer and user communities. Robust set of features Adheres to the Model 2 MVC paradigm Enjoys strong industry support


Lots of links to documentation and samples at the Struts homepage: