Vous êtes sur la page 1sur 43

Struts:

MVC meets JSP


James Turner, Kevin Bedell
Adapted from:
Struts Kick Start

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;

public class User {

private String username = null;


private String password = null;

public String getUsername () { return username; }


public void setUsername(String name) {
username = name;
}

public String getPassword () { return password; }


public void setPassword(String pw) {
password = pw;
}

public static User findUser(String username) {


User u = new User();
u.setUsername(username);
u.setPassword(“test”); // dummy implementation
return u;
}
}
2003-09 13
The Model (cont)
„ No rocket science so far, the Model (in this
case) is a simple bean with a dummied-up
load method that just creates a test user.
„ The key point of MVC is that the model
doesn’t get directly exposed to the view
(the JSP page in Struts.)
„ So how is data passed back and forth to
the user?

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;

public class UserForm extends ActionForm {

private String username = null;


private String password = null;

public String getUsername () { return username; }


public void setUsername(String name) {
username = name;
}

public String getPassword () { return password; }


public void setPassword(String pw) {
password = pw;
}

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;

public class LoginUserAction extends Action {


public ActionForward execute(ActionMapping mapping,
ActionForm form, HttpServletRequest req,
HttpServletResponse resp) {
UserForm uf = (UserForm) form;
User u = User.findUser(uf.getUsername());
ActionErrors errors = new ActionErrors();
if (u == null) {
errors.add(“username”,
new ActionError(“login.username.notfound”));
} else if (!uf.getPassword().equals(u.getPassword()) {
errors.add(“password”,
new ActionError(“login.password.invalid”));
}
2003-09 26
A Simple Action Class (cont)
if (errors.size() > 0) {
saveErrors(request, errors);
return mapping.getInputForward();
}
request.getSession().setAttribute(“currentUser”, u);
return mapping.findForward(“success”);
}
}

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

„DynaForms allow you to


avoid writing ActionForms
alltogther.

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