Struts: MVC Meets JSP
Struts: MVC Meets JSP
2003-09 1
Agenda
What is Struts?
A Brief Review of MVC
A Look at a Simple Struts Example
The Struts Tag Library
Advanced Features of Struts
2003-09 2
Who Are We? - James
Director of Software Development, Benefit
Systems Inc.
23 years of development experience.
Author of JSP & MySQL Web Applications,
Struts Kick Start, JSF Kick Start (Forthcoming,
Fall 2003)
Committer status on Apache Commons and
Apache Struts.
2003-09 3
Who Are We? - Kevin
E-Business Architect, Sun Life Financial.
BS Engineering, MBA.
Microsoft MCSE
Sun Certified Java Programmer
Co-Author, "Struts Kick Start", SAMS Publishing
Co-Author, "Axis: The Definitive Guide", O'Reilly
Contributing Editor, Linux Business &
Technology
2003-09 4
What is Struts?
Struts implements the Model-View-
Controller design pattern for JSP.
Pioneered by Craig McClanahan of Sun.
Maintained as part of the Apache Jakarta
project.
Currently in final betas for a 1.1 release.
2003-09 5
The Components of Struts
Struts consists of two main components:
1. The servlet processing portion, which is
responsible for maintaining control of user
sessions and data, and managing workflow.
2. The tag libraries, which are meant to reduce
or eliminate the use of Java scriptlets on the
JSP page.
2003-09 6
The Power of Struts
Of the two, the tag libraries are the most
visible part, but also the least important
part of Struts (at least in the long run.)
Many of the tag libraries are already
obsolete if you can take advantage of
JSTL (i.e., you have a Servlet 2.3
container)
Most of the rest will be obsoleted by JSF.
2003-09 7
The Power of Struts (MVC)
The real power of Struts comes from the
MVC design pattern that is implemented
by the request processor.
To understand why this is such a powerful
tool, you first need to be familiar with MVC
2003-09 8
The MVC Pattern
The MVC (or model 2) design pattern is
intended to separate out the ever-
changing presentation layer (the JSP
page) from the web application control
flow (what page leads to what) and the
underlying business logic.
2003-09 9
The Three Pieces of MVC
The Model – The actual business data and logic,
such as an class representing users in the
database and routines to read and write those
users.
The View – A separate class which represents
data as submitted or presented to the user on
the JSP page.
The Controller – The ringmaster who decides
what the next place to take the user is, based on
the results of processing the current request.
2003-09 10
MVC and Struts
The best way to learn both MVC and Struts is to
see it in operation in a simple application.
Let’s look at a basic user registration form
implemented using Struts.
This walk-through skips all the basic
configuration steps and focuses on features.
See Struts Kick Start for all the gory details of setting
up Struts.
http://www.strutskickstart.com
2003-09 11
The Model
The model isn’t part of Struts per se, it’s
the actual back-end business objects and
logic that Struts exposes to the user.
In this case, we’ll write a very simple bean
that implements a User object.
Note: All example code omits imports for
brevity.
2003-09 12
package strutsdemo;
2003-09 14
Enter the View
The view is an placeholder object used in
association with the JSP pages, and which holds
a temporary copy of the model.
Why do this? Well, suppose you are editing a
model object, and the form submission fails
during validation.
If the model = the view, the model is now in an
inconsistent state and the original values are
lost.
2003-09 15
Defining the View
With Struts 1.1, there are now two different
ways to define a view object (known as an
ActionForm)
You can create a bean manually, with manual
form validation.
Or you can use DynaBeans in combination
with the Validator Framework.
2003-09 16
A Manual ActionForm
package strutsdemo.struts.forms;
2003-09 17
A Manual ActionForm (cont)
public ActionErrors validate(ActionMapping map,
HttpServletRequest req)
{
ActionErrors errors = new ActionErrors();
if ((username == null) || (username.size() == 0)) {
errors.add(“username”,
new ActionError(“login.user.required”));
}
if ((password == null) || (password.size() == 0)) {
errors.add(“password”,
new ActionError(“login.passwd.required”));
}
return errors;
}
}
2003-09 18
Key Points for ActionForms
In general, all fields should be Strings.
This preserves the contents of the field if it
doesn’t match against the required type
so if you type in “1OO” (rather than 100) for a
field that needs to be a number, the field
contents will be preserved when it returns to
the input form.
2003-09 19
More on ActionForms
If an ActionForm doesn’t implement
validate, the default validate (which does
nothing) is run.
If an ActionForm overrides validate, it
controls whether a form passes validation
or not. If the ActionErrors object returned
has size > 0, control is returned to the
input page.
2003-09 20
A Common ActionForm Gotcha
Let’s say you have a boolean property
called isJavaGeek tied to a checkbox on a
page.
You submit the form with the checkbox
checked.
Then you hit the back button (or it returns
to the page because of a validation error),
and you uncheck the box.
2003-09 21
A Common ActionForm Gotcha
The problem: Because by the HTML
standard, unchecked checkboxes don’t get
placed on the request, the form object will
not get the new value because the
reflection will never occur to change the
value of isJavaGeek
The solution: Implement the reset()
method on the ActionForm.
2003-09 22
Using Struts on the JSP Page
Let’s take a look at the input form that
supplies our newly created ActionForm
with values
Struts uses the struts-html taglib to make
interacting with the view easy.
2003-09 23
login.jsp
<%@ page language=“java” %>
<%@ taglib uri=“/WEB-INF/struts-html.tld” prefix=“html” %>
<head><title>Log in Please</title></head>
<h1>Log In Please</h1>
<html:form action=“/login”>
<html:errors property=“username”/><BR>
Username: <html:text property=“username”/><BR>
<html:errors property=“password”/><BR>
Username: <html:password property=“password”/>
<html:submit/>
</html:form>
2003-09 24
Controlling Flow with Actions
The actual processing of forms occurs in
Actions.
The action is the link between the view
and the backend business logic in the
model.
The Action is also responsible for
determining the next step in the pageflow.
2003-09 25
A Simple Action Class
package strutsdemo.struts.actions;
2003-09 27
Fun Things to do with Actions
If the Action returns null, no further
processing occurs afterwards.
This means you can use an Action to
implement pure servlet technology, like
generating a CSV file or a JPG.
You can chain together Actions using the
configuration file, useful for instantiating
multiple ActionForms.
2003-09 28
A Note About Validation
Because the ActionForm shouldn’t contain
business logic, the Action may need to do
some validations (such as
username/password checking)
Since the Action isn’t called until the
ActionForm validates correctly, you can
end up getting new errors at the end of the
process.
2003-09 29
Tying it All Together
So far, you’ve seen all the components
that come together to form a Struts
request cycle, except…
The piece that ties all the disparate pieces
together.
In Struts, this is the struts-config.xml file.
2003-09 30
A Simple Example of the Config
<struts-config>
<form-beans>
<form-bean name=“userForm”
type=“strutsdemo.struts.forms.UserForm”/>
</form-beans>
<action-mappings>
<action path=“/login” name=“userForm” scope=“request”
validate=“true”
type=“strutsdemo.struts.actions.LoginUserAction”
input=“/login.jsp”>
<forward name=“success” path=“/mainMenu.jsp”/>
</action>
</action-mappings>
</struts-config>
2003-09 31
Things to Notice in the Config
For space reasons, the XML header was
ommitted.
Form-beans define a name that Struts uses to
access an ActionForm.
Actions define:
What URL path the action is associated with.
What JSP page provides the input.
What JSP pages can serve as targets to the Action.
What Action is used to process the request.
Whether the form should be validated.
2003-09 32
Built-in Security
Because all JSP pages are reached via calls to
Actions, they end up with URLs like “/login.do”
The end-user never sees the actual URL of the
underlying JSP page.
You can place access control in your Actions,
avoiding having to put checks on all your JSP
pages.
You can also use container-based security to
control access via roles directly in the config.
2003-09 33
The Struts Tag Libraries
With the exception of the HTML and
TILES libraries, they have all been
superceded by JSTL.
However, if you can’t move to a Servlet
2.3 container, they offer a lot of the power
of JSTL.
2003-09 34
Examples of Struts Tags vs JSTL
Struts:
<logic:iterate id=“person” name=“people”>
<logic:empty name=“person” property=“height”>
<bean:write name=“person” property=“name”/>
has no height<BR>
</logic:empty>
</logic:iterate>
JSTL:
<c:forEach var=“person” items=“${people}”>
<c:if test=“${empty person.height}”>
<c:out value=“${person.name}”/> has no height<BR>
</c:if>
</c:forEach>
2003-09 35
The Struts Tag Libraries
Logic – Conditional Display, Iteration
Bean – Data Instantiation and Access
Html – Forms and Links
Nested – Access to Properties of Beans
Tiles – Structured Layout of Pages
2003-09 36
Advanced Tricks with Struts
2003-09 37
<form-bean name=“userForm”
type=“org.apache.struts.actions.DynaAction
Form”>
<form-property name=“username”
type=“java.lang.String”/>
<form-property name=“password”
type=“java.lang.String”/>
</form-bean>
--------------------------------
DynaActionForm uf =
(DynaActionForm) form;
String userName =
(String)uf.get(“username”);
2003-09 38
How to Validate DynaForms
Since you don’t define DynaForms as explicit
classes, how do you do validation?
Answer 1: Extend the DynaActionForm class
and write validate() methods.
Answer 2: Using the Struts Validator Framework.
Based on the Commons Validator package.
Uses an XML file to describe validations to be applied
to form fields.
2003-09 39
The Validator Framework
Predefined validations include:
Valid number: float, int
Is a Credit Card number
Length Checks
Blank/NotBlank
Regular Expression Matches
Plus the all-purpose cross-field dependency:
requiredif
2003-09 40
<form name=“medicalHistoryForm">
<field property=“lastCheckup"
depends=“required">
<arg0 key=" medicalHistoryForm.checkup.label"/>
</field>
<field property=“weight"
depends=“required,float">
<arg0 key=" medicalHistoryForm.weight.label"/>
</field>
</form>
2003-09 41
Validwhen appears in Struts 1.2
<form name=“medicalHistoryForm">
<field property=“lastMamogram"
depends="validwhen">
<arg0 key="dependentlistForm.firstName.label"/>
<var>
<var-name>test</var-name>
<var-value>((gender=“M”) OR (*this* != null))
</var-value>
</var>
</field>
</form>
2003-09 42
Summary
Struts 1.1 is about to be released.
Supported by all major IDEs (Eclipse,
IdeaJ, Jbuilder, etc)
Widely accepted and integrated into most
J2EE platforms.
Want to learn more?
“We’ve seen no better resource for learning Struts than
Struts Kick Start. “ -- barnesandnoble.com
2003-09 43