Struts in Action
Struts in Action
Building web applications
with the leading Java framework
Ted Husted
Cedric Dumoulin
George Franciscus
David Winterfeldt
MANNING
Greenwich
(74° w. long.)
For online information and ordering of this and other Manning books, go to
www.manning.com. The publisher offers discounts on this book when ordered in quantity.
For more information, please contact:
Special Sales Department
Manning Publications Co.
209 Bruce Park Avenue Fax: (203) 661-9018
Greenwich, CT 06830 email: [email protected]
©2003 by Manning Publications Co. All rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted,
in any form or by means electronic, mechanical, photocopying, or otherwise, without
prior written permission of the publisher.
Many of the designations used by manufacturers and sellers to distinguish their products
are claimed as trademarks. Where those designations appear in the book, and Manning
Publications was aware of a trademark claim, the designations have been printed in initial
caps or all caps.
Recognizing the importance of preserving what has been written, it is Manning’s policy to have
the books they publish printed on acid-free paper, and we exert our best efforts to that end.
The following figures were adapted from other Manning books: figure 2.1 from Swing by
■
Exploring the Struts architecture 29
3
■
Building a simple application 59
4
■
Configuring Struts components 105
P
ART
2R
AISING
YOUR
FRAMEWORK
.............................
145
5
■
Coping with ActionForms 147
6
■
Wiring with ActionForwards 183
7
Developing applications with Tiles 319
12
■
Validating user input 365
13
■
Localizing content 409
14
■
Using data services with Struts 437
P
ART
4S
TRUTS
BY
EXAMPLE
.........................................
473
15
■
Artimus: pulling out the stops 475
16
■
Other types of frameworks 6
1.3 Enabling technologies 6
Hypertext Transfer Protocol (HTTP) 7
■
Common Gateway
Interface (CGI) 8
■
Java servlets 9
■
JavaServer Pages 10
JSP tags 11
■
JavaBeans 12
■
Model 2 14
1.4 Struts from 30,000 feet 14
Building a simple application 16
■
Jump-starting
development 16
■
Where the rubber meets the road 18
Looking back 24
1.5 Summary 28
viii
CONTENTS
2
Exploring the Struts architecture 29
2.1 Talking the talk 30
2.2 Why we need Struts 30
3
Building a simple application 59
3.1 Strut by Strut 60
Why a logon application? 61
3.2 Touring a logon application 61
Start here 61
■
Screens we’ll see 62
■
The welcome screen 62
The logon screen 62
■
The welcome screen, again 64
The welcome screen, good-bye 64
■
Feature roundup 65
3.3 Dissecting the logon application 65
The browser source for the welcome screen 65
■
The JSP source for
the welcome screen 66
■
The configuration source for the welcome
screen 69
■
The browser source for the logon screen 70
The configuration source for the logon screen 73
The LogonSubmit source 73
■
The LogonForm source 74
■
Configuring the ActionErrors 100
■
Compiling
and testing the logon page 101
■
Amending the welcome
page 101
■
The Struts ActionForward Action 102
3.5 Summary
104
4
Configuring Struts components 105
4.1 Three XMLs and a Properties file
106
The rest of the family 106
4.2 The web application deployment descriptor
107
The web.xml file 107
■
ActionServlet parameters 110
4.3 The Struts configuration
113
Details, details 113
■
Change management 115
The principle of Protected Variation 115
4.4 The Struts configuration elements
116
4.11 Configuring modular applications
139
Divide and conquer 140
■
Prefixing pages 142
Retrofitting a configuration 142
4.12 Sharing the Struts JAR
142
4.13 Summary
143
x
CONTENTS
P
ART
2R
AISING
YOUR
FRAMEWORK
.......................... 145
5
Coping with ActionForms 147
5.1 Garbage in, treasure out 148
ActionForm requirements 150
5.2 The many faces of an ActionForm 151
The ActionForm as a field harvester 151
■
The ActionForm as a
data buffer 153
■
Nesting a mutable
value object 167
■
Setting an immutable value object 168
Setting a mutable value object 169
■
Using a factory method 170
Passing a Map 171
■
Transferring values by reflection 173
Using an adaptor class 178
5.7 BaseForm 179
SessionLocale 180
■
Dispatch 180
■
Autopopulation 181
BaseMapForm 181
5.8 Summary 182
6
Wiring with ActionForwards 183
6.1 What ActionForwards do 184
6.2 How ActionForwards work 185
Forward versus redirect 185
6.3 Global and local forwards 187
6.4 Runtime parameters 188
CONTENTS
xi
Adding parameters in the page 188
■
The input property 200
The parameter property 201
■
The attribute property 202
The prefix and suffix properties 202
■
The unknown
ActionMapping 203
7.3 Nested components
203
Local forwards 203
■
Local exceptions 204
7.4 Rolling your own ActionMapping
204
7.5 Summary
205
8
Working with Action objects 207
8.1 Ready, set, action!
208
8.2 Getting it done with Action objects
208
What are Actions? 209
■
When are Actions called? 210
What do Actions do? 211
■
What does an Action look like? 217
9
Extending ActionServlet 255
9.1 Where’s the beef? 256
The servlet’s Gang of Three 258
9.2 The RequestProcessor 259
The process method 260
■
processRoles 260
9.3 The ExceptionHandler 262
9.4 PlugIn 263
9.5 Summary 264
P
ART
3B
UILDING
YOUR
PAGES
................................. 265
10
Displaying dynamic content 267
10.1 Tag—you’re it 268
JSP tags—what are they good for? 268
■
Struts and JSTL 271
Struts tags and MVC 273
10.2 Working with tag extensions 274
How are tag extensions written? 274
■
■
Template
consequences 321
■
Using templates 322
Combining templates, Tiles, and Struts 323
11.2 Building a layout template 324
But what is a tile? 326
■
Deploying a Tiles template 328
Adding a style sheet 329
■
Templates and MVC 330
11.3 Tiles Definitions 331
Declaring Definitions 331
■
JSP declarations 332
Configuration file declarations 335
Using Definitions as ActionForwards 338
11.4 Tile attributes 339
useAttribute 340
■
importAttribute 340
■
put 341
putList and add 343
11.5 Migrating an application to Tiles 343
Setting up the Tiles framework 344
■
Testing the default
■
The mask validator 380
The range validator 381
■
The maxLength validator 382
The minLength validator 383
■
The byte, short, integer, long,
float, and double validators 383
■
The date validator 383
The creditCard validator 384
■
The email validator 384
12.4 Resource bundles 384
The default bundle 385
■
Default validator messages 385
Custom validator messages 386
12.5 Configuration files 387
12.6 Validator JSP tags 388
12.7 ValidatorForm and ValidatorActionForm 391
12.8 Localized validations 392
12.9 Pluggable validators 392
Creating pluggable validators 392
12.10 Techniques 394
Multipage validations 395
■
Cancel buttons 395
■
■
How Java internationalization works 412
13.2 Struts’ internationalized components 417
Session Locale attribute 417
■
MessageResources 418
The default resource bundle 419
■
ActionErrors 421
ActionMessages 421
■
Locale-sensitive JSP tags 422
CONTENTS
xv
13.3 Localizing a Struts application 427
Enabling localization 428
■
Using the framework Locale
object 430
■
Placing labels and messages in Properties files 431
Creating language-specified Properties files 431
■
Specifying an
appropriate key in localization-aware components 431
■
Using
<bean:message> with other components 431
13.4 Localizing other components 432
Localizing the Struts Validator 432
Executing
ProcessBeans 448
■
Accessing data services 449
■
Following
a typical flow 451
■
Coding a business activity 451
ProcessBeans as a persistence layer 454
■
Using other
persistence layers 455
14.4 Using result objects 455
ResultList methods 455
14.5 Using helper Actions 457
14.6 Using Lucene 458
searchProperties redux 459
14.7 Using content syndication 464
Digesting RSS 464
■
Retrieve and render 465
Syndicating RSS 466
14.8 Using EJBs with Struts 468
Session Facade 469
■
Data transfer objects 470
Implementation patterns 470
14.9 Summary 471
xvi
15.5 ArtimusServlet 484
Our subclass 486
■
Our String tokens 486
Our extension point 486
15.6 The application and SQL Properties files 487
15.7 index.jsp 488
15.8 Global forwards 489
15.9 /find/Recent 492
extends bean 494
■
super.execute 495
■
getArticles 495
Access.findByLast and ResultList 495
■
ProcessResult 497
ProcessAction 498
15.10 tiles.xml and Article.jsp 499
useAttribute 501
■
baseStyle 501
■
title 502
■
Tiles 502
15.11 result.jsp 504
The legend 506
■
isResult? 506
/menu/Find 528
■
/find/Last 529
/menu/Contributor 530
■
/menu/Manager 531
15.17 Summary 532
16
Redux: migrating to Struts 1.1 533
16.1 Next station, Struts 1.1 534
Struts 1.1 feature roundup 535
■
Features we can use 538
16.2 Baseline changes 538
Tiles in Struts 1.1 540
■
Validator in Struts 1.1 543
ReloadAction in Struts 1.1 544
■
Other baseline changes to
web.xml and struts-config.xml 544
■
message.jsp (1.1) 545
form.jsp (1.1) 546
■
MenuCreate (1.1) 547
■
Onward 548
16.3 Discretionary changes 548
Form to DynaActionForm 549
Deploying the Velocity
servlet 567
■
The toolbox configuration file 568
17.7 Setting up struts-config 569
17.8 Summary 570
xviii
CONTENTS
A
Design patterns 573
A.1 A brief history of design patterns 574
The Gang of Four 575
■
J2EE Blueprints 575
Core J2EE Patterns 576
A.2 Why patterns are important 576
A.3 What patterns won’t do 577
A.4 Struts—a Who’s Who of design patterns 577
The Service to Worker pattern 578
■
The Singleton pattern 579
The Session Facade pattern 579
■
Value Object / Value Object
Assembler patterns 579
■
The Composite View pattern 580
The Synchronizer Token pattern 580
■
The Decorator
index 624
xix
foreword
You’re holding in your hands the result of the hard labor of some of Struts’
most important developers. Ted, Cedric, George, and David have done an
outstanding job of explaining how Struts works
and
how it is used in prac-
tice. If you’re a new developer,
Struts in Action
will make it much easier for
you to learn the framework and quickly put it to work on your own projects.
But even the most seasoned Struts developer is certain to learn something
new by reading this book.
I became interested in web application development in the late 1990s. I
was ready for a language that would let me address one of the most problem-
atic aspects of advanced development—the need to free up dynamically allo-
cated memory when I was through with it.
In the beginning, all I really hoped to accomplish was to make life a little
easier for a few developers building web applications. The incredible popu-
larity that Struts has achieved since then means that I wasn’t the only one
who struggled—Struts fills a very common need.
When the early public drafts of the JavaServer Pages specification (ver-
sions 0.91 and 0.92) became available, one of the intriguing concepts
embedded in these documents was the idea of two basic design styles for
JSP
-
based applications. A
Model 1
fected tier immediately.
While all of this intellectual investigation of web application architectures was
going on, my professional career was leading me in interesting directions as well. I
was working for a company that provided information services to the long-haul
trucking industry in the United States, and we wanted to expand this service into
Europe. This created the need to deal with multiple languages and international-
ization. I quickly whipped up a simple controller servlet that let me implement
the basic
MVC
architecture, but it didn’t address, say, the need to include a Select
Language control.
Our first effort at internationalization started me down the path of creating
“user interface components” using the new custom tags facilities of
JSP
1.1—which
led ultimately to things like the
<bean:message>
tag that is a part of Struts today.
Shortly after this, I joined Sun Microsystems to work with the Tomcat servlet
and
JSP
container (I was the primary architect of the Catalina servlet container that
is the basis of Tomcat 4). A large portion of this development took place in the
open source community at Apache, as part of the Jakarta Project—initiated when
Sun contributed the source code of what had been the servlet and
JSP
reference
implementation to Apache in 1999. However, I was never happy with the state of
Model 2-oriented application designs, so I resolved to do something about it.
FOREWORD
Enjoy!
Craig McClanahan
Portland, Oregon
xxiii
preface
By 2000, Java had come of age. The dust from the early hype had settled and
some very interesting development tools and libraries were cropping up. I
had already been writing web applications for several years. Like many devel-
opers, I started with simple apps in JavaScript and Perl. A powerful combina-
tion, but a bear to maintain. Next came ColdFusion, which was much more
powerful but at the time too expensive for my client’s pocketbook. I even
tried FileMaker Pro, which was fun, but very, very proprietary.
My major client for this succession of web applications was a public broad-
casting station. The station’s major fund-raiser was (and still is) an annual auc-
tion. Local vendors donate goods and services, and people buy them at
auction to support the station. Of course, we were quick to post images of the
high-end items on the web site:
objets d’art
, a car, vacation packages, auto-
graphed items, and so forth.
In 1998, we used an application written with JavaScript and Perl to accept
“pre-bids” on the high-end items. The actual bidding on these items took
place in live television bid-downs. All the application really did was set the
starting bid price. In 1999, we accepted both online and phone bids right up
to when the item sold. Each year, I used a different platform to put the auction
online, because each year I found that the platform didn’t meet all my needs.
Since we were already satisfied users of the Apache
HTTPD
server, I
a Struts forum and
FAQ
, and we moved the main Struts
FAQ
to JGuru, where I con-
tinue to manage it.
Around the same time, publishers started to take notice of Struts, and offers
began to arrive in my mailbox. After consulting with some of the other Struts
Committers, we eventually decided to work with Manning Publications. Like
Apache, Manning has a longstanding commitment to quality. While we wanted to
get a Struts book out as soon as we could, we also wanted to be sure that it would
be the best book possible.
The result is Struts in Action. It is very much a “team book.” David Winterfeldt,
the creator of the Struts Validator, was kind enough to draft our Validator chapter.
Likewise, Cedric Dumoulin, the creator of Tiles, drafted the Tiles chapter. George
Franciscus provided the critical chapter 1 of the book, which is designed to help
bring newbies into the fold. We even dragged a foreword out of Craig (who would
“rather be programming”). Of course, other Struts developers and Committers