You are on page 1of 50

Java II--Copyright © 2001-2003 Tom Hunter

J2EE
Struts

Java II--Copyright © 2001-2003 Tom Hunter


Struts:
Introduction

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Introduction *

• Once you’ve coded a lot of JSP applications, you find


yourself doing a lot of repetitive things.
• Also, if you have a hard-coded link scattered around a lot
of JSPs, the first time you need to change that link you
discover a special kind of agony.
• Struts was designed to solve that problem and a few
others.
• Struts is about moving code to xml property files.

* This lecture was based on “Struts in Action” by Ted Husted ISBN 1-930110-50-2 Java II--Copyright © 2001-2003 Tom Hunter
Struts: Introduction
• Struts is based on the MVC or Model-View-Controller
design pattern.

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Introduction
• Under Struts the work of operating a web application is
divided up:
ActionServlet—this Struts component controls
navigation.
Action—this Struts component controls business logic.

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Introduction
• Here’s the process:
1.) An ActionServlet receives a request from the
container.
2.) The ActionServlet collects the information in the
request.
3.) Using the request URI, the ActionServlet tries to
match the URI with a so-called Action class.
4.) Whichever Action class is passed the request will take
the correct course of action.

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Introduction
• The preceding is just a general idea of how it works.
• Struts uses the following Java classes to work its magic:

ActionForm
ActionServlet
ActionMapping
ActionForward
Action

• In addition to these, Struts places a lot of information in


xml configuration files:
strut-config.xml

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Introduction
We will explore these in depth, but here’s a thumbnail
version of each:

ActionForm—Collects form data from HTML page.


ActionServlet—Controls everything.
ActionMapping—Helps when deciding where to go.
ActionForward—Where to send request
Action—Called to do business logic.

Java II--Copyright © 2001-2003 Tom Hunter


Struts:
ActionForm

Java II--Copyright © 2001-2003 Tom Hunter


Struts: ActionForm
• A Web Application is driven by HTML pages.

• A typical WebApp contains text fields in a FORM.

• To extract information from this page, we use the NAME.

<HTML>
<HEAD><TITLE>Simple JSP</TITLE></HEAD>
<BODY>
<FORM METHOD="POST" ACTION="/TestServlet">
<BR>Username:
<INPUT TYPE="text" NAME="user" VALUE="">
<BR>Password:
<INPUT TYPE="text" NAME="pass" VALUE="">
</FORM>
</BODY>
</HTML>
Java II--Copyright © 2001-2003 Tom Hunter
Struts: ActionForm
• Given the HTML page we see below, we could pull out
the value of the tag with the NAME of user by using the
following code in a Servlet’s doPost() method:

String userField = request.getParameter("user");

<HTML>
<HEAD><TITLE>Simple JSP</TITLE></HEAD>
<BODY>
<FORM METHOD="POST" ACTION="/SomeServlet">
<BR>Username:
<INPUT TYPE="text" NAME="user" VALUE="">
<BR>Password:
<INPUT TYPE="text" NAME="pass" VALUE="">
</FORM>
</BODY>
</HTML>
Java II--Copyright © 2001-2003 Tom Hunter
Struts: ActionForm
• However, with any fairly large page, this becomes tedious.

• A better way is to use a JavaBean.

• Using a JavaBean, we place all the data in the bean on the


JSP side and then it’s convenient for us to unpack it on the
servlet side.
• Struts has taken this one step further.

• If you follow the rules, Struts will automatically populate a


JavaBean for you—saving you the trouble of loading it.

Java II--Copyright © 2001-2003 Tom Hunter


Struts: ActionForm
• Okay, what are these rules we’re suppose to follow?

Instead of making up your own JavaBean, you need to


extend a special Struts JavaBean called the “ActionForm”
extends org.apache.struts.action.ActionForm

Java II--Copyright © 2001-2003 Tom Hunter


Struts: ActionForm
A Struts action form:
“is a JavaBean that extends ActionForm.”

It captures the input fields sent through the request.

You must create a JavaBean (that extends ActionForm)


that has an instance variable (with the correctly named getters
and setters) for each input field in the JSP page.

