Professional Documents
Culture Documents
What Is Struts?
Framework for writing
applications using
MVC architecture
Open source
• Part of Apache’s Jakarta Project
• Current production version 1.0.2
Model 2 architecture implementation
Provides standard framework
infrastructure
Makes no presumptions about
business and
application objects it deals with
• Could be EJBs, CORBA, directly from
database, XML
tree
Page 3
What Is MVC?
Stands for ModelView
Controller
Design paradigm
• Originated in the Smalltalk community
Decouples data access code,
business logic
code and presentation code
Often ripple effects occur when
changes are
required in applications without this
separation
Page 4
What Is MVC?
MVC Components
Model
• Application data
View
• Translates Model into
readable form
Controller
• Processes user input
• Initiates change in state
of Model
• In web design also
responsible for flow
control
Page 5
Struts & MVC
MVC implementation
Model – Business Services, Transfer
Objects
• Business Services populate and return
Transfer
Objects
View – JSPs, ActionForms
• JSP queries ActionForm for form data
Controller – ActionServlet, Actions
• ActionServlet delegates control to Action
class
instances
Page 6
Struts Components
ActionServlet
Actions
ActionMappings
ActionForwards
ActionErrors
ActionForms
Resource Management
Tag Libraries
Configuration
Logging
Page 7
What Is the
ActionServlet
Manages application flow of
control
Primary controller for Struts
framework
Performs initialization for
application such as
Parses Struts configuration file
• Loads application message resources
• Initializes:
Action mapping cache
Application defined data sources
Servlet mapping information
Page 8
What Does the
ActionServlet
Do?
For each user request
Identifies action to invoke from URI
Instantiates ActionForm bean if
required by
mapping configuration
• Initialized with submitted form’s field
values
Calls the Action’s perform method
• May have to load and instantiate Action
first
HTTP GET and POST treated
identically
Page 9
ActionServlet
Processing
Segment of Struts ActionServlet
request
processing
* Copyright (c) 19992001 The Apache Software
Foundation. All rights
reserved
protected void process(HttpServletRequest
request,
HttpServletResponse response)
…
// Acquire the Action instance to process this
request
Action actionInstance =
processActionCreate(mapping, request);
…
ActionForward forward
= processActionPerform(actionInstance, mapping,
formInstance, request, response);
…
processActionForward(forward, mapping,
formInstance,
request, response);
Page 10
Struts 1.1
ActionServlet
Introduction of Request
Processor
Handles much of the functionality of
the
ActionServlet in Struts 1.0
Allows developers to more easily
customize the
request handling behavior
Page 11
What Is an Action?
Bridge between HTTP request
and business
services
Typically performs single task
or business
operation
Alternatively can group
cohesive actions
together within an Action class
Reduces number of required Action
classes
Page 12
How Is an Action
Used?
Implements perform() method
Executed by ActionServlet
according to
defined ActionMappings
Single instance per Action class
type
Therefore must be threadsafe
Page 13
What Does an Action
Do?
Processes request parameters
Invokes appropriate business
service
Prepares business service results
Determines path to follow
Uses ActionMapping to determine
where to
dispatch the user based on
• Request parameters
• Business service results
Page 14
Action Relationships
Business Service
Action
ActionMapping
ActionForm
queries
uses
invokes
Page 15
Action Interactions
Business Service
ActionMapping
ActionServlet
ActionForm
Action
saveInput
3:
findForward
4:
return forward
5:
getInput
2:
perform
1:
Page 16
Example Action
public ActionForward perform(ActionMapping
mapping,
ActionForm form,
HttpServletRequest req,
HttpServletResponse resp)
throws IOException, ServletException {
…
final EditPersonForm editPersonForm =
(EditPersonForm) form;
final String action =
editPersonForm.getSelected();
if (WebConstants.SAVE.equals(action)) {
savePerson(editPersonForm.getModifiedPerson());
return mapping.findForward("save");
}
else {
// Initial pass - forward to the view
return mapping.findForward("view");
}
Page 17
How Is an Action
Configured?
<action-mappings>
<action path="/person/editPerson"
type="com.redhook.examples.genealogy.web.EditPe
rsonAction"
scope="request"
name="edit.person.form"
input="/person/editPerson.jsp"
validate="true">
<forward name="save"
path="/common/welcome.do"
redirect="true"/>
<forward name=“view"
path="/common/editPerson.jsp"/>
</action>
</action-mappings>
Page 18
Struts 1.1 Actions
Method
perform()
replaced by
execute()
Backwards compatible
Change necessary to support
declarative
exception handling
Addition of DispatchAction
class
Supports multiple business methods
instead of a
single
execute()
method
• Allows easy grouping of related business
methods
Page 19
What Is an
ActionMapping?
Encapsulates mapping
information
Used to hold information that the
ActionServlet
knows about a mapping
Allows meta information to be
passed to
Action object
e.g. Configuration mappings for an
Action
Page 20
How Is an
ActionMapping
Used?
Passed to Action class when
perform()
invoked
Can be queried by Action class for
information
Used to determine where user should
be
forwarded or redirected
Page 21
ActionMapping
Interactions
Business Service
ActionMapping
ActionForward
ActionServlet
Action
JSP
Invoke
2:
findForward
3:
get URI
5:
return
4:
perform
1:
forward
6:
Page 22
Example
ActionMapping
Usage
Used to look up ActionForwards
with a
lookup name
try {
delegate.createPerson(personInfo);
return mapping.findForward(“save”);
}
Can also be used to retrieve
input source
catch (final DuplicatePersonException
duplicatePersonException) {
ActionErrors errors = new ActionErrors();
ActionError error = new
ActionError(“error.duplicate.name”);
errors.add(“name”, error);
saveErrors(request, errors);
return mapping.findForward(mapping.getInput());
}
Page 23
How Is an
ActionMapping
Configured?
Parent element of
Action
in the application
configuration
<action-mappings>
<action path=“/editPerson”>
…
<forward name=“save”
path=“/person/viewPersonProfile.do”
redirect=“true”/>
</action>
<action path=“/findPerson”>
…
<forward name=“view”
path=“/person/displayList.jsp”/>
</action>
…
</action-mappings>
Page 24
What Is an
ActionForward?
Logical abstraction of a web
resource
Minimizes coupling of an application
to physical
resources
Encapsulates URI that
ActionServlet can
redirect control to
Three properties
• Name – lookup key
• Path – URI
• Redirect – whether to redirect or forward
Page 25
How Is an
ActionForward
Used?
Defined as local to an action or
global to the
application
Look up via ActionMapping
class
findForward
Can also be dynamically created
by
specifying URI
Page 26
ActionForward
Interactions
Business Service
ActionMapping
ActionForward
ActionServlet
Action
JSP
Invoke
2:
findForward
3:
get URI
5:
return
4:
perform
1:
forward
6:
Page 27
Example
ActionForward
public ActionForward perform(…) throws
IOException,
ServletException {
…
String action = form.getSelected();
ActionForward forward;
if (action.equals(“login”)) {
forward = mapping.findForward(“login”);
}
else {
forward = new ActionForward(
“http://authserver:7001/authcontrol”,
true);
}
return forward;
}
Page 28
How Is an
ActionForward
Configured?
Can be configured globally
<global-forwards>
<forward name="welcome"
path="/common/welcome.do"
redirect="true"/>
</global-forwards>
Or relative to an action
<action>
…
<forward name="view"
path="/common/welcome.jsp"/>
</action>
Page 29
What Is an
ActionError?
Represents an error condition
detected
during application workflow
Passed through the system in a
container
object
ActionErrors
Page 30
How Is an ActionError
Used?
Created in ActionForm
validate()
or
Action
perform()
method
Created with error message key
and
parameters
Added to error container with
key
Represents form field causing the
error
ActionErrors is a request scope
object
Only exists until the input JSP is
redisplayed with
the error messages
Page 31
What Does an
ActionError Do?
Used to transport error
messages to the user
Supports internationalization of
error
messages
Allows user to be notified of
multiple error
conditions
Prevents a cycle of submit, display
error,
resubmit, display next error…
Page 32
ActionError
Relationships
ActionErrors
ActionError
ActionForm
Action
JSP
Displays
0..*
Creates
Creates
Page 33
ActionError
Interactions
ActionServlet
ActionErrors
ActionForm
ActionError
Client
JSP
Submit
1:
return
6:
Add
5:
Get error
8:
new ()
3:
Validate
2:
Get message
9:
new ()
4:
Display message
10:
Forward
7:
Page 34
How Is an ActionError
Configured?
Error messages defined in
resource bundle
ApplicationResources.properties by
default
Can be parameterized with up to five
parameters
• e.g.
error.invalid.date=Date {0} is not
valid
Error header and footer defined
errors.header
and
errors.footer
If present, added before and after
error
messages
Page 35
Example ActionError
Creation
Created in ActionForm validate
method
public ActionErrors validate(ActionMapping
mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
try {
DateFormat.parse(getBirthDate());
}
catch (final ParseException parseException) {
ActionError error = new
ActionError(“error.invalid.date”),
getBirthDate());
errors.add(“birthDate”, error);
}
return errors;
}
Page 36
Example ActionError
Creation
Can also be created in Action
perform
method
Generally if business validation is
necessary
• e.g. Uniqueness of input
…
try {
personDelegate.createPerson(personInfo);
}
catch (final DuplicatePersonException
duplicatePersonException) {
ActionErrors errors = new ActionErrors();
ActionError error = new
ActionError(“error.duplicate.name”);
errors.add(“name”, error);
saveErrors(request, errors);
return mapping.findForward(mapping.getInput());
}
Page 37
Example ActionError
Display
<form method=“post” action=“createPerson”>
<table>
…
<tr>
<td>Birthdate</td>
<td><input type=“text” name=“birthDate”/></td>
</tr>
<tr>
<td><html:errors/></td>
</tr>
<tr>
<td><input type=“submit” name=“Submit”
value=“Create”></td>
</tr>
</table>
</form>
Page 38
Struts 1.1 ActionErrors
New ActionMessage super class
introduced
Used for more general purpose
messages
• Action ‘Error’ implies improper to use for
informational
or warning messages
Introduction of declarative
exception
handling
Allows definition of exception
handling policy
externally
Page 39
What Is an
ActionForm?
Defines an abstract class for
managing forms
Standard callback for form validation
Standard callback for resetting a form
Supports form management by
Capturing input data
Validation of form data
Returning error message on validation
failure
Transferring data to Action class
Determining which action was
submitted
• If multiple submits in the form
Page 40
How Is an ActionForm
Used?
Defines accessors and mutators
for form
being maintained
Implements validate and reset
methods
Validate performs validation of data
• Only called if form configured for
validation
Reset allows recycling of forms
Two levels of scope – session
(default) and
request
Session used to support multipage
wizards
Form passed into Action class
when invoked
Page 41
What Does an
ActionForm Do?
When a form is submitted, the
ActionServlet
will:
Detect which ActionForm subclass is
associated
with the mapping (if any)
Find an existing instance or
instantiate one
Populate it with form data from the
request
Invoke the ActionForm’s validate
method
Pass the ActionForm instance to the
Action
instance
• If validation successful
Page 42
ActionForm
Relationships
ActionServlet
ActionErrors
ActionForm
ActionError
JSP
populated from
displays
invokes
creates
Page 43
ActionForm
Interactions
ActionServlet
ActionError
ActionErrors
ActionForm
Client
JSP
submit
1:
return
6:
new ()
4:
new ()
3:
add
5:
validate
2:
display errors
8:
forward
7:
Page 44
Example ActionForm
public ActionErrors validate(ActionMapping
mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
try {
DateFormat.parse(getBirthDate());
} catch (final ParseException parseException) {
errors.add(“birthDate”,
new ActionError(“error.invalid.date”),
getBirthDate());
}
if ((getName() == null) ||
(getName().equals(“”))) {
errors.add(“name”, new
ActionError(“error.name.required”));
}
return errors;
}
Page 45
How Is an ActionForm
Configured?
<form-beans>
<form-bean name=“edit.person.form"
type="com.redhook.examples.genealogy.web.EditPe
rsonForm"/>
</form-beans>
…
<action path="/person/editPerson"
type="com.redhook.examples.genealogy.web.EditPe
rsonAction"
name=“edit.person.form"
scope="request"
input="/person/editPerson.jsp"
validate="true">
<forward name=“save" path="/common/welcome.do"
redirect="true"/>
</action>
Page 46
Struts 1.1 ActionForms
Dynamic Forms introduced
Configured in configuration file
rather than
coding
Version exists that works with
validator package
to provide automatic validation
Page 47
Struts 1.1 Validation
Validator framework from
Jakarta
Part of Commons subproject
Struts 1.1 includes this by
default
Allows declarative validation for
many fields
• e.g. Formats
Dates, Numbers, Email, Credit Card, Postal Codes
• Lengths
Minimum, maximum
• Ranges
Can also be configured for Struts 1.0
Page 48
Struts Resource
Management
Centralizes resource
administration for
Internationalization
Error treatment
Standard labeling
By default
ApplicationResources.properties
Can be changed in web.xml
configuration
Must be located on class path
• Typically in WEBINF/classes
Page 49
ResourceManagement
–
ApplicationResources.
properties
# Titles
title.welcome=Genealogy Tree
# Labels
label.first.name=First Name:
# Links
link.add.person=Add a new person
# Resources
resource.image.save=/images/save.gif
# Errors
error.invalid.date=Date {0} is not
valid.
Page 50
Struts Resource
Management
Can be accessed from JSP
through tag
libraries
<bean:message
key=“label.first.name”/>
<html:img
pageKey=“resource.image.save”
/>
Can also be accessed in Action
objects
through MessageResources
MessageResources messages =
getResources();
Locale locale =
getLocale(request);
messages.getMessage(“label.na
me", locale);
Page 51
Struts & TagLibs
Struts supports four tag libraries
Not mandatory
• Renders cleaner pages
• Not limited to these four
Provides flexible way to
• Access application and framework objects
under
different scopes
• Render objects to output stream, handle
validation
and processing errors
• Support internationalization capabilities
• Create page templates that support
reusable design
Page 52
Struts & TagLibs
What is required to use them?
web.xml tag library declaration for
each library
<taglib>
<taglib-uri>/WEB-INF/tlds/struts-
bean.tld</taglib-uri>
<taglib-location>
/WEB-INF/tlds/struts-bean.tld
</taglib-location>
</taglib>
Taglib directive on each target page
<%@ taglib uri='/WEB-INF/tlds/struts-
bean.tld'
prefix='bean' %>
Page 53
Bean Tag Library
Provides ways to access and
expose beans
and properties in the application
Provides internationalization
functionality
Includes parametric replacement
Bean references can be created
String constants can be defined
Page 54
HTML Tag Library
Provides support for rendering
html controls
Input controls, images, forms, etc.
Includes support for:
JavaScript event handling
Cascading Style Sheets
Navigation attributes
Supports display of errors found
during form
validation
Page 55
Logic Tag Library
Conditional generation of
content
Supports comparison properties
equality to a
constant
Conditional on presence (or lack) of
variables or
properties
• Includes cookies, roles, etc.
Navigational forwarding or
redirection
Iteration of collection elements
Page 56
Template Tag Library
Allows atomic views to be
created
i.e. Section, Header, Footer, Content
Views can then be added to a
defined layout
Page 57
Struts & TagLibs
Can also use other tag libraries
Jakarta TagLibs
JSTL
Custom Tags
Struts 1.1
Tile TagLib supercedes Template
TagLib
• Provides more extensive layout support
Nested TagLib
• Extends base Struts Taglibs to support
relation to
each other in a nested manner
Page 58
Configuration
Two aspects to Struts
configuration
web.xml
strutsconfig.xml
Page 59
Configuration –
Web.xml
<web-app>
<servlet>
<servlet-name>action</servlet-name>
<servlet-
class>org.apache.struts.action.ActionServlet</s
ervlet-
class>
<init-param>
<param-name>application</param-name>
<param-value>ApplicationResources</param-value>
</init-param>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-
value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
…
Page 60
Configuration –
Web.xml
<web-app>
…
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
Page 61
Configuration –
Web.xml
<web-app>
…
<taglib>
<taglib-uri>/WEB-INF/tlds/struts-
bean.tld</taglib-uri>
<taglib-location>
/WEB-INF/tlds/struts-bean.tld
</taglib-location>
</taglib>
</web-app>
Page 62
Configuration –
Strutsconfig.xml
<struts-config>
<form-beans>
<form-bean name="edit.person.form"
type="com.redhook.examples.genealogy.web.EditPersonF
orm"/>
</form-beans>
<global-forwards>
<forward name="welcome" path="/common/welcome.do"
redirect="true"/>
</global-forwards>
<action-mappings>
<action path="/person/editPerson"
type="com.redhook.examples.genealogy.web.EditPersonA
ction"
name="edit.person.form"
scope="request"
input="/person/editPerson.jsp"
validate="true">
<forward name="save" path="/common/welcome.do"
redirect="true"/>
</action>
</action-mappings>
</struts-config>
Page 63
Configuration –
Strutsconfig.xml
<struts-config>
<form-beans>
<form-bean name=“edit.person.form"
type="com.redhook.examples.genealogy.web.EditPersonF
orm"/>
</form-beans>
<global-forwards>
<forward name="welcome" path="/common/welcome.do"
redirect="true"/>
</global-forwards>
<action-mappings>
<action path="/person/editPerson"
type="com.redhook.examples.genealogy.web.EditPersonA
ction"
scope="request"
name=“edit.person.form"
input="/person/editPerson.jsp"
validate="true">
<forward name="save" path="/common/welcome.do"
redirect="true"/>
</action>
</action-mappings>
</struts-config>
Page 64
Configuration –
Strutsconfig.xml
<struts-config>
<form-beans>
<form-bean name="edit.person.form"
type="com.redhook.examples.genealogy.web.EditPersonF
orm"/>
</form-beans>
<global-forwards>
<forward name="welcome" path="/common/welcome.do"
redirect="true"/>
</global-forwards>
<action-mappings>
<action path="/person/editPerson"
type="com.redhook.examples.genealogy.web.EditPersonA
ction"
scope="request"
name="edit.person.form"
input="/person/editPerson.jsp"
validate="true">
<forward name="save" path="/common/welcome.do"
redirect="true"/>
</action>
</action-mappings>
</struts-config>
Page 65
Struts 1.1
Configuration
Adds support for
Multiple application modules
Declarative exceptions
Plug in elements
Multiple message resource elements
Visual configuration tools can
also be found
Both commercial and opensource
•
http://jakarta.apache.org/struts/resources/gu
is.html
Page 66
Logging
Important aspect of applications
3
rd
party logging frameworks used pre
JDK 1.4
• i.e. log4j
Logging API introduced with JDK
1.4
• Similar to log4j
Hierarchical categories
Logging levels
Page 67
Logging
What does Struts provide?
Nothing
Jakarta project provides thin
logging
wrapper
Part of Commons subproject
Provides wrappers for standard
logging
frameworks
• JDK 1.4, log4j, etc.
Can also develop wrapper for custom
logging
API
Page 68
Logging
Why use Jakarta Common
Logging?
Can declaratively switch logging
frameworks
Implementation wrapper class
declared in a
properties file
Must still configure logging
framework in
typical way
i.e. log4j.properties
Jakarta also provides logging
tag library
Useful for debugging
• Allows dump of scope attributes
Page 69
Resources
JSP and Tag Libraries for Web
Development
by Wellington L.S. da Silva, New Riders
Publishing
ISBN: 0735710953
Programming Jakarta Struts
By Chuck Cavaness, O’Reilly & Associates
(October 2002)
ISBN: 0596003285
Struts in Action: A Practical Guide to
the Leading
Java Web Framework
by Ted Husted et al., Manning Publications
Company
ISBN: 1930110502
Page 70
Websites
http://jakarta.apache.org/struts/index.html
http://www.husted.com/struts
Sample app can be found at:
http://www.redhookgroup.com/downloads/css/geneal
ogy.zip
Thank you.
Any questions
andrew@redhookgroup.com