Professional Documents
Culture Documents
StrutsBasics Speakernoted
StrutsBasics Speakernoted
StrutsBasics Speakernoted
Struts Basics
The goal of this session is to learn the basic concept of Struts and
its architecture.
12/03/2003
Sang Shin
sang.shin@sun.com
www.javapassion.com
Java™ Technology Evangelist
Sun Microsystems, Inc.
2
12/03/2003
3
12/03/2003
Revision History
?
11/10/2003: version 1: created by Sang Shin
? Things to do
– Speaker notes need to be added to some slides
– Contents still need to be polished
4
12/03/2003
Agenda
? What is and Why Struts?
? Struts architecture
– Controller
– Model
– View
? Struts tag library
? Internationalization
? Validation and error handling
? Tools
5
This is the agenda. We will learn what is and why Struts first. Then we will
look into Struts architecture as one that follows MVC pattern.
Struts comes with extensive tag library so we will learn how to use them.
We will also learn how internationalization is done in Struts. We will learn
how input validation and error handling can be done. At the end we will
learn some of the Struts utility classes and J2EE patterns useed.
12/03/2003
What is Struts?
So what is Struts?
12/03/2003
Jakarta Struts
? Struts is an open source Web application
framework developed as Apache Jakarta
project
– http://jakarta.apache.org/struts/
I assume most of you know Struts is an open source web application framework developed as
Apache Jakarta project.
12/03/2003
What is Struts?
? Model-View-Controller (MVC) framework
? Used for constructing web applications
using Servlets and JSPs
? Pattern oriented
– Singleton, composition, delegate
– Easy to use and learn
? Includes JSP custom tag libraries
? Utility classes that support:
– XML parsing
– JavaBean property population
– Internationalization 8
Let me give you a quick high-level overview on what Struts is from a technical
standpoint.
Struts leverages J2EE design patterns that have been identified quite useful in
building J2EE applications.
Struts has its own set of custom tag libraries. Struts also support utility classes.
12/03/2003
Why Struts?
10
Why Struts?
? Takes much of the complexity out of building your
own MVC framework
? Encourages good design practice and modeling
? Easy to learn and use
? Feature-rich
? Many supported 3rd-party tools
? Flexible and extensible
? Large user community
? Stable and mature
? Open source 11
So we know you want to build your Web application based on MVC framework. Now
instead of building your own MVC, you can use Struts.
Struts also encourages good design practices and modeling because the framework is
designed with “time-proven” design patterns. Struts is relatively simple, thus is easy to learn
and use. It support many useful features.
Another reason Struts is popular is there are many 3rd-party tools. Struts is designed to be
extensible and flexible. Ever since its advent, Struts enjoyed a very large following from
developer community. Struts has been around quite a while and is considered very stable
and mature. And of course, being a open source project helps Struts' adoption.
12/03/2003
Why Struts?
? Integrates well with J2EE
? Good taglib support
? Works with existing web apps
? Easy to retain form state
? Unified error handling (via ActionError)
? Easily construct processes spanning multiple
steps
? Clear delineation of responsibility makes long
term maintenance easier (more modular)
12
Struts is very well integrated with J2EE. For example, many people use EJB as
model objects. Struts provides good tag libraries. It is relatively easy to adapt
existing Web applications to the Struts framework.
Struts allows capturing input form data into JavaBean objects called ActionForms.
It also provides standard error handling.
12/03/2003
Struts Architecture
(Quick Overview)
13
12/03/2003
Model-View-Control (model 2)
MVC Design Pattern
1
Request
(Controller)
Servlet
BROWSER
Ins
tan
Redirect 3 2
tia
te
5 (View) (Model )
Java Bean
Response JSP 4
14
15
The Action object can handle the request and respond to the client (usually a
Web browser) or indicate that control should be forwarded elsewhere. For
example, if a login succeeds, a login action may wish to forward the request onto
the mainMenu page.
Action objects have access to the application's controller servlet, and so have
access to that servlet's methods. When forwarding control, an Action object can
indirectly forward one or more shared objects, including JavaBeans, by placing
them in one of the standard contexts shared by Java Servlets.
12/03/2003
The handlers are tied to a Model, and each handler acts as an adapter
between the request and the Model. The Model represents, or
encapsulates, an application's business logic or state.
17
Now key aspect of Struts is controller. That is, the Struts framework has a
concrete set of programming API's and classes for Controller functions
while Struts does not dictate any Model or View technologies. In fact, it is
said that Struts is model and view independent because Struts allow any
kind of View and Model technologies.
12/03/2003
18
I
12/03/2003
Controller
19
12/03/2003
20
21
source: Chuck Cavaness
22
12/03/2003
Developer Responsibility
? Write an Action class (that is, an extension of the
Action class) for each logical request that may
be received
– override execute() method (perform() method
in Struts 1.0)
? Write the action mapping configuration file (in
XML) that is used to configure the controller
servlet (struts-config.xml)
? Update the web application deployment
descriptor file (in XML) for your application to
include the necessary Struts components
23
12/03/2003
Controller Components in
Struts Framework
? ActionServlet (Provided by Struts)
? RequestProcessor (Struts 1.1)(Provided by Struts)
– One for each module
? Action
– Developer extends Struts-provided Action class
? Action Mapping
– Developer specifies action mapping in
struts-config.xml file
– Struts framework creates ActionMapping object and
passes it to Action object
24
Struts also supports the ability to use ActionMapping classes that have
additional properties beyond the standard ones required to operate the
framework. This allows you to store additional information specific to
your application, but still utilize the remaining features of the
framework. In addition, Struts lets you define logical "names" to which
control should be forwarded so that an action method can ask for the
"Main Menu" page (for example), without knowing what the actual
name of the corresponding JSP page is. These features greatly assist
you in separating the control logic (what to do) with the view logic
(how it's rendered).
12/03/2003
ActionServlet
(Provided by Framework)
25
12/03/2003
26
The Struts controller delegates most of this grunt work to Action classes.
12/03/2003
27
http://localhost:8080/myApp/foo/someAction.do
28
12/03/2003
RequestProcessor
(Provided by Framework)
30
The RequestProcessor is where the majority of the core processing occurs for
each request. Let's take a look at the helper functions the process method
invokes in-turn:
12/03/2003
31
(read slide)
12/03/2003
(read slide)
12/03/2003
(read slide)
12/03/2003
34
(read slide)
12/03/2003
35
(read slide)
12/03/2003
36
(read slide)
12/03/2003
Action Mapping
(You provide it)
37
12/03/2003
38
39
* <form-beans>
* <global-forwards>
* <action-mappings>
12/03/2003
40
* name: A unique identifier for this bean, which will be used to reference
it in corresponding action mappings. Usually, this is also the name of the
request or session attribute under which this form bean will be stored.
* type: The fully-qualified Java classname of the ActionForm subclass to
use with this form bean.
12/03/2003
struts-config.xml: <form-beans>
1 <?xml version="1.0" encoding="ISO-8859-1" ?>
2
3 <!DOCTYPE struts-config PUBLIC
4 "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
5 "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
6
7 <struts-config>
8
9 <!-- ========== Form Bean Definitions ================= -->
10 <form-beans>
11
12 <form-bean name="submitForm"
13 type="hansen.playground.SubmitForm"/>
14
15 </form-beans>
42
12/03/2003
struts-config.xml:
<action-mappings>
1 <!-- ========== Action Mapping Definitions ============ -->
2 <action-mappings>
3
4 <action path="/submit"
5 type="hansen.playground.SubmitAction"
6 name="submitForm"
7 input="/submit.jsp"
8 scope="request"
9 validate="true">
10 <forward name="success" path="/submit.jsp"/>
11 <forward name="failure" path="/submit.jsp"/>
12 </action>
13
14 </action-mappings>
15
16 </struts-config>
43
12/03/2003
* name: The logical name for this forward. This is used in your
ActionForm's execute method to forward to the next appropriate resource.
Example: homepage
* path: The context relative path to the resource. Example: /index.jsp or
/index.do
* redirect: True or false (default). Should the ActionServlet redirect to the
resource instead of forward?
12/03/2003
Global Forwarding
1 <struts-config>
2 <form-beans>
3 <form-bean
4 name="logonForm"
5 type="org.apache.struts.webapp.example.LogonForm" />
6 </form-beans>
7 <global-forwards
8 type="org.apache.struts.action.ActionForward">
9 <forward
10 name="logon"
11 path="/logon.jsp"
12 redirect="false" />
13 </global-forwards>
14
45
Global Forwarding
1
2 <action-mappings>
3 <action
4 path="/logon"
5 type="org.apache.struts.webapp.example.LogonAction"
6 name="logonForm"
7 scope="request"
8 input="/logon.jsp"
9 unknown="false"
10 validate="true" />
11 </action-mappings>
12 </struts-config>
46
As you can see, this mapping matches the path /logon (actually,
because the MailReader example application uses extension mapping,
the request URI you specify in a JSP page would end in /logon.do).
When a request that matches this path is received, an instance of the
LogonAction class will be created (the first time only) and used. The
controller servlet will look for a bean in request scope under key
logonForm, creating and saving a bean of the specified class if needed.
12/03/2003
Local Forwarding
1 <!-- Edit mail subscription -->
2 <action
3 path="/editSubscription"
4 type="org.apache.struts.webapp.example.EditSubscriptionAction"
5 name="subscriptionForm"
6 scope="request"
7 validate="false">
8 <forward
9 name="failure"
10 path="/mainMenu.jsp"/>
11 <forward
12 name="success"
13 path="/subscription.jsp"/>
14 </action>
47
Optional but very useful are the local "forward" elements. In the
MailReader example application, many actions include a local
"success" and/or "failure" forward as part of an action mapping.
Using just these two extra properties, the Action classes are almost
totally independent of the actual names of the presentation pages. The
pages can be renamed (for example) during a redesign, with negligible
impact on the Action classes themselves. If the names of the "next"
pages were hard coded into the Action classes, all of these classes
would also need to be modified. Of course, you can define whatever
local forward properties makes sense for your own application.
12/03/2003
ActionForm
(You provide it)
48
12/03/2003
If you declare such beans in your Struts configuration file (see " Building
the Controller Components"), the Struts controller servlet will
automatically perform the following services for you, before invoking the
appropriate Action method:
51
When you code your ActionForm beans, keep the following principles
in mind:
Example: submit.jsp
1 <%@ page language="java" %>
2 <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
3 <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
4 <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
5
6 <html>
7 <head><title>Submit example</title></head>
8 <body>
9
10 <h3>Example Submit Page</h3>
11
12 <html:errors/>
13
14 <html:form action="submit.do">
15 Last Name: <html:text property="lastName"/><br>
16 Address: <html:textarea property="address"/><br>
17 Sex: <html:radio property="sex" value="M"/>Male
18 <html:radio property="sex" value="F"/>Female<br>
19 Married: <html:checkbox property="married" /><br>
20 Age: <html:select property="age">
21 <html:option value="a">0-19</html:option>
22 <html:option value="b">20-49</html:option>
23 <html:option value="c">50-</html:option>
24 </html:select><br>
25 <html:submit/>
26 </html:form> 52
So this slide shows submit.jsp page in which a form page prompts 5 properties
- lastname, address, sex, married, age. And in the following slide, we will see
how these properties are reflected as getter and setter methods of ActionForm
class.
12/03/2003
Model: ActionForm
1 package hansen.playground;
2
3 import javax.servlet.http.HttpServletRequest;
4 import org.apache.struts.action.*;
5
6 public final class SubmitForm extends ActionForm {
7
8 /* Last Name */
9 private String lastName = "Hansen"; // default value
10 public String getLastName() {
11 return (this.lastName);
12 }
13 public void setLastName(String lastName) {
14 this.lastName = lastName;
15 }
16
17 /* Address */
18 private String address = null;
19 public String getAddress() {
20 return (this.address);
21 }
22 public void setAddress(String address) {
23 this.address = address;
24 }
25 ...
53
struts-config.xml: <form-beans>
1 <?xml version="1.0" encoding="ISO-8859-1" ?>
2
3 <!DOCTYPE struts-config PUBLIC
4 "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
5 "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
6
7 <struts-config>
8
9 <!-- ========== Form Bean Definitions ================= -->
10 <form-beans>
11
12 <form-bean name="submitForm"
13 type="hansen.playground.SubmitForm"/>
14
15 </form-beans>
54
12/03/2003
struts-config.xml: <action-mappings>
1 <!-- ========== Action Mapping Definitions ============ -->
2 <action-mappings>
3
4 <action path="/submit"
5 type="hansen.playground.SubmitAction"
6 name="submitForm"
7 input="/submit.jsp"
8 scope="request"
9 validate="true">
10 <forward name="success" path="/submit.jsp"/>
11 <forward name="failure" path="/submit.jsp"/>
12 </action>
13
14 </action-mappings>
15
16 </struts-config>
55
12/03/2003
56
Action
(You create one)
57
12/03/2003
Action Class
? Focus on control flow
– Process client request by calling other objects
(BusinessLogic beans) inside its execute() method
– Returns an ActionForward object that identifies
where control should be forwarded
?
JSP
? Tile definition
?
Velocity template
?
Another Action
59
The goal of an Action class is to process a request, via its execute method,
and return an ActionForward object that identifies where control should be
forwarded (e.g. a JSP, Tile definition, Velocity template, or another Action)
to provide the appropriate response.
12/03/2003
60
12/03/2003
61
T
12/03/2003
Developer Responsibility:
Action Class
? Extend org.jakarta.struts.action.Action
? Override
– execute() method (in Struts 1.1)
– perform() method (in Struts 1.0)
62
12/03/2003
63
64
The perform method may still be used in Struts 1.1 but is deprecated. The
Struts 1.1 method simply calls the new execute method and wraps any
Exception thrown as a ServletException.
12/03/2003
65
In the MVC/Model 2 design pattern, a typical Action class will often implement logic
like the following in its execute method:
* Validate the current state of the user's session (for example, checking that the user
has successfully logged on). If the Action class finds that no logon exists, the request
can be forwarded to the presentation page that displays the username and password
prompts for logging on. This could occur because a user tried to enter an application
"in the middle" (say, from a bookmark), or because the session has timed out, and the
servlet container created a new one.
* If validation is not complete, validate the form bean properties as needed. If a
problem is found, store the appropriate error message keys as a request attribute, and
forward control back to the input form so that the errors can be corrected.
* Perform the processing required to deal with this request (such as saving a row
into a database). This can be done by logic code embedded within the Action class
itself, but should generally be performed by calling an appropriate method of a
business logic bean.
* Update the server-side objects that will be used to create the next page of the user
interface (typically request scope or session scope beans, depending on how long you
need to keep these items available).
* Return an appropriate ActionForward object that identifies the presentation page
to be used to generate this response, based on the newly updated beans. Typically,
you will acquire a reference to such an object by calling findForward on either the
ActionMapping object you received (if you are using a logical name local to this
mapping), or on the controller servlet itself (if you are using a logical name global to
the application).
12/03/2003
67
Write code for a multi-threaded environment - The controller servlet creates only one instance of
your Action class, and uses this one instance to service all requests. Thus, you need to write thread-
safe Action classes. Follow the same guidelines you would use to write thread-safe Servlets. Here are
two general guidelines that will help you write scalable, thread-safe Action classes:
Only Use Local Variables - The most important principle that aids in thread-safe coding is to use
only local variables, not instance variables, in your Action class. Local variables are created on a
stack that is assigned (by your JVM) to each request thread, so there is no need to worry about
sharing them. An Action can be factored into several local methods, so long as all variables needed
are passed as method parameters. This assures thread safety, as the JVM handles such variables
internally using the call stack which is associated with a single Thread.
Don't throw it, catch it! - Ever used a commercial website only to have a stack trace or exception
thrown in your face after you've already typed in your credit card number and clicked the purchase
button? Let's just say it doesn't inspire confidence. Now is your chance to deal with these application
errors - in the Action class. If your application specific code throws expections you should catch
these exceptions in your Action class, log them in your application's log (servlet.log("Error
message", exception)) and return the appropriate ActionForward.
It is wise to avoid creating lengthy and complex Action classes. If you start to embed too much
logic in the Action class itself, you will begin to find the Action class hard to understand, maintain,
and impossible to reuse. Rather than creating overly complex Action classes, it is generally a good
practice to move most of the persistence, and "business logic" to a separate application layer. When
an Action class becomes lengthy and procedural, it may be a good time to refactor your application
architecture and move some of this logic to another conceptual layer; otherwise, you may be left with
an inflexible application which can only be accessed in a web-application environment. Struts should
be viewed as simply the foundation for implementing MVC in your applications. Struts provides you
12/03/2003
struts-config.xml: ActionMapping
1
2 <!-- ========== Action Mapping Definitions ============ -->
3 <action-mappings>
4
5 <action path="/submit"
6 type="hansen.playground.SubmitAction"
7 name="submitForm"
8 input="/submit.jsp"
9 scope="request"
10 validate="true">
11 <forward name="success" path="/submitSuccess.jsp"/>
12 <forward name="failure" path="/submitFailure.jsp"/>
13 </action>
14
15 </action-mappings>
16
17 </struts-config>
69
12/03/2003
70
12/03/2003
Model Components
(You provide them)
71
12/03/2003
Model Components
? Model divided into concepts
– Internal state of the system
– Actions that can change that state
? Internal state of system represented by
– JavaBeans
– Enterprise JavaBeans
– POJO's
– JDO
– JDBC
– Whatever 72
The Model portion of an MVC-based system can be often be divided into two major
subsystems -- the internal state of the system and the actions that can be taken to
change that state.
In grammatical terms, we might think about state information as nouns (things) and
actions as verbs (changes to the state of those things).
Many applications represent the internal state of the system as a set of one or more
JavaBeans. The bean properties represent the details of the system' state. Depending
on your application's complexity, these beans may be self contained (and know how
to persist their own state), or they may be facades that know how to retrieve the
system's state from another component. This component may be a database, a search
engine, an Entity Enterprise JavaBean, a LDAP server, or something else entirely.
Many requirements documents used for building web applications focus on the View.
However, you should ensure that the processing required for each submitted request is
also clearly defined from the Model's perspective. In general, the developer of the
Model components will be focusing on the creation of JavaBeans classes that support
all of the functional requirements. The precise nature of the beans required by a
particular application will vary widely depending on those requirements, but they can
generally be classified into several categories discussed below.
12/03/2003
73
source: Chuck Cavaness
This picture shows where the model components fits. As the picture
shows, actual model components can be in any form including
JavaBeans, JDO, CORBA, EJB, JDBC or whatever that can be used
to maintain some internal state.
12/03/2003
Model Components
? JavaBeans and Scope
– Page – visible within a single JSP page, for the
lifetime of the current request
– Request – visible within a single JSP page, as
well as to any page or servlet that is included in
this page, or forwarded to by this page
– Session – visible to all JSP pages and servlets
that participate in a particular user session,
across one or more requests
– Application - visible to all JSP pages and servlets
that are part of a web application
74
# page - Beans that are visible within a single JSP page, for the lifetime of the
current request. (Local variables of the service method)
# request - Beans that are visible within a single JSP page, as well as to any page or
servlet that is included in this page, or forwarded to by this page. (Request
attributes)
# session - Beans that are visible to all JSP pages and servlets that participate in a
particular user session, across one or more requests. (Session attributes)
# application - Beans that are visible to all JSP pages and servlets that are part of a
web application. (Servlet context attributes)
12/03/2003
Model Components
? JSP pages and servlets in the same web
application share the same sets of bean
collections
? Example
– Servlet code
?
MyCart mycart = new MyCart(...);
? request.setAttribute("cart", mycart);
– JSP page
? <jsp:useBean id="cart" scope="request"
?
class="com.mycompany.MyApp.MyCart"/>
75
It is important to remember that JSP pages and servlets in the same web application
share the same sets of bean collections. For example, a bean stored as a request
attribute in a servlet like this:
is immediately visible to a JSP page which this servlet forwards to, using a standard
action tag like this:
(read slide)
12/03/2003
SystemState Bean
? For small scale systems or for state
information that need not be kept for a long
period of time
– a set of system state beans may contain all the
knowledge that the system ever has
? Large scale application
– System state beans may represent information that
is stored permanently in some external database
? CustomerBean object that corresponds to a particular
row in the CUSTOMERS table
– EJB might be used 79
For small scale systems, or for state information that need not be kept
for a long period of time, a set of system state beans may contain all
the knowledge that the system ever has of these particular details. Or,
as is often the case, the system state beans will represent information
that is stored permanently in some external database (such as a
CustomerBean object that corresponds to a particular row in the
CUSTOMERS table), and are created or removed from the server's
memory as needed. Entity Enterprise JavaBeans are also used for this
purpose in large scale applications.
12/03/2003
BuesinessLogic Bean
? Struts does not define formal class of this
– Can be an ordinary JavaBean
– Can be stateful or stateless EJB
? Encapsulates functional logic of an
application using method calls
? Action object should translate the HTTP
request then call BusinessLogic bean
80
You should encapsulate the functional logic of your application as method calls
on JavaBeans designed for this purpose. These methods may be part of the
same classes used for the system state beans, or they may be in separate
classes dedicated to performing the logic. In the latter case, you will usually
need to pass the system state beans to be manipulated to these methods as
arguments.
Depending on the complexity and scope of your application, business logic
beans might be ordinary JavaBeans that interact with system state beans
passed as arguments, or ordinary JavaBeans that access a database using
JDBC calls. For larger applications, these beans will often be stateful or
stateless Enterprise JavaBeans (EJBs) instead.
12/03/2003
BuesinessLogic Bean
? Ideally should be designed so that they do
not know they are being executed in a web
application environment
– should not refer any Web application objects
– enhanced reusability
81
View Components
(You provide them)
82
12/03/2003
83
source: Chuck Cavaness
This picture shows where the view components fit in the bug picture.
12/03/2003
View Components
? JSP files which you write for your specific
application
? Set of JSP custom tag libraries
? Resource files for internationalization
? Allows for fast creation of forms for an
application
? Works in concert with the controller Servlet
84
View
? ActionForward object tells Servlet controller
which JSP page is to be dispatched to
? JSP pages use ActionForm beans to get
output Model data to display
? Struts contains a series of tag libraries
– Facilitates communication between HTML designers
and developers
– Facilitates dynamic Web content
85
12/03/2003
86
At one time or another, most web developers have built forms using the standard
capabilities of HTML, such as the <input> tag. Users have come to expect interactive
applications to have certain behaviors, and one of these expectations relates to error
handling -- if the user makes an error, the application should allow them to fix just
what needs to be changed -- without having to re-enter any of the rest of the
information on the current page or form.
Fulfilling this expectation is tedious and cumbersome when coding with standard
HTML and JSP pages. For example, an input element for a username field might look
like this (in JSP):
<input type="text" name="username"
value="<%= loginBean.getUsername() >"/>
which is difficult to type correctly, confuses HTML developers who are not
knowledgeable about programming concepts, and can cause problems with HTML
editors. Instead, Struts provides a comprehensive facility for building forms, based
on the Custom Tag Library facility of JSP 1.1. The case above would be rendered
like this using Struts:
<html:text property="username"/>;
with no need to explicitly refer to the JavaBean from which the initial value is
retrieved. That is handled automatically by the JSP tag, using facilities provided by
the framework.
12/03/2003
Example: submit.jsp
1 <%@ page language="java" %>
2 <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
3 <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
4 <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
5
6 <html>
7 <head><title>Submit example</title></head>
8 <body>
9
10 <h3>Example Submit Page</h3>
11
12 <html:errors/>
13
14 <html:form action="submit.do">
15 Last Name: <html:text property="lastName"/><br>
16 Address: <html:textarea property="address"/><br>
17 Sex: <html:radio property="sex" value="M"/>Male
18 <html:radio property="sex" value="F"/>Female<br>
19 Married: <html:checkbox property="married"/><br>
20 Age: <html:select property="age">
21 <html:option value="a">0-19</html:option>
22 <html:option value="b">20-49</html:option>
23 <html:option value="c">50-</html:option>
24 </html:select><br>
25 <html:submit/>
87
26 </html:form>
This slide shows submit.jsp page which is the only JSP page used in
the very simple application we built.
12/03/2003
Example: submit.jsp
1 <logic:present name="lastName" scope="request">
2 Hello
3 <logic:equal name="submitForm" property="age" value="a">
4 young
5 </logic:equal>
6 <logic:equal name="submitForm" property="age" value="c">
7 old
8 </logic:equal>
9 <bean:write name="lastName" scope="request"/>
10 </logic:present>
11
12 </body>
13 </html>
88
12/03/2003
web.xml
89
12/03/2003
Just like any other Web application, web.xml resides under WEB-INF
directory either in packed form (*.war file) or unpacked form.
12/03/2003
Example: web.xml
1 <!DOCTYPE web-app
2 PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
3 "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
4
5 <web-app>
6 <display-name>Advanced J2EE Programming Class Sample App</display-name>
7
8 <!-- Standard Action Servlet Configuration (with debugging) -->
9 <servlet>
10 <servlet-name>action</servlet-name>
11 <servlet-class>
12 org.apache.struts.action.ActionServlet
13 </servlet-class>
14 <init-param>
15 <param-name>application</param-name>
16 <param-value>ApplicationResources</param-value>
17 </init-param>
18 <init-param>
19 <param-name>config</param-name>
20 <param-value>/WEB-INF/struts-config.xml</param-value>
21 </init-param>
22 </servlet> 91
12/03/2003
Example: web.xml
1 <!-- Standard Action Servlet Mapping -->
2 <servlet-mapping>
3 <servlet-name>action</servlet-name>
4 <url-pattern>*.do</url-pattern>
5 </servlet-mapping>
6
7 <!-- Struts Tag Library Descriptors -->
8 <taglib>
9 <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
10 <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
11 </taglib>
12 <taglib>
13 <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
14 <taglib-location>/WEB-INF/struts-html.tld</taglib-location>
15 </taglib>
16 <taglib>
17 <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
18 <taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
19 </taglib>
20
21 </web-app>
22 92
12/03/2003
93
12/03/2003
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib> 97
…
Bean Tags
98
12/03/2003
Bean Tags
? Tags for accessing beans and their
properties
? Enhancements to <jsp:useBean>
? Convenient mechanisms to create new
beans based on the value of:
– Cookies
– Request Headers
– Parameters
99
This tag library contains tags useful in accessing beans and their
properties, as well as defining new beans (based on these
accesses) that are accessible to the remainder of the page via
scripting variables and page scope attributes. Convenient
mechanisms to create new beans based on the value of request
cookies, headers, and parameters are also provided.
12/03/2003
Example: submit.jsp
1 <logic:present name="lastName" scope="request">
2 Hello
3 <logic:equal name="submitForm" property="age" value="a">
4 young
5 </logic:equal>
6 <logic:equal name="submitForm" property="age" value="c">
7 old
8 </logic:equal>
9 <bean:write name="lastName" scope="request"/>
10 </logic:present>
11
12 </body>
13 </html>
100
HTML Tags
101
12/03/2003
HTML Tags
? Form bridge between JSP view and other
components
? Input forms are important for gathering data
? Most of the actions of the HTML taglib
involve HTML forms
? Error messages, hyperlinking,
internationalization
? HTML tags must be nested within a form tag
– inform tag handler which bean to use for initializing
displayed values
102
The tags in the Struts HTML library form a bridge between a JSP
view and the other components of a Web application. Since a
dynamic Web application often depends on gathering data from a
user, input forms play an important role in the Struts framework.
Consequently, the majority of the HTML tags involve HTML
forms.
The HTML taglib contains tags used to create Struts input forms,
as well as other tags generally useful in the creation of HTML-
based user interfaces. The output is HTML 4.01 compliant or
XHTML 1.0 when in XHTML mode.
HTML Tag Resources
12/03/2003
HTML Tags
?
checkboxes
?
hidden fields
?
password input fields
?
radio buttons
?
reset buttons
?
select lists with embedded option or options items
?
option
?
options
?
submit buttons
?
text input fields
?
textareas
103
In every case, a field tag must be nested within a form tag, so that
the field knows what bean to use for initializing displayed values.
12/03/2003
Example: submit.jsp
1 <%@ page language="java" %>
2 <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
3 <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
4 <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
5
6 <html>
7 <head><title>Submit example</title></head>
8 <body>
9
10 <h3>Example Submit Page</h3>
11
12 <html:errors/>
13
14 <html:form action="submit.do">
15 Last Name: <html:text property="lastName"/><br>
16 Address: <html:textarea property="address"/ ><br>
17 Sex: <html:radio property="sex" value="M"/ >Male
18 <html:radio property="sex" value="F"/>Female<br>
19 Married: <html:checkbox property="married"/><br>
20 Age: <html:select property="age">
21 <html:option value="a">0-19</html:option>
22 <html:option value="b">20-49</html:option>
23 <html:option value="c">50-</html:option>
24 </html:select><br>
25 <html:submit/> 104
26 </html:form>
12/03/2003
Logic Tags
105
12/03/2003
Logic Tags
? Provides presentation logic tags that
eliminate need for scriptlets
? Value comparisons
Include: = != <= >= < >
? Substring matching
– match, notmatch
? Presentation logic
– forward, redirect
? Collections
– iterate 106
Example: submit.jsp
1 <logic:present name="lastName" scope="request">
2 Hello
3 <logic:equal name="submitForm" property="age" value="a">
4 young
5 </logic:equal>
6 <logic:equal name="submitForm" property="age" value="c">
7 old
8 </logic:equal>
9 <bean:write name="lastName" scope="request"/>
10 </logic:present>
11
12 </body>
13 </html>
< 107
12/03/2003
Template Tags
108
12/03/2003
Template Tags
? Templates are JSP pages that include
parameterized content
? Useful for creating dynamic JSP
templates for pages that share a common
format
? Functionality provided is similar to what
can be achieved using the standard JSP
include directive, but these tags allow for
dynamic rather than static content
109
12/03/2003
Template Tags
? Three template tags work in an
interrelated function:
– Get - Gets the content from request scope that
was put there by a put tag.
– Insert - Includes a template
– Put - Puts content into request scope
110
12/03/2003
111
12/03/2003
layout.jsp
<html>
<head>
<title> <template:get name='title'/> </title>
</head>
<body >
<table>
<tr><td> <template:get name='header'/> </td></tr>
<tr><td> <template:get name='content'/> </td></tr>
<tr><td> <template:get name='footer'/> </td></tr>
</table>
</body>
</html>
112
12/03/2003
Internationalization
113
Internationalization
? Extends basic approach of
java.util.ResourceBundle
– org.apache.struts.util.MessageResources
? Allows specification of dynamic locale key
on a per user basis
? Limited to presentation, not input
? Configure resource bundles in web.xml file
114
Internationalization:
Developer responsibilities
? Create resource file for a default language
? Create resource files for each language
you want to support
? Define base name of the resource bundle
in an initialization parameter
? In JSP page
– Use <html:errors/> to display locale specific error
messages
115
12/03/2003
Resource files
? MyApplication.properties
– Contains the messages in the default language for
your server
– If your default language is English, you might have
an entry like this:
? prompt.hello=Hello
? MyApplication_xx.properties
– Contains the same messages in the language
whose ISO language code is "xx"
? prompt.hello=Bonjour
116
Example:
ApplicationResource.properties
1 errors.header=<h4>Validation Error(s)</h4><ul>
2 errors.footer=</ul><hr>
3
4 error.lastName=<li>Enter your last name
5 error.address=<li>Enter your address
6 error.sex=<li>Enter your sex
7 error.age=<li>Enter your age
117
12/03/2003
Example: web.xml
1 <servlet>
2 <servlet-name>action</servlet-name>
3 <servlet-class>
4 org.apache.struts.action.ActionServlet
5 </servlet-class>
6 <init-param>
7 <param-name>application</param-name>
8 <param-value>
9 com.mycompany.mypackage.MyApplication
10 </param-value>
11 </init-param>
12 <!-- ... -->
13 </servlet>
118
When you configure the controller servlet in the web application deployment
descriptor, one of the things you will need to define in an initialization
parameter is the base name of the resource bundle for the application. In the
case described above, it would be
com.mycompany.mypackage.MyApplication.
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
org.apache.struts.action.ActionServlet
</servlet-class>
<init-param>
<param-name>application</param-name>
<param-value>
com.mycompany.mypackage.MyResources
</param-value>
</init-param>
<!-- ... -->
</servlet>
12/03/2003
(Input) Validation
119
Validation: Developer
responsibilities (Struts 1.0)
? Indicate you want input validation as
attributes of <action> element under
<action-mapping> in servlet-config.xml file
– validate=”true”
? Specify the JSP page that needs to be
displayed when validation fails
– input=”/errorpage.jsp”
? Override validate() method within
ActionForm class
– optional 120
(read slide)
12/03/2003
validate() method
? Called by the controller servlet
– after the bean properties have been populated
– but before the corresponding action class's
execute() method is invoked
? Optional
– default method returns null
? Syntax
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request);
121
In addition to the form and bean interactions described above, Struts offers an additional
facility to validate the input fields it has received. To utilize this feature, override the
following method in your ActionForm class:
The validate method is called by the controller servlet after the bean properties have been
populated, but before the corresponding action class's execute method is invoked.
The validate method is called by the controller servlet after the bean properties have been
populated, but before the corresponding action class's execute method is invoked.
12/03/2003
122
12/03/2003
validate() method
? After performing validation
– if no validation error, return null
– If validation error, return ActionErrors
? Each ActionError contains error message key
* Perform the appropriate validations and find no problems -- Return either null
or a zero-length ActionErrors instance, and the controller servlet will proceed to
call the perform method of the appropriate Action class.
* Perform the appropriate validations and find problems -- Return an
ActionErrors instance containing ActionError's, which are classes that contain the
error message keys (into the application's MessageResources bundle) that should
be displayed. The controller servlet will store this array as a request attribute
suitable for use by the <html:errors> tag, and will forward control back to the
input form (identified by the input property for this ActionMapping).
12/03/2003
ActionError Class
? Mechanism used to return errors during
input validation
? Encapsulate errors
– message key used for text lookup from resource
file
? Supports parametric replacement
? ActionErrors is a collection of ActionError
124
12/03/2003
struts-config.xml: Validation
1
2 <!-- ========== Action Mapping Definitions ============ -->
3 <action-mappings>
4
5 <action path="/submit"
6 type="hansen.playground.SubmitAction"
7 name="submitForm"
8 input="/submit.jsp"
9 scope="request"
10 validate="true">
11 <forward name="success" path="/submit.jsp"/>
12 <forward name="failure" path="/submit.jsp"/>
13 </action>
14
15 </action-mappings>
16
17 </struts-config>
125
ActionForm
1 public final class SubmitForm extends ActionForm {
2
3 ...
4 public ActionErrors validate(ActionMapping mapping,
5 HttpServletRequest request) {
6
7 ...
8
9 // Check for mandatory data
10 ActionErrors errors = new ActionErrors();
11 if (lastName == null || lastName.equals("")) {
12 errors.add("Last Name", new ActionError("error.lastName"));
13 }
14 if (address == null || address.equals("")) {
15 errors.add("Address", new ActionError("error.address"));
16 }
17 if (sex == null || sex.equals("")) {
18 errors.add("Sex", new ActionError("error.sex"));
19 }
20 if (age == null || age.equals("")) {
21 errors.add("Age", new ActionError("error.age"));
22 }
23 return errors;
24 }
25 ..
26 } 126
Please note that for each input validation error, ActionError object
is created and then added to ActionErrors array.
12/03/2003
Example: submit.jsp
1 <%@ page language="java" %>
2 <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
3 <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
4 <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
5
6 <html>
7 <head><title>Submit example</title></head>
8 <body>
9 <h3>Example Submit Page</h3>
10
11 <html:errors/>
12
13 <html:form action="submit.do">
14 Last Name: <html:text property="lastName"/><br>
15 Address: <html:textarea property="address"/><br>
16 Sex: <html:radio property="sex" value="M"/>Male
17 <html:radio property="sex" value="F"/>Female<br>
18 Married: <html:checkbox property="married"/><br>
19 Age: <html:select property="age">
20 <html:option value="a">0-19</html:option>
21 <html:option value="b">20-49</html:option>
22 <html:option value="c">50-</html:option>
23 </html:select><br>
24 <html:submit/>
25 </html:form> 127
This is submit.jsp page in which the error information that is collected in the
form of ActionErrors array object gets displayed via <html:errors/> tag.
12/03/2003
128
(read slide)
12/03/2003
Error Handling
129
12/03/2003
130
CustomExceptionHandler (1.1)
? Define a custom ExceptionHandler to
execute when an Action's execute()
method throws an Exception
– Subclass
org.apache.struts.action.ExceptionHandler
– Your execute() method should process the
Exception and return an ActionForward object to
tell Struts where to forward to next
? Example
– Define one for java.lang.Exception for debugging
purpose
132
The default Struts exception handler class creates an ActionError object and
stores it in the appropriate scope object. This allows the JSP pages to use
the errors to inform the user of a problem. If this behavior does not fulfill
your requirements, you are free to plug in one of your own
ExceptionHandler classes.
<global-exceptions>
<exception
key="some.key"
type="java.io.IOException"
handler="com.yourcorp.ExceptionHandler"/>
</global-exceptions>
CustomExceptionHandler (1.1)
? Can be either global or per action
<action ...>
<exception
key="some.key"
type="java.io.IOException"
handler="com.yourcorp.ExceptionHandler"/>
</action>
134
T
12/03/2003
<exception
handler="com.cavaness.storefront.SecurityExceptionHandler"
key="security.error.message"
path="/login.jsp"
scope="request"
type="com.cavaness.storefront.SecurityException"/>
</global-exceptions>
136
View Selection
137
12/03/2003
138
12/03/2003
struts-config.xml: ActionMapping
1
2 <!-- ========== Action Mapping Definitions ============ -->
3 <action-mappings>
4
5 <action path="/submit"
6 type="hansen.playground.SubmitAction"
7 name="submitForm"
8 input="/submit.jsp"
9 scope="request"
10 validate="true">
11 <forward name="success" path="/submit.jsp"/>
12 <forward name="failure" path="/submit.jsp"/>
13 </action>
14
15 </action-mappings>
16
17 </struts-config>
139
12/03/2003
Tools
141
12/03/2003
Struts Console
? Visual editor of
– JSP Tag Library files
– Struts 1.0 and 1.1 config files
– Tiles config file
– Validator config files
? Can be used as a standalone or plugin to
major IDE's
? Download it from
– http://www.jamesholmes.com/struts/console/
142
The Struts Console also plugs into multiple, popular Java IDEs for
seamless management of Struts applications from one central
development tool.
12/03/2003
Struts Console
143
12/03/2003
Struts Console
144
12/03/2003
Struts Console
145
12/03/2003
Struts Console
146
12/03/2003
Struts Console
147
12/03/2003
Struts Console
148
12/03/2003
Struts Console
149
12/03/2003
Struts Console
150
12/03/2003
151