Java II--Copyright © 2001-2003 Tom Hunter


Struts: ActionForm
• So, let’s recall our HTML/JSP file, and then see how we
would create the correct ActionForm:
<HTML>
<HEAD><TITLE>Simple JSP</TITLE></HEAD>
<BODY>
<FORM METHOD="POST" ACTION="/SomeServlet">
<BR>Username:
<INPUT TYPE="text" NAME="user" VALUE="">
As we see, our
<BR>Password: SimpleForm
<INPUT TYPE="text" NAME="pass" VALUE=""> extends
</FORM> ActionForm
</BODY>
</HTML> It has getters and
setters named so they
import org.apache.struts.action.*; will be automatically
found.
public class SimpleForm extends ActionForm
{
private String user = “”;
private String pass = “”;

public SimpleForm(){}

public void setUser( String u ) { user = u; }


public void setPass( String p ) { pass = p; }
public String getUser() { return user; }
public String getPass() { return pass; }
} Java II--Copyright © 2001-2003 Tom Hunter
Struts: ActionForm
• When compiled, this .class file should be placed here:
webapps
myapp
WEB-INF
classes

Java II--Copyright © 2001-2003 Tom Hunter


Struts: ActionForm

• Here’s what will happen. The ActionServlet will


receive a POST, thereby executing its doPost()
method.

• The ActionServlet will try to match the


parameters in the request with the properties in the
ActionForm.

• For a parameter wxyz, the JavaBean (ActionForm)


must have a corresponding setWxyz() and
getWxyz() method.

Java II--Copyright © 2001-2003 Tom Hunter


Struts:
ActionServlet

Java II--Copyright © 2001-2003 Tom Hunter


Struts: ActionServlet
• The ActionServlet behaves like an orchestra
Conductor. It doesn’t do a lot of the work, but it
manages the other components.

• The ActionServlet receives a request from the


container and it routes the request to the correct place.

• 99% of the time, you will never need to change the


existing ActionServlet

Java II--Copyright © 2001-2003 Tom Hunter


Struts: ActionServlet
• The ActionServlet uses a special xml configuration file
called: struts-config.xml.

When the web container receives a request in the form of


/register-complete/enter.do, then—because of the
.do extension—it knows to pass the request off to the
ActionServlet. In turn, the ActionServlet looks in its
struts-config.xml file to see where to send the request.

Using this “mapping”, the


ActionServlet knows to send the
request to the JSP located at this path.
Thus, we have decoupled the location
of the actual JSP from its location as
implied by URL.
Java II--Copyright © 2001-2003 Tom Hunter
Struts: ActionServlet
• So, let’s review the sequence so far:

1.) Web container gets a request with a .do extension.


2.) Web container passes the request to the
ActionServlet
3.) ActionServlet grabs all the request parameters and
tries to insert them in an ActionForm.
4.) ActionServlet strips the .do extension.
5.) ActionServlet looks in the struts-config.xml
file for a matching URI pattern.
6.) …

Java II--Copyright © 2001-2003 Tom Hunter


Struts:
ActionMapping

Java II--Copyright © 2001-2003 Tom Hunter


Struts: ActionMapping
• The Struts Java class called ActionMapping is used inside
of the Action class (not yet covered).
• It has only one method we’re interested in:

ActionMapping mapping = new ActionMapping();

mapping.findForward( “somesymbolicname” );

• This means: “When you reach this statement, you should


forward the request to the JSP page represented by this
symbolic name ‘somesymbolicname’.”

Java II--Copyright © 2001-2003 Tom Hunter


Struts:
Action

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Action
• Recall that the business logic of a Struts application is all
done in the Action class.

• You will often need to create your own subclass of this


Action class.

• Your Action class must follow a very specific design


pattern:

Java II--Copyright © 2001-2003 Tom Hunter


import org.apache.struts.action.*;
import javax.servlet.http.*;

public class MyAction extends Action


{
public ActionForward perform( ActionMapping mapping,
ActionForm form,
HttpServletRequest req,
HttpServletResponse res )
{

After you have extended the Action class,


you will need to override the inherited
method called “perform()”.
In order for your override to work, it must
}
}
match the signature of the superclass, and
thus it must take the form we see here.

Java II--Copyright © 2001-2003 Tom Hunter


import org.apache.struts.action.*;
import javax.servlet.http.*;

public class MyAction extends Action


{
public ActionForward perform( ActionMapping mapping,
ActionForm form,
HttpServletRequest req,
HttpServletResponse res )
{
SimpleForm sf = (SimpleForm) form;
String username = sf.getUser();
String password = sf.getPass();
Now, the first step is to cast the
received ActionForm reference
into your subclass of
ActionForm. In this case, it’s
called SimpleForm. Recall, since
SimpleForm is an
ActionForm, we can perform
} this cast.
}

import org.apache.struts.action.*;

public class SimpleForm extends ActionForm


{

Java II--Copyright © 2001-2003 Tom Hunter


import org.apache.struts.action.*;
import javax.servlet.http.*;

public class MyAction extends Action


{
public ActionForward perform( ActionMapping mapping,
ActionForm form,
HttpServletRequest req,
HttpServletResponse res )
{
SimpleForm sf = (SimpleForm) form; Finally, we see how—depending
String username = sf.getUser(); on the results of the logic
String password = sf.getPass(); performed in this Action
if( username == null || password == null )
class—we use the
{ ActionMapping class to
return mapping.findForward( “failure” ); decide where to send the request
} from here.
else
{
return mapping.findForward( “success” );
}
}
}

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Action
• Remember, your Action class must do these three things:

Cast the incoming ActionForm class into your subclass.


Apply business logic.
Return the correct ActionForward.

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Action
• And let’s review how the struts-config.xml would
be modified to use our action class:

Here we see a new attribute was added to the action.


Within the Action class (our MyAction) we saw the
“findForward()” method referred to the symbolic
name “success”. Here’s where that is defined.

Java II--Copyright © 2001-2003 Tom Hunter


Struts:
Review So Far

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Review So Far
• As you no doubt see, this can be confusing.

• The names chosen for the components are not that meaningful and the
process is non-intuitive.

• Still, let’s see if we can understand the entire process.

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Review So Far
1.) Point your browser to a web page.

http://localhost:8080/register-complete/enter.jsp

First, we see that we’re


executing the JSP called
enter.jsp that lives in a
web application called
register-complete.

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Review So Far
2.) This is the HTML within the page enter.jsp
<form name="registerForm"
method="POST" action="/register-complete/enter.do">

UserName:
<input type="text" name="username" value=""><br>
enter password:
<input type="password" name="password1" value=""><br>
re-enter password:
<input type="password" name="password2" value=""><br>
<input type="submit" name="submit" value="Register">
</form>

When we click the Submit button, we trigger a POST against


the page /register-complete/enter.do.
The web container sees that we have asked it to render a page
that ends in .do.
The web container knows that all page requests that end in
.do should be sent to the ActionServlet, which will be
allowed to decide what to do.

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Review So Far
3.) The ActionServlet receives the page request. It
looks up the URI “mapping” pattern in its struts-
config.xml file.
The ActionServlet also stores the request
parameters in the ActionForm bean.
Since we are already inside the
register-complete web
application, you can omit that part
of the name. So, we’re doing a post
against /register-
complete/enter.do.
The ActionServlet knows
to strip off the .do, so it’s looking
for a path mapped to /enter.
And, we see that does exist.

Java II--Copyright © 2001-2003 Tom Hunter


This is the RegisterAction.java class. Relying on
the struts-config.xml file to identify this class, the
ActionServlet will execute the perform() method.

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Review So Far
4.) Next, the ActionServlet looks to see if a name
property is associated with the mapping.
In this case, it does find a name property, called
“registerForm”.
As we see, the name “registerForm” appears in the
line above. It represents an ActionForm bean called
“RegisterForm”.
The name property
tells it which
ActionForm class to
use.

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Review So Far
5.) Since the ActionServlet has discovered an
ActionForm is associated, it instantiates the bean and tries
to call its getters and setters for each of the parameters in
the request.

This same line also informs the


ActionServlet which
ActionForm class it should
use when it captures all the
request parameter information.

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Review So Far
6.) Finally, depending on the outcome of the business logic
in the RegisterAction class, one of the
findForward() methods is executed.

Java II--Copyright © 2001-2003 Tom Hunter


Struts:
Understanding the
Architecture

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Understanding the Architecture
• Let’s first review the sequence of actions:
1.) A client requests a web page that matches the Action URI pattern.
2.) Seeing the .do extension, the web container passes the request to
the ActionServlet.
3.) The ActionServlet looks in its struts-config.xml for
the mapping for that particular path.
4.) If that mapping specifies an ActionForm [JavaBean], the
ActionServlet either uses an existing instance of that
ActionForm or it instantiates a new one. The ActionServlet
populates the ActionForm.
5.) The ActionServlet sees which Action class is mapped to
that path and executes the perform() method of that Action
class.
6.) The Action class does what it needs for business logic.
7.) The Action returns an ActionForward to the
ActionServlet.
Java II--Copyright © 2001-2003 Tom Hunter
Struts: Understanding the Architecture
1, 2.) A client requests a web page that matches the Action
URI pattern. Seeing the .do extension, the web container
passes the request to the ActionServlet.

How does this happen?

Recall that the web container [the server] has its web.xml configuration
file. Within that config file, there is an element called—

<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

—that allows you to specify that all pages with this pattern should go to the servlet
action.
Java II--Copyright © 2001-2003 Tom Hunter
Struts: Understanding the Architecture
3-7.) The ActionServlet looks in its
struts-config.xml for the mapping for that
particular path.

When the ActionServlet receives a request, it has


several things to accomplish:
i.) process the locale
ii.) process the mapping—to see which Action to send the request to
and whether a bean is needed.
iii.) if a bean is needed, either find one in scope or create a new one, then
process the ActionForm bean—take the request parameters and
put them into the bean using its setters.
iv.) if the ActionMapping specifies the forward attribute, control is
either transferred to another resource or to an Action object.
v.) process the Action (if appropriate) by calling the perform()
method.
vi.) the Action returns an ActionForward
Java II--Copyright © 2001-2003 Tom Hunter
Struts:
Our First Example

Java II--Copyright © 2001-2003 Tom Hunter


Struts: Our First Example
• Once again, we will take the organic approach and see what
happens in a linear fashion.
• Before then, I would like to explore the set up of the web
app using Struts in the directory.

Java II--Copyright © 2001-2003 Tom Hunter


This “logon” is the root of the web app. Every path will be considered relative to this directory.

In this example, the pages directory will hold the JSP files. You have some
flexibility in where you place your JSPs, but wherever they go, you must make
sure your paths reflect that location.

This WEB-INF directory is


very important. In it we will
find the files at right.
We will explore these files more
on the next slide.

Our Action classes must go in this directory. In this


case, we see an app directory—which tells us that our
Action class specified that it was in a package called
app.

The resources directory will hold .properties files,


such as Messages.properties or any other
resource we might need.

Finally, the lib directory holds JAR files such as the


struts.jar file.
Java II--Copyright © 2001-2003 Tom Hunter
Struts: Our First Example
• As you recall from the previous slide, these files are
contained in the WEB-INF directory.

web.xml

The web.xml file is the same one that


must be present in all web applications. In
our case, aside from listing the
ActionServlet as being present, this
web.xml has a line that informs it to
send all pages with a .do extension to the
ActionServlet for processing.
Java II--Copyright © 2001-2003 Tom Hunter
Struts: Our First Example
• This slide explores the struts-config.xml file
First, we create a key
struts-config.xml “logonForm” that gives the
name of our ActionForm

These <action-mappings> tell the


ActionServlet which Action class
to execute when it encounters a particular
URI pattern.

In this example, you see that a forward has been


declared. This must work in concert with the business
logic in the Action class.
Java II--Copyright © 2001-2003 Tom Hunter
Struts: Our First Example
• This is a look at the HTML behind our first JSP.

Welcome.jsp

Java II--Copyright © 2001-2003 Tom Hunter

You might also like