0% found this document useful (0 votes)
2K views800 pages

Web Development Using JSP

Web Development with JavaServer Pages is the second edition of a book by duane fields. Fields, mark kolb and shayn bayer are the authors. No part of this publication may be reproduced without prior written permission.

Uploaded by

Kaushal Shakya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2K views800 pages

Web Development Using JSP

Web Development with JavaServer Pages is the second edition of a book by duane fields. Fields, mark kolb and shayn bayer are the authors. No part of this publication may be reproduced without prior written permission.

Uploaded by

Kaushal Shakya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Web Development with JavaServer Pages

Web Development with

JavaServer Pages
SECOND EDITION
DUANE K. FIELDS MARK A. KOLB SHAWN BAYERN

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 Greenwich, CT 06830

Fax: (203) 661-9018 email: [email protected]

2002 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 Mannings policy to have the books we publish printed on acid-free paper, and we exert our best efforts to that end.

Library of Congress Cataloging-in-Publication Data

Manning Publications Co. 209 Bruce Park Avenue Greenwich, CT 06830

Copyeditor: Elizabeth Martin Typesetter: Tony Roberts Cover designer: Leslie Haimes

Printed in the United States of America


1 2 3 4 5 6 7 8 9 10 VHG 04 03 02 01

To Kris for her patience, encouragement and good humor that made this project possible D.K.F. For Megan, Andrew, and Jean your presence is my strength, and your love my inspiration M.A.K. To my parents For teaching me everything I know (except JSP) S.B.

brief contents
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
I

Introduction

1 17

HTTP and servlets First steps 30 46

How JSP works

Programming JSP scripts

65 101

Actions and implicit objects Using JSP components 129

Developing JSP components Working with databases 198

165

Architecting JSP applications An example JSP project 272

229

Introducing filters and listeners Applying filters and listeners Deploying JSP applications

318

334 384 418 470

Performing common JSP tasks Generating non-HTML content

viii

BRIEF CONTENTS

17 18 19 20 A B C D E F

JSP by example

493 529 582

Creating custom tags

Implementing advanced custom tags Validating custom tag libraries Changes in the JSP 1.2 API 621

669 676

Running the reference implementation Incorporating Java applets JSP resources 697 702 718 683

JSP syntax reference JSP API reference

contents
preface to the second edition preface to the first edition acknowledgments about this book xxxi xxv xxix xxxiii xxxviii

about the authors

authors online xxxix about the cover illustration xl

Introduction
1.1 1.2

1
2
I

What is JSP?

Dynamic content on the web 2 Why dynamic content? 3 Common Gateway Interface 4 Template systems 5 Java on the Web 8 How XML fits in 11
I I I

1.3

The role of JSP 13 The JavaBeans component architecture 13 JSP and Java 2 Platform Enterprise Edition

15

CONTENTS

2 3

HTTP and servlets 17


2.1 2.2 The Hypertext Transfer Protocol (HTTP) 18 HTTP basics 18 GET versus POST 21
I

Java servlets 23 How a web server uses servlets 24 The anatomy of a servlet 24 A servlet example 26
I I

First steps 30
3.1 3.2 Simple text 31
I

Dynamic content 32 Conditional logic 33 Iteration Non-HTML output 37


I

34

3.3 3.4

Processing requests and managing sessions 38 Accessing request parameters 38 Using sessions Separating logic from presentation 41 Reusing logic with JavaBeans 42 Abstracting logic with custom tags 44 Review of examples 45

39

3.5

How JSP works


4.1

46

The structure of JSP pages 47 Directives and scripting elements 47 Standard and custom actions 48 Behind the scenes 52 Translation to servlets 52
I

4.2 4.3

Translation versus execution


I

54

What the environment provides 56 Automatic servlet generation 56 Buffered output Session management 59 Exception handling 63 Implicit objects 64 Support for JavaBeans and HTML forms 64
I I

57

CONTENTS

xi

Programming JSP scripts


5.1 5.2 5.3 Scripting languages JSP tags 68
I

65

66

JSP directives 68 Page directive 68 Include directive Tag library directive 82 Scripting elements 83 Declarations 84 Expressions
I

80

5.4 5.5

88

Scriptlets

91

Flow of control 93 Conditionalization 93 Exception handling 94


I

Iteration 94 A word of caution 98

97

5.6

Comments 97 Content comments 98 JSP comments Scripting language comments 99

6 7

Actions and implicit objects


6.1

101
I

Implicit objects 102 Servlet-related objects 104 Input/Output 105 Contextual objects 112 Error handling 120
I

6.2

Actions 121 Forward 122 Include Bean tags 128


I

125

Plug-in

128

Using JSP components


7.1

129
I

The JSP component model 130 Component architectures 130 Benefits of a component architecture 131 Component design for web projects 132 Building applications from components 133
I I

xii

CONTENTS

7.2 7.3

JavaBean fundamentals 135 The different types of JavaBeans

138
I

JSP bean tags 140 Tag-based component programming 140 Accessing JSP components 142 Initializing beans 150 Controlling a beans scope 157
I

Developing JSP components 165


8.1 What makes a bean a bean? 166 Bean conventions 166 The bean constructor 167 Defining a beans properties 168 Indexed properties 172 Implementing bean properties as cursors 176 Boolean properties 178 JSP type conversion 179 Configuring beans 181
I I I I I I

8.2

Some examples 182 Example: a TimerBean 182 A bean that calculates interest
I

184

8.3

Bean interfaces 189 The BeanInfo interface 189 The Serializable interface 190 The HttpSessionBindingListener interface 190 Other features of the Bean API 191
I

8.4

Mixing scriptlets and bean tags 192 Accessing beans through scriptlets 192 Accessing scriptlet created objects 193

Working with databases


9.1

198
200
I

JSP and JDBC 199 JNDI and data sources

Prepared statements

201

CONTENTS

xiii

9.2

Database driven JSPs 202 Creating JSP components from table data 202 JSPs and JDBC data types 205 Maintaining persistent connections 208 Handling large sets of results 211 Transaction processing 216
I I

9.3

Example: JSP conference booking tool 217 Project overview 217 Our database 218 Design overview 218
I

10

Architecting JSP applications


10.1

229

Web applications 230 Web application flow 232 Architectural approaches 233 Page-centric design 233 Role-based pages 233 Managing page flow with action targets 236 Building composite pages 238 Limitations of the page-centric approach 241
I I

10.2

10.3

Servlet-centric design 242 Hello, Worldwith servlets 243 JSP and the servlet API 244 Servlets for application control 247 Servlets for handling application logic 248 Servlets as single entry points 249 Handling errors in the servlet 252 Example: servlet-centric employee browser 253 EmployeeBean 255 FetchEmployeeServlet 258 JSP employee list 261 JSP page viewer 262
I I I I I I I

10.4

Enterprise JavaBeans 263 What are Enterprise JavaBeans? 263 JavaBeans vs. EJBs 264 Application servers and EJB containers 264 Application design with EJBs 265
I I

xiv

CONTENTS

10.5

Choosing an appropriate architecture 266 Application environment 267 Enterprise software requirements 268 Performance, scalability, and availability 269 Technical considerations 269 Organizational considerations 270
I I I

11

An example JSP project


11.1

272
I

An FAQ system 273 Project motivations 273 Application requirements Application modules 275 Building an FAQ component 276 The storage module 278 Database schema 279 The FaqRepository class Storage module exceptions 285
I

273

11.2

279

11.3

The administration module 286 The administration servlet 287 The main menu Adding an FAQ 297 Deleting an FAQ 300 Updating an FAQ 306
I I I

293

11.4

The web access module 311 The FaqServlet 312 Viewing a single FAQ 313 Viewing all the FAQs 314 A table of contents view Plain text view 317
I

315

12

Introducing filters and listeners 318


12.1 12.2 Life-cycle event listeners 319 Session listeners 319 Application listeners
I

324

Filters 326 How filters work 327 Wrapper classes 332 Using filters and listeners

Filter classes 333

330

12.3

CONTENTS

xv

13

Applying filters and listeners


13.1 13.2 Application description 335

334

User authentication 337 User account representation 337 User management interface 338 User management implementation 339
I I

13.3

Web authentication 341 Session interactions 341 Login servlet 344 Login pages 350 Content pages 353 Logout servlet 357 Logout pages 358
I I I

13.4 13.5

Access control filters 360 Authentication filter 361

Role filter

364

Logging listener 368 HttpSessionListener methods 369 HttpSessionAttributeListener methods


I

369

13.6

Content filter 372 Filter methods 373 Response wrapper inner class 375 Output stream inner class 376 More filter methods 377 Filter results 380 Other content filters 381
I I

14

Deploying JSP applications 384


14.1 14.2 14.3 This means WAR 385 WAR is XML 386 Waging WAR
I

389 396

The art of WAR 390 WAR materiel 390

Drafting deployment descriptors 415

Maintaining a WAR footing

xvi

CONTENTS

15

Performing common JSP tasks 418


15.1 Handling cookies 419 Managing cookies 419 The Cookie class Example 1: setting a cookie 421 Example 2: retrieving a cookie 422
I I

420

15.2

Creating error pages 425 An erroneous page 426 Data collection methods 427 Sending electronic mail 432 The error page 433
I

15.3 15.4

Mixing JSP and JavaScript


I

437

Building interactive interfaces 441 Sticky widgets 441 Utility methods 442 The example form 443 Setting up the form 445 Text and hidden fields 446 Text areas 447 Radio buttons 447 Select boxes 448 Check boxes 448 Form source 449
I I I I

15.5

Validating form data 451 Client- and server-side validation 451 Example: server-side validation 452 Building a shopping cart 458 Overview 459 The catalog page 460 ShoppingCartItem and InventoryManager The ShoppingCart bean 464 Displaying the shopping cart 466
I

15.6

460

15.7

Miscellaneous tasks 467 Determining the last modification date Executing system commands 468

467

CONTENTS

xvii

16

Generating non-HTML content


16.1

470
I

Working with non-HTML content 471 The importance of MIME 471 Controlling the content type 472 Detecting your client 472 Designing multiformat applications 473 Controlling the file extension 474
I

16.2

Text content formats 475 Plain text output 475 WYGIWYG output (what you generate is what you get) 476
I

16.3 16.4 16.5

XML documents 477 Creating voice XML documents External content 482 JSP style sheets 483
I

479 485 489

JavaScript
I

Advanced content formats Excel spread sheets 488

487 Code generation

17

JSP by example
17.1 17.2 17.3

493
I

A rotating banner ad 494 The BannerBean 494 Using the bean A random quote generator 497 The QuoteBean 497 Using the bean
I

495 498 502

The Tell a Friend! sticker 499 The sticker 500 The MailForm page Sending the mail 503
I I

17.4

A JSP Whois client 505 The Whois protocol 505 Requirements and design considerations 507 The WhoisBean 507 Building the front end 515
I

17.5

An index generator 517 A basic implementation Going further 525

518

An improved version

520

17.6

A button to view JSP source 525 Displaying the source 525 Limitations of the view source program 527 Adding a view source button \to a page 527 Viewing source through a bookmark
I I I

528

18

Creating custom tags 529


18.1 18.2 18.3 Role of custom tags 530 531
I

How tag libraries work

Tag library descriptors 535 Library elements 535 Validator elements 537 Listener elements 538 Tag elements 538 Variable elements 540 Attribute elements 541 Example element 543
I I

18.4

API overview 544 Tag handlers 544 Helper classes 556 Example tag library Content substitution Tag attributes 563

Tag handler life-cycle 550 Auxiliary classes 559

18.5 18.6 18.7 18.8 18.9 18.10

559 560

Content translation 567 URL rewriting 568 HTML encoding


I

572

Exception handling To be continued

575

580

CONTENTS

xix

19

Implementing advanced custom tags 582


19.1 19.2 19.3 19.4 Tag scripting variables 583 Example tag 583 Scripting variable JavaBean
I

585

Flow of control 587 Conditionalization 588 Interacting tags 613 Interaction mechanisms The final ingredient 619

Iteration
I

595 616

614

Index tag

20

Validating custom tag libraries 621


20.1 20.2 Two representations of JSP
I

622

JSP pages as XML documents 624 The root element 625 Template text 626 Scripting elements 627 Request-time attribute values Directives and actions 629 Sample page 629
I I

627

20.3 20.4

Tag library validation

631
I

Example validators 634 Copying validator 635 Script-prohibiting validator Error handling 642 Content handler 645 Nesting validator 651
I

638

20.5

Packaging the tag library 660 Packaging a single library 661 Packaging multiple libraries 662 For further information 666

20.6

Changes in the JSP 1.2 API


A.1 A.2 Introduction 669

669

Changes to the API 670 Java 2, Version 1.2 now a requirement

670

xx

CONTENTS

Servlet API 2.3 required 670 XML syntax now fully supported 670 Determining the real path 671 Redirects are not relative to the servlet context 671 Restricted names 671 Page encoding attribute 671 Flush on include no longer required 671
I I I

A.3

Web application changes 672 New 2.3 web application DTD 672 Handling of white space 672 Resolving path names in the web.xml file 672 Request mappings 672 Dependency on installed extensions 672
I I I

A.4

Custom tag improvements 673 Translation time validation 673 New tag interfaces 673 Changes to the TLD 673
I I

A.5

JavaBean changes 674 Bean tags cannot implicitly access scriptlet objects Fully qualified class names required 674 New servlet features 674 Servlet filters 675 Application events
I

674

A.6

675

B C

Running the reference implementation


B.1 B.2 B.3 Prerequisites 677 677 681 Downloading and installing Tomcat Web applications and Tomcat

676

Incorporating Java applets 683


C.1 C.2 Browser support for Java 683
I

The plug-in action 685 Required attributes 685 Optional attributes Parameters 688 Fallback text 689
I

687

C.3

Example: applet configuration

690

CONTENTS

xxi

JSP resources
D.1 D.2 D.3 D.4 D.5 D.6 D.7 D.8

697
697 697 698 699

Java implementations JSP-related web sites JSP containers 698 JSP FAQs and tutorials

Java application servers with JSP support JSP development tools 700 700 700 Tools for performance testing Mailing lists and newsgroups

JSP syntax reference 702


E.1 E.2 E.3 E.4 E.5 E.6 E.7 E.8 E.9 E.10 E.11 E.12 E.13 E.14 Content comments JSP comments 703 704 705 707 706 <jsp:declaration> 702

<jsp:directive.include> <jsp:directive.page> <jsp:directive.taglib> <jsp:expression> <jsp:forward> <jsp:include> <jsp:plugin> <jsp:scriptlet> <jsp:useBean> <jsp:getProperty> 711 712 713 714 715 708 710 709

<jsp:setProperty>

xxii

CONTENTS

JSP API reference 718


F.1 F.2 JSP implicit objects 719 Package javax.servlet 719 Interface Filter 719 Interface FilterChain 719 Interface FilterConfig 720 Class GenericServlet 720 Interface RequestDispatcher 720 Interface servlet 721 Interface ServletConfig 721 Interface ServletContext 721 Interface ServletContextAttributeEvent 722 Interface ServletContextAttributeListener 722 Interface ServletContextEvent 722 Interface ServletContextListener 723 Class ServletException 723 Class ServletInputStream 723 Class ServletOutputStream 724 Interface ServletRequest 724 Class ServletRequestWrapper 725 Interface ServletResponse 726 Class ServletResponseWrapper 726 Interface SingleThreadModel 727 Class UnavailableException 727
I I I I I

F.3

Package javax.servlet.http 727 Class cookie 727 Class HttpServlet 728 Interface HttpServletRequest 729 Class HttpServletRequestWrapper 730 Interface HttpServletResponse 730 Class HttpServletResponseWrapper 732 Interface HttpSession 733 Interface HttpSessionActivationListener 733 Interface HttpSessionAttributeListener 733 Class HttpSessionBindingEvent 734
I

CONTENTS

xxiii

Interface HttpSessionBindingListener 734 Class HttpSessionEvent 734 Interface HttpSessionListener 735 Class HttpUtils
I

735

F.4

Package javax.servlet.jsp 735 Interface HttpJspPage 735 Class JspEngineInfo 736 Class JspException 736 Class JspFactory 736 Interface JspPage 737 Class JspTagException 737 Class JspWriter 737 Class PageContext 738
I I I I

F.5

Package javax.servlet.jsp.tagext 740 Class BodyContent 740 Interface BodyTag 740 Class BodyTagSupport 740 Interface IterationTag 741 Class PageData 741 Interface Tag 741 Class TagAttributeInfo 742 Class TagData 742 Class TagExtraInfo 743 Class TagInfo 743 Class TagLibraryInfo 744 Class TagLibraryValidator 744 Class TagSupport 744 Class TagVariableInfo 745 Interface TryCatchFinally 745 Class VariableInfo 745
I I I I I I I

index

747

preface to the second edition


When the first edition of Web Development with JavaServer Pages was published some eighteen months ago, URLs ending with a .jsp file extension were a novelty. Today, this is a commonplace occurrence for millions of web surfers. JSP has been widely adopted, and we are very pleased to have played a supporting role in its popularization. We are likewise very pleased with the reception of the first edition. As one of the first JSP books on the market, we knew we were taking a risk. Its clear from the response, however, that JSP addresses a serious need in the development community, resulting in an equally serious need for good reference material. By presenting such reference material from the practitioners point of view, we appear to have struck a nerve. The first edition received both critical and popular acclaim as one of the leading books on the subject, and our thanks go out to all of the readers who contributed to its success. Of course, the books success is due in no small part to the success of JSP itself. JavaServer Pages technology has experienced a rapid adoption in the past year or so, anxiously embraced by the teeming millions of Java and web developers who had been clamoring for a standard mechanism for generating dynamic web content. At the time the first edition was published, there were only a handful of application servers supporting JSP 1.0, and even fewer supporting version 1.1. As a required component of the J2EE (Java 2 Enterprise Edition) platform, however, there are now dozens of commercial application servers with full JSP support. Tool support is another area that has thankfully experienced significant growth. Today,

xxvi

PREFACE TO THE SECOND EDITION

web developers can take advantage of a wide array of editors, IDEs, and code generators with built-in support for JSP. As with any Internet technology though, JSP continues to evolve. In September 2001 Sun released the JavaSer ver Pages 1.2 and the Java Servlets 2.3 specifications. These APIs were updated to provide several new features, clarify some outstanding issues from the previous specifications, and pave the way for improved tool support. Among those new features are full XML support, servlet filters and life-cycle event handlers, and enhanced validation of custom tag libraries. Readers interested in a quick overview of the new APIs are directed to Appendix A. Given these changes to the specifications, as well as our desire to fix a few gaffes from the first edition, we felt an obligation to our readersboth past and future to start work on a second edition. As was true of the first edition, our goals for this new edition are twofold. In addition to updating the text to address the changes and enhancements introduced in JSP 1.2, we have also revised and expanded the opening chapters to provide a gentler introduction to JSP and the underlying technologies (such as HTTP and servlets) for those who are new to web development. At the turn of the millennium, it was safe to assume that anyone brave enough to be dabbling with JSP already knew their way around the underlying protocols. JSP is now an established platform in its own right, and it was felt that providing a bit more context for understanding the inherent properties of that platform was more than justified. Weve also added more examples, including the much-requested shopping cart, as well as an entire chapter on creating non-HTML content. JSP was always intended as a general-purpose mechanism for generating dynamic content of all kinds, not just HTML. With the recent excitement revolving around XML and other text-based document formats, full coverage of this topic was a given for the second edition. A pair of new chapters focus on servlet filters and life-cycle event listeners, two new features of the Servlet 2.3 API that are equally applicable to JSP applications. Filters enable developers to layer new functionalitysuch as on-the-fly encryption, compression, translation, or authenticationatop existing servlets and JSP pages, without having to change the original code. Event listeners provide applications with the ability to monitor (and therefore take advantage of) the activity of the underlying servlet or JSP container more closely. A chapter-length example demonstrates how both of these features may be leveraged to simplify the implementation of key application behaviors.

PREFACE TO THE SECOND EDITION

xxvii

As we continue to gain experience in real-world web development projects, we are often exposed to new techniques for architecting JSP applications. In the interest of keeping readers abreast of such alternatives, new material in chapter 10 introduces the concept of action targets, an extension to the page-centric design approach presented in the first edition. In keeping with the industrys growing interest in custom tag libraries, weve expanded our coverage of this topic, as well. There are now three chapters dedicated to using, developing, validating, and deploying custom tags. New examples are included to demonstrate JSP 1.2 enhancements, and new custom tag libraries are available from our companion web site, http://www.taglib.com/. Observant readers will notice an additional name on the cover of this second edition, Shawn Bayern. Shawn, an active member of the Java Community Process, is the reference-implementation lead for the JSP Standard Tag Library, a collection of general-purpose custom tags that will ultimately be supported by all JSP containers. He lends us his unique insight into JSPs place in the technology spectrum, and we are confident that readers will value his contributions to this book as much as we do. Welcome then, to readers both new and returning. We hope that this second edition will prove itself a worthy successor to the original Web Development with JavaServer Pages. And we look forward to uncovering even more .jsp file extensions as we surf the web, hunting for the next generation of killer web applications.

preface to the first edition


In late 1998 we were asked to develop the architecture for a new web site. Our employer, a vendor of enterprise software for system and network management, had an unconventional set of requirements: that the site be able to provide product support data customized for each customer; and that the support data be tailored to the software the customer had already purchased, as well as the configurations already selected. Of course, the web site needed to look sharp and be easy to navigate. Management software, which of necessity must be flexible and support a wide range of operating conditions, tends to be very complex. This particular software was targeted at Internet and electronic commerce applications, so using the web as a major component of product support was a natural fit. By personalizing web-based support for each customer, this inherent complexity would be reduced, and the customer experience improved. But how to accomplish that ... and how to do it within the time constraints the project required? What we needed was an architecture that would give everyone on the team, both the designers and the programmers, as much freedom as possible to work unhindered in the limited time available. The ability of these two groups to progress independently, without costly rework, was crucial. A solution that could provide dynamic content as an add-on to otherwise conventional HTML files clearly was the best approach. We briefly considered, then just as quickly dismissed, the notion of building our own dynamic context system. There just wasnt enough time to deliver both a publishing system and a web site.

xxx

PREFACE TO THE FIRST EDITION

At the time we were already familiar with Java servlets. Indeed, servlets were a key element of the architecture of the product to which this site would be devoted. We mulled over using servlets for the site itself but were concerned with how this would affect those responsible for the content, graphics, and layout of the site. As we researched the problem further we were reminded of an ongoing initiative at Sun Microsystems called JavaServer Pages (JSP). JSP was still being refined, and Version 1.0 was months away. However, it was intended to become a standard Java technology, and it used Java servlets as its foundation. It also allowed us to implement dynamic content on top of standard HTML files. Best of all, it worked! As we became more familiar with JSP, we found that it worked very well indeed. As is often the case, there were some rough spots as the JSP specification went through major changes along the way. Hair was pulled, teeth were gnashed, lessons were learned. Fortunately, we obtained a great deal of help from the JSP community the developers at Sun and the other JSP vendors, as well as our fellow early adopters. This book thus serves a twofold purpose. First, we hope to help future users of JSP by sharing the hard-earned lessons of our experience. We offer them what we hope is a helpful guide to the current JSP feature set: JavaServer Pages is now at version 1.1 and the need for published reference material has long been recognized. Second, we offer this book as an expression of gratitude to the current community of JSP developers in return for the assistance they provided when we needed it. Thanks to all.

acknowledgments
We recognize the support and understanding of the many people who helped make this book possible. We acknowledge: T. Preston Gregg, the former development manager of Duane and Mark, for allowing them to make the early leap to a JSP architecture, before the technology was considered ready for prime time. This head start was painful at times, but ultimately proved a boon to their web development projects. It also gave them the experience necessary to develop this text, for which they are equally grateful. Other colleagues who advised them during the writing of the this book include Kirk Drummond and Ward Harold. Pierre Delisle for encouraging and guiding Shawns efforts in the Java community. Merci pour tout, mon ami. Shawn also wishes to thank his colleagues at Yale, especially Andy Newman and Nicholas Rawlings. The JSP design team at Sun Microsystems, especially Eduardo Pelegr-Llopart. His assistance and attentiveness to our queries was critical to the success of this effort. The teeming millions of Java and JSP developers who continue to offer their insights and expertise to the development community through their unselfish participation in mailing lists, newsgroups, and the web. Double thanks to everyone participating in the Jakarta and Apache projects for their outstanding work in the Open Source arena. You are all instrumental to the continuing success of Java and establishing it as a lingua franca for Internet development. Our publisher, Marjan Bace, for giving us this opportunity; our editor, Elizabeth Martin, for her yeomans effort in polishing this manuscript; and our typesetter,

xxxii

ACKNOWLEDGMENTS

Tony Roberts. Their insights, guidance, and expertise were invaluable to the completion of this book. Our reviewers, whose comments, criticisms, and commendations advised, corrected and encouraged us. Our deep appreciation is extended to Michael Andreano, Dennis Hoer, Vimal Kansal, Chris Lamprecht, Max Loukianov, James McGovern, Dave Miller, Dr. Chang-Shyh Peng, Anthony Smith, and Jason Zhang. Special thanks to Lance Lavandowska for his technical edit of the final manuscript. Our friends, families, and coworkers for their unfailing support, assistance, and tolerance throughout the writing process. Without them this book could not have been possible.

about this book


JavaServer Pages is a technology that serves two different communities of developers. Page designers use JSP technology to add powerful dynamic content capabilities to web sites and online applications. Java programmers write the code that implements those capabilities behind the scenes. Web Development with JavaServer Pages is intended to present this technology to both groups. It is impossible in a book of this length to provide all the background information required by this subject, and, for this reason, we do not attempt to describe the HTML markup language. It is assumed that the reader is sufficiently familiar with HTML to follow the examples presented. It is likewise assumed that the reader is familiar with URLs, document hierarchies, and other concepts related to creating and publishing web pages. We also do not include a primer on the Java programming language. As with HTML, there is a wealth of reference information available on the language itself. Programmers reading this book are assumed to be familiar with Java syntax, the development cycle, and object-oriented design concepts. A basic understanding of relational database technology in general, and JDBC in particular, is recommended but not required. Our focus here, then, is strictly on JavaServer Pages. The interaction between JSP and the technologies already mentionedHTML, Java, and databaseswill of course be covered in depth. For the benefit of readers not so well versed in the enabling technologies upon which JSP depends, however, this second edition features new coverage of HTTP, the protocol that web browsers and web servers use to

xxxiv

ABOUT THIS BOOK

communicate with one another, and Java servlets, the foundational technology for server-side Java applications. The topics covered are as follows: Chapter 1 introduces JavaServer Pages (JSP) and presents a brief history of web development. JSP is contrasted with past and present web technologies. Since this chapter provides historical context and a broad introduction, it is intended for a general audience. Chapter 2 discusses core technologies on which JSP depends. The Hypertext Transfer Protocol (HTTP) and the Java Servlet platform, both of which help define how JSP operates, are introduced. A simple Java Servlet example is discussed. This chapter focuses on technical details that are important for programmers, but page designers can read it to learn how the web works. Chapter 3 presents a tutorial introduction to JSP. Examples designed to demonstrate JSPs capabilitiesfrom simple iteration and conditionalization to session management and non-HTML content generationare discussed in a gradual progression. This chapters examples are intended for a general audience. Chapter 4 provides more information for programmers and page designers about how JSP operates behind the scenes. The chapter focuses on how JSP works and introduces some of the core, time-saving features that JSP provides. The core elements of a JSP page are also introduced more formally than in chapter 3. Chapters 5 and 6 introduce the four basic categories of JSP tags: directives, scripting elements, comments, and actions. The use and syntax of all standard JSP tags is presented, with the exception of those specific to JavaBeans. The first three categories are covered in chapter 5. Chapter 6 introduces action tags, and describes the implicit Java objects accessible from all JSP pages. In both of these chapters, particular emphasis is placed on the application of these tags and objects to dynamic content generation via scripting. The scripting examples use the Java programming language, and may be of secondary interest to page designers. Because this chapter introduces most of the major functionality provided by JavaServer Pages, it is intended for a general audience. Chapters 7 and 8 cover JSPs component-centric approach to dynamic page design through the use of JavaBeans and JSP bean tags. The JSP tags covered in chapter 7 allow page designers to interact with Java components through HTMLlike tags, rather than through Java code. Chapter 8 will explain the JavaBeans API and teach you to develop your own JSP components. Chapter 9 covers techniques for working with databases through JSP. Nowadays, most large-scale web sites employ databases for at least some portion of their

ABOUT THIS BOOK

xxxv

content, and JSP fits in nicely. By combining the power of a relational database with the flexibility of JSP for content presentation and front-end design, it is practical to build rich, interactive interfaces. In chapter 10, we discuss several architectural models useful for developing JSP applications. We examine the various architectural options available when we combine JSP pages with servlets, Enterprise JavaBeans, HTML, and other software elements to create web-based applications. In chapter 11 we apply the JSP programming techniques we covered in previous chapters to the development of a real world, enterprise web application. In a chapterlength example, we will be developing a system for managing and presenting lists of frequently asked questions (FAQs). This chapter is based on a project the authors recently completed for a major software companys customer support site. The presentation aspect of this chapter should be of interest to page designers, while the implementation aspects should be of interest to programmers. Chapters 12 and 13 introduce two new features of the JSP 1.2 and Servlet 2.3 specificationsfilters and listeners. Filters can be used to layer new functionality onto JSP and servlet-based applications in a modular fashion, such as encryption, compression, and authentication. Listeners enable developers to monitor various activities and events occurring over the lifecycle of a web application. Chapter 12 covers the basics, while chapter 13 presents a chapter-length intranet example which demonstrates the use of filters and listeners to add enhanced capabilities to an existing application. Issues surrounding the deployment of web-based applications are the focus of chapter 14. Web Application Archives provide a portable format for the packaging of related servlets and JSP pages into a single, easily-deployed file, called a WAR file. The practical aspects of this approach to web deployment are demonstrated through coverage of the configuration and construction of a WAR file for the example application presented in chapter 13. Since both code and pages are stored together in a WAR file, this chapter should be of interest to all JSP developers. Chapter 15 explains how to perform common tasks with JSP. A multitude of examples and mini-projects address issues such as cookies, form processing, and error handling. If you learn best by example, you will find this chapter particularly helpful. In chapter 16 we examine a newer application of JSP programming, creating content other than HTML. The chapter explores this new area with coverage of plain text, XML, JavaScript, and even dynamic spreadsheets.

xxxvi

ABOUT THIS BOOK

We return to the topic of JSP examples in chapter 17. Here, the emphasis is on full-fledged applications that illustrate the various techniques and practices presented in previous chapters. Chapter 18 covers the development, deployment, and application of custom tag libraries. This material focuses primarily on the implementation of custom tags by Java programmers. From the perspective of jointly designing a set of applicationspecific tags, page designers may find some benefit in reviewing the introductory sections of this chapter, which discuss the types of functionality that can be provided by custom tags. In chapter 19, we expand upon the topic of custom tags with additional examples that take advantage of more advanced features of Java and JSP. Coverage of JSP custom tags concludes in chapter 20 with a discussion of tag library validators, a new feature introduced in JSP 1.2. Using validators, custom tag developers can enforce constraints and manage dependencies within all JSP pages that make use of their tags. Furthermore, because tag library validation occurs during page translation and compilation, rather than in response to a request, it enables custom tag errors to be detected earlier in the development process. There are six appendices in the book. Appendix A is provided for the benefit of readers of the first edition, the terminally impatient, and those wanting a quick look at whats new. In it we hit the highlights of recent advances in JSP technology, notably JSP 1.2 and the Servlet 2.3 API. Appendix B describes how to download, install, and run Tomcat, the JSP reference implementation. This appendix is aimed at readers who dont already have a JSP container to use; setting up Tomcat will help these readers experiment with the books examples. Java applets are small applications that run within the context of a web browser. Appendix C describes the <jsp:plugin> action, a cross-platform tag for specifying applets which use Sun Microsystems s Java Plug-in technology in order to take advantage of the Java 2 platform within the browser. This appendix is directed at Java programmers. As is the case with any major software technology in use today, there is a wealth of information on JSP and related topics available online. Appendix D provides a collection of mailing lists, newsgroups, and web sites of relevance to both categories of JSP developers, accompanied by brief descriptions of the content available from each. Appendix E, serving as a quick reference, summarizes the use and syntax of all of the standard (i.e., built-in) JSP tags available to page designers.

ABOUT THIS BOOK

xxxvii

Appendix F, geared toward Java programmers, lists all of the Java classes introduced by the JSP and servlet specifications to supplement the standard Java class library for web-based application development. Summary descriptions of these classes and their methods are provided, as is a table of the JSP implicit objects.

Source code
The source code for all of the examples called out as listings in the book is freely available from our publishers web site, www.manning.com/fields2, and from the books companion web site, www.taglib.com. The listings are organized by chapter and topic and include the source for both Java classes and JSP pages used in the examples. If any errors are discovered updates will be made available on the web.

Code conventions
Courier typeface is used to denote code (JSP, Java, and HTML ) as well as file

names, variables, Java class names, and other identifiers. When JSP is interspersed with HTML, we have used a bold Courier font for JSP elements in order to improve the readability of the code. Italics are used to indicate definitions and user specified values in syntax listings.

about the authors


DUANE K. FIELDS, web applications developer and Internet technologist, has an extensive background in the design and development of leading edge Internet applications for companies such as IBM and Netscape Communications. Duane lives in Austin, Texas, where he consults, does Java applications development, and tries to find more time to fish. He frequently speaks at industry conferences and other events and has published numerous articles on all aspects of web application development from Java to relational databases. He is a Sun Certified Java Programmer, an IBM Master Inventor, and holds an engineering degree from Texas A&M University. He can be reached at his web site at www.deepmagic.com. MARK A. KOLB, Ph.D., is a reformed rocket scientist with graduate and undergraduate degrees from MIT. A pioneer in the application of object-oriented modeling to aerospace preliminary design, his contributions in that field were recently recognized with a NASA Space Act Award. With over 15 years experience in software design, Marks current focus is on Internet applications, ranging from applet-based HTML editors to server-side systems for unified messaging and residential security monitoring. Mark resides in Round Rock, Texas, with his family and a large stack of unread books hes hoping to get to now that this one is done. His home on the web is at www.taglib.com. SHAWN BAYERN is a research programmer at Yale University. An active participant in the Java Community Process, he serves as the reference-implementation lead for the JSP Standard Tag Library (JSPTL). He is a committer for the Jakarta Taglibs Project and has written articles for a number of popular industry journals. Shawn holds a computer-science degree from Yale University and lives in New Haven, Connecticut. He can be found on the web at www.jsptl.com.

authors online
Purchase of Web Development with Java Server Pages includes free access to a private web forum run by Manning Publications where you can make comments about the book, ask technical questions, and receive help from the author and from other users. To access the forum and subscribe to it, point your web browser to www.manning.com/fields2 This page provides information on how to get on the forum once you are registered, what kind of help is available, and the rules of conduct on the forum. Mannings commitment to our readers is to provide a venue where a meaningful dialog between individual readers and between readers and the authors can take place. It is not a commitment to any specific amount of participation on the part of the authors, whose contribution to the AO remains voluntary (and unpaid). We suggest you try asking the authors some challenging questions lest their interest stray! The Author Online forum and the archives of previous discussions will be accessible from the publishers web site as long as the book is in print.

about the cover illustration


The cover illustration of this book is from the 1805 edition of Sylvain Marchals four-volume compendium of regional dress customs. This book was first published in Paris in 1788, one year before the French Revolution. Its title alone required no fewer than 30 words.

Costumes Civils actuels de tous les peuples connus dessins daprs nature gravs et coloris, accompagns dune notice historique sur leurs coutumes, moeurs, religions, etc., etc., redigs par M. Sylvain Marchal
The four volumes include an annotation on the illustrations: grav la manire noire par Mixelle daprs Desrais et colori. Clearly, the engraver and illustrator deserved no more than to be listed by their last namesafter all they were mere technicians. The workers who colored each illustration by hand remain nameless. The remarkable diversity of this collection reminds us vividly of how distant and isolated the worlds towns and regions were just 200 years ago. Dress codes have changed everywhere and the diversity by region, so rich at the time, has melted away. It is now hard to tell the inhabitant of one continent from another. Perhaps we have traded cultural diversity for a more varied personal lifecertainly a more varied and interesting technological environment. At a time when it is hard to tell one computer book from another, Manning celebrates the inventiveness and initiative of the computer business with book covers based on the rich diversity of regional life of two centuries ago, brought back to life by Marchals pictures. Just think, Marchals was a world so different from ours people would take the time to read a book title 30 words long.

Introduction

This chapter covers


I I I I

An introduction to JSP technology The evolution of dynamic content on the Web How JSP interacts with other Java code How to separate presentation and implementation

CHAPTER 1

Introduction

Welcome to Web Development with JavaServer Pages. This book has been written to address the needs of a wide audience of web developers. You might just be starting out as a web programmer, or perhaps youre moving to JavaServer Pages (JSP) from another language such as Microsoft Active Server Pages (ASP) or ColdFusion. You could be a Hypertext Markup Language (HTML) designer with little or no background in programmingor a seasoned Java architect! In any case, this book will show you how to use JSP to improve the look and maintainability of web sites, and it will help you design and develop web-based applications. Without further ado, lets begin our look at JavaServer Pages.

1.1

What is JSP?
JavaServer PagesJSP, for shortis a Java-based technology that simplifies the process of developing dynamic web sites. With JSP, designers and developers can quickly incorporate dynamic content into web sites using Java and simple markup tags. The JSP platform lets the developer access data and Java business logic without having to master the complexities of Java application development. In short, JSP gives you a way to define how dynamic content should be introduced into an otherwise static page, such as an unchanging HTML file. When a JSP page is requested by a web browser, the page causes code to run and decide, on the fly, what content to send back to the browser. Such dynamic content allows for the construction of large and complex web applications that interact with users. JSP is flexible: it adapts to the needs of developers and organizations. For some, JSP is a simple way to mix Java code and HTML text to produce dynamic web pages. For others, it helps separate Java code from presentation text, giving nonprogrammers a way to produce functional and dynamic web pages. JSP is not even limited to the production of dynamic HTML-based content. For instance, it can be used in wireless and voice-driven applications. Because JSP is based on widely accepted standards, products from numerous vendors support it. Like Java itself, JSP isnt dependent on a particular platform. When you learn JSP, you can be confident that your new skills will be applicable outside the individual environment in which you learned them.

1.2

Dynamic content on the web


The simplest application of the web involves the transmission of static, unchanging data (figure 1.1). When discussing computer systems, however, its important to keep in mind that static is a relative term. Compared with traditional forms of data

Dynamic content on the web

storage file cabinets and stone carvings, for instanceall computer files are transient. When we discuss content on the Web, we draw a conventional distinction between URLs that refer to simple files and those that refer to the output of a program.
DEFINITION

Web browser

1. Requests a URL 2. Responds with correct file

Web server
File 1 File 2

Figure 1.1

Static web sites transmit only simple, static files

Static content on the Web comes directly from text or data files, such as HTML or JPEG files. These files might be changed, but they are not altered automatically when requested by a web browser. Dynamic content, on the other hand, is generated on the fly, typically in response to an individual request from a browser.

1.2.1 Why dynamic content?


By our definition, dynamic content is typically generated upon individual requests for data over the Web. This is not the only way that an ever-changing web site might be produced. A typical computer system that runs a web server might easily run other software that can modify files in the servers file systems. If the web server then sends these automatically processed files to web browsers, the server achieves a primitive style of dynamic content generation. For example, suppose that a proWeb browser Web server 1. Requests a URL gram running in the background on File 1 a web server updates an HTML file 2. Responds with File 2 correct file ever y five minutes, adding a ranNormal, non-web program domly selected quotation at the botmodifies data (whenever it needs to) tom. Or suppose that a news organization has a program that Figure 1.2 A simple way to achieve dynamic accepts manual entry of breakingcontent is to modify files behind the scenes programmatically. news stories from journalists, formats these into HTML, and saves them in a file accessible by a web server. In both cases, a web site provides relatively dynamic data without requiring specific web programming (figure 1.2). However, such web sites dont easily support interaction with web users. Suppose there were a search engine that operated using this type of behind-the-scenes approach. Theoretically, such an engine could figure out all of the search terms it

CHAPTER 1

Introduction

supported and then createand storeindividual HTML pages corresponding to every supported combination of terms. Then, it could produce a gigantic list of HTML hyperlinks to all of them, in a file that looked like the following:
... <a href="aardvark-and-lizard.html">Search for "aardvark and lizard"</a> <a href="aardvark-and-mouse.html">Search for "aardvark and mouse"</a> <a href="aardvark-and-octopus.html">Search for "aardvark and octopus"</a> ...

Such a scheme, of course, would rapidly become unworkable in practice. Not only would the user interface be tedious, but the search engine would have to store redundant copies of formatted search results across trillions of HTML files. Imagine how long it would take to generate these files when new search terms were added, and consider how much disk space would be required. Moreover, many sites need to be able to respond to arbitrary, unpredictable input from the user. An online email application certainly couldnt predict every message a user might write. And often, a web site needs to do more than simply send HTML or other data when a request is issued; it also needs to take programmatic, behind-the-scenes action in responce to a request. For example, an online store might need to save users orders into a database, and an email application would actually have to send email messages. In many cases, simply displaying prefabricated HTML isnt enough. For all of these reasons, several web-specific technologies have been designed to allow programmers to design sites that respond dynamically to requests for URLs from browsers. JSP is one such technology, and we can get a better sense of how JSP is useful if we look at a few of its predecessors and competitors.

1.2.2 Common Gateway Interface


The first widely used standard for producing dynamic web content was the Common Gateway Interface, or CGI, which defined a way for web servers and external programs to communicate. Under typical operating systems, there are only a few ways that a program can communicate with another one that it starts: it might specify particular text on the target programs command line, set up environment variables, or use a handful of other strategies. CGI takes advantage of these approaches to allow a web server to communicate with other programs. As shown in figure 1.3, when a web server receives a request thats intended for a CGI program, it runs that program and provides it with information associated with the particular incoming request. The CGI program runs and sends its output back to the server, which in turn relays it to the browser.

Dynamic content on the web

Web browser

1. Requests a URL

Web server

2. Runs program, passing information about request 3. Sends output (HTML, etc.)

CGI program

4. Transmits response (HTML, etc.)

Figure 1.3

To respond dynamically, a web server can spawn a CGI program to handle a web request.

CGI is not an application programming interface (API) for any particular language. In fact, CGI is almost completely language-neutral. Many CGI programs have been written in Perl, but nothing prevents you from writing one in C, LISP, or even Java. The CGI standard simply defines a series of conventions which, when followed, let programs communicate with CGI-aware web servers and thus respond to

web requests. Because it imposes few constraints, CGI is quite flexible. However, the CGI model has an important drawback: a web server that wants to use a CGI program must call a new copy in response to every incoming web request.
DEFINITION

In operating-system parlance, a running instance of a program is known as a process. In slightly more formal terms, then, CGI requires that a new process be created, or spawned, for every new incoming web request.

CGI doesn t provide for any mechanism to establish an ongoing relationship between a server process and the external CGI processes it runs. This limitation leads to a relatively large cost of initialization upon each new request, for creating a process on a server is a relatively expensive operation. This cost isnt immediately obvious when a server runs only a handful of programs, but for large web sites that deal with thousands of requests every minute, CGI becomes an unattractive solution, no matter how efficient an individual CGI program might be.

1.2.3 Template systems


The CGI model has another drawback: it requires programs to produce HTML files and other content, meaning that program code often needs to contain embedded fragments of static text and data (figure 1.4). Many newer technologies have taken a different approach. Systems such as Macromedia ColdFusion, Microsoft ASP, and the open-source PHP (a hypertext preprocessor) all permit the integration of scripting code directly into an otherwise static file. In such a file, the static texttypically HTMLcan be thought of as a template around which the dynamic content, generated by the scripting code, is inserted (figure 1.5). The mechanism is similar to the

CHAPTER 1

Introduction

now-ancient idea of mail merge, a feature supported by nearly all word-processing systems whereby the same letter can be printed multiple times, varying only in the particular spots where customized content is necessary. Such template systems provide a convenient way for source_code { web designers to insert dynamic content into their function1(); web pages. Unlike CGI , template systems don t function2(); if (x) { require developers to write stand-alone, executable print programs that print HTML. In fact, a template system [HTML Fragment] usually doesnt require an in-depth understanding of } programming in the first place. Instead, designers } need only learn a scripting language supported by the template system they use. Even the procedure for Figure 1.4 CGI often requires debugging and testing pages developed under such that HTML fragments appear systems is similar to that of HTML: reload a page in within program code, making the browser, and changes to both scripting code and both harder to maintain. template HTML take effect. Conceptually, template languages are all fairly simi<p> lar. The most visible differences among these systems Your order's involve the particular scripting languages they suptotal comes to port, the syntax used for accessing such languages, and $ [simple the way that they provide access to back-end logic. program code]

ColdFusion That's right; we're ripping ColdFusion provides a set of HTML-like tags that can you off. be used to produce dynamic content. Instead of writ</p> ing more traditional types of code, ColdFusion developers can build applications using a combination of Figure 1.5 Template systems HTML tags and ColdFusion-specific tags. Using taglet HTML designers embed simple program code within based syntax has the advantage of consistency: pages HTML documents. that consist only of HTML-like tags are more accessible to HTML designers who do not have experience with programming languages. ColdFusion is available for Microsoft Windows and a variety of UNIX platforms, and it allows developers to write extensions to its core tag set in C++ and Java. Furthermore, ColdFusion code can access reusuable components such as CORBA objects and Enterprise JavaBeans (EJBs)as well as COM objects when it runs on Windows. Work on ColdFusion also gave birth to a technology known as WebDistributed Data Exchange (WDDX), which helps transfer data from one platform

Dynamic content on the web

to another. ColdFusion supports WDDX and can communicate with other services that use it.

Active Server Pages ASP technology supports multiple scripting languages, which can be embedded in HTML documents between the delimiters <% and %>. (As we will see, JSP uses these same delimiters.) ASP is a core feature of the Microsoft Internet Information Server (IIS), and it provides access to reusable Windows-based objects known as ActiveX components. Traditional ASP supports two scripting languages by defaultVisual Basic Scripting Edition, based on Visual Basic, and JScript, based on JavaScript. More recently, Microsoft has introduced ASP.NET as part of its .NET framework. While classic ASP offers an interpreted scripting environment where code is executed directly out of a text file every time a page is loaded, ASP.NET logic is compiled, yielding greater performance. ASP.NET offers access to any programming language supported in the .NET environment, including Visual Basic (in contrast with simple VBScript on ASP) and C#, which is pronounced C sharp and represents a new language offering from Microsoft. The new ASP.NET environment, like Java, supports type-safe programming, which can improve code maintainability. Furthermore, ASP.NET introduces the concept of an ASP.NET server control, which lets ASP.NET code authors access logic using a simple, HTML-like tag interface, just like ColdFusionand, as we will see later, JSP. The greatest drawback of the ASP and ASP.NET environments is that they are centered primarily on a single platform Windows. Some vendors, such as Chili!Soft, have introduced products that support ASP in other environments. And the more recent .NET framework promotes certain kinds of integration with nonMicrosoft platforms. Nonetheless, ASP and ASP. NET have not typically been regarded as attractive solutions for organizations that are not committed to Microsoft technology. PHP and other alternatives PHP is an open source template system. As with other open source projects, such as the Linux operating system and the Apache HTTP Server, PHP is not a commercial product. Instead, it is the result of contributions from a community of developers who freely build and support its code base. Open source products are typically available on a variety of operating systems, and PHP is no exception. Like ASP, PHP was once based on purely interpreted scripting, but it has moved closer to compilation over time. PHP 4 provides improved efficiency over PHP 3 by compiling scripts before executing them. PHP 4 comes with a rich function library

CHAPTER 1

Introduction

that includes support for accessing mail services, directories, and databases. Like ColdFusion, it supports WDDX, which provides for interoperability with other languages. Furthermore, it can interact with Java code, and it provides an API that allows programmers to insert custom modules. PHP isnt the only open source platform for generating dynamic content on the Web. For instance, like PHP, a system called Velocity falls under the umbrella of the Apache Software Foundation. Velocity is a template engine that is geared toward providing access to Java objects using a simple, custom template language. Open source template systems are flexible and free. Because their source code is available, experienced developers can debug nearly any problem they run into while using open source systems. In contrast, when a bug is encountered in a proprietary system, developers might need to wait for new releases to see it addressed. Some developers, however, see the sheer number of solutions offered by the open source community as a drawback. With dozens of competing alternatives that change frequently, the community can appear fragmentary, and some organizations might find it hard to settle with confidence on a solution they trust to be stable.

1.2.4 Java on the Web


So far, we have mentioned little about how Java and JSP fit into the larger picture. Java, as you probably know, is a language that was developed by Sun Microsystems. Java programs run inside a Java Virtual Machine (JVM), which provides a platformindependent level of processing for Java bytecodes, into which Java source files are compiled. Java thus avoids tying itself to a particular hardware platform, operatingsystem vendor, or web server. Furthermore, because Java has gained wide industry acceptance, and because the Java Community Process provides a well-defined mechanism for introducing changes into the platform when enough industry support exists, Java users can be confident that they develop applications on a standard and flexible platform. Lets take a quick look at how Java is used on the Web.

Java applets All of the technologies discussed so far involve dynamic content generation on the web servers end. However, the Web can also be used to deliver software that acts dynamically once it reaches the client machine. Determining the appropriate mixture of client-side and server-side code to use in an application is a complex problem, and the industry historically seems to swing between the two alternatives. At the client-side end of the spectrum, a web site could offer fully functional, downloadable programs that users can run; at the

Dynamic content on the web

server-side end, servers handle almost all of the processing of an application, merely asking clients to render screens of HTML or other markup languages. Java applets, an early use of Java technology that remains popular in some environments, are examples of client-side code. Applets are typically small programs that can be downloaded and run inside web browsers. Applets can access the network and perform a variety of other functions, offering a rich user interface from within a simple web browser. But applets have drawbacks and are not suitable for all applications. For instance, not all web browsers support Java applets identically; in fact, not all web browsers support Java applets in the first place. Furthermore, in many situations, server-side code is easier to maintain and support.

Java servlets A Java servlet relates to a server, roughly, as a Java applet does to a web browser. A servlet is a program that plugs into a web server and allows it to respond to web requests according to instructions provided as Java code. As we mentioned, the CGI standard allows developers to write code in Java. Why, then, would a separate standard for Java servlets be necessary? Foremost, servlets offer a great performance advantage over CGI programs. This may seem counterintuitive to those who realize that code that runs inside a JVM is typically slower than code that runs natively on a particular platform. Even though the performance difference between Java and native code diminishes as research improves, the gap is still noticeable. Thus, if CGI supports native code but Java requires a JVM, how could servlets be faster than CGI programs? The major difference lies in the limitation of CGI that we discussed earlier: CGI processes need to be run individually in response to web requests. The Java Servlet platform offers a different model that allows a Java program within a single JVM process to direct requests to the right Java classes. Since no new operating-system processesonly lighter-weight threads of execution within the JVMneed to be created for incoming requests, servlets end up scaling better than CGI programs do. Servlets also offer Java programmers more convenience than the base CGI specification. CGI does not provide language-specific APIs, nor does it provide standard libraries to facilitate programming. The Java Servlet standard, in contrast, provides an API that supports abstraction and convenience. In order to access information about incoming requests, for example, servlet programmers can use objects from a particular class hierarchy defined in the Servlet specification. Moreover, servlets have access to all of the benefits of the Java platform itself, including reusable class libraries and platform independence. Since a servlet is just a Java class, it can naturally access other Java code.

10

CHAPTER 1

Introduction

NOTE

Well look more at servlets in the next chapter. Appendix F provides a reference to the servlet API.

Servlets first appeared as part of the Sun Java web server product, which was an HTTP server written in Java. Versions 2.1 and 2.2 of the Servlet standard appeared in 1999, and version 2.3 was released in 2001. The evolution of the Servlet platform continues under the Java Community Process. Even with the services provided by the Java Servlet API, however, the platform has a drawback in terms of convenience and maintainability when it is used to produce dynamic web pages. Servlets offer all of the tools necessary to build web sites, but just like the CGI standard, they require developers to write code that prints entire HTML filesor other dataon demand. Code that looks like
out.println("<p>One line of HTML.</p>"); out.println("<p>Another line of HTML.</p>");

is common. The ease of template systems, where code can simply be embedded in static text, is not present. Libraries and toolkits help orient the servlet environment toward the creation of HTML pages (and other types of data). For instance, the Element Construction Set ( ECS ), another open source project under the Apache Software Foundation s umbrella, offers an approach that should be familiar to object-oriented programmers. ECS supports the creation of HTML and Extensible Markup Language (XML) pages using a class hierarchy representing textual elements. This approach facilitates the construction and maintenance of textual documents, but it has a potential drawback: all document content, both static and dynamic, still exists inside source code. To edit the layout of a page, a developer must modify Java code; an HTML designer cannot simply edit a straightforward text file.

JavaServer Pages (JSP) Ideally, then, it seems that web designers and developers who use the Java platform would want a standards-based template system built on top of the Servlet platform. As we discussed, servlets provide performance benefits and can take advantage of existing Java code. But template systems let dynamic web pages be created and maintained easily. JSP was the natural result of this need. JSP works like a template system, but it also extends the Servlet platform and provides most of the advantages of servlets. Like servlets, JSP pages have access to the full range of Java codes capabilities. JSP pages can include Java as embedded scripting code between <% and %> delimiters,

Dynamic content on the web

11

the same as those used in ASP. But like ColdFusion, JSP also provides several standard HTML-like tags to access back-end logic, and it lets developers design new tags. In short, JSP is a standards-based template system that extends the Java Servlet framework. The first draft of the JSP specification appeared in 1998, followed by versions 1.0 and 1.1 in 1999. The newest version of the standardJSP 1.2was released in 2001; this version is the one covered by this book. In addition to the underlying technical specifics, servlets and JSP differ from most other technologies in another important respect: they are supported by a wide variety of vendors. Dozens of server-side platforms and development tools support servlets and JSP.

1.2.5 How XML fits in


What implications does XML have for web developers? XML is not a development language; it does not serve a function coordinate with that of template systems, CGI, or anything else weve discussed so far. XML is, at heart, a format for representing data. A quick primer on XMLs syntax and how it relates to HTML is given in chapter 4, but for now, think of an XML document as a way to represent treestructured data in textual form. XML is not tied to any particular programming language, so it is sometimes called portable data. (For example, the WDDX technology mentioned in section 1.2.3 is based on XML.)

A quick tour of XML technologies Several technologies support XML and make it useful as a mechanism for storing, transmitting, and manipulating data for web applications. For instance, document type definitions (DTDs) ensure a certain level of structure in XML documents. XML Schema is a technology that goes far beyond DTDs in ensuring that an XML document meets more complex constraints.
TIP

Heres a relatively lighthearted but instructional way to look at XML basics. Suppose you want to store a list of jokes on your computer. You could easily store such a list in a simple text file. XML lets you impose structure: for example, you can mark off sections of the jokes into set-ups and punchlines. Given such a structured file, DTDs let you make sure that every joke has a punchline. And XML Schema, one might say, comes close to ensuring that the punchlines are funny! Of course, such a claim about XML Schema is not literally true. But XML Schema can be used to define details about how data needs to appear in a document.

12

CHAPTER 1

Introduction

Several APIs and languages exist for manipulating XML. The Document Object Model (DOM) provides programmatic, well-defined access to an in-memory copy of an XML document. The Simple API for XML (SAX), by contrast, supports an event-driven model that allows programmers to handle XML without keeping an entire document in memory at once. Extensible Stylesheet Language Transformations (XSLT) provides a mechanism for manipulating XML documentsthat is, for extracting pieces of them, rearranging these pieces, and so on. XSLT uses the XML Path Language (XPath) for referencing portions of the XML document. An XPath expression, as an example, can refer to all <punchline> elements under all <joke> elements within a document. An XSLT transformation would let you format an XML document containing data into HTML for presentation on web browsersand also into the Wireless Markup Language (WML) for use on cell phones and other wireless devices. Some web-specific technologies have focused specifically on XML. One such technology is Cocoon, yet another product of the Apache Software Foundation. Cocoon supports pipelines of XSLT transformations and other operations, so that a single XML document gets massaged through a series of steps before being sent to its final destination. Cocoon uses this model to support presentation of data in HTML and other formats. The Cocoon framework also introduces the idea of eXtensible Server Pages (XSP), which works like an XML-based template system; XSP can be used to generate XML documents dynamically, using markup that references either embedded or external instructions.

XML and JSP JSP touches on XML technology at a number of points. Most simply, JSP can easily be used to create dynamic XML documents, just as it can create dynamic HTML documents. Java code used by JSP pages can, moreover, easily manipulate XML documents using any of the Java APIs for XML, such as the Java API for XML Processing (JAXP). JSP pages can even be written as XML documents; most of JSP syntax is compatible with XML, and the syntactic constructs that arent compatible have analogous representations that are. Behind the scenes, the JSP 1.2 specification uses XML to let developers validate pages. Just as JSP pages can be authored in XML, every JSP page is represented, internally by the JSP processor, as an XML document. JSP 1.2 lets developers use this view of the page to verify the document as it is being processedthat is, to ensure that the page meets custom constraints the developer can specify. This might be useful in environments where back-end developers want to ensure that HTML designers using the developers code follow certain conventions appropriately.

The role of JSP

13

Future versions of JSP might use this internal XML representation to let developers execute automatic XSL transformations, or other modifications, on JSP pages before they execute.

1.3

The role of JSP


When we presented individual template systems, we discussed how they provided access to back-end libraries and custom logic. For instance, ASP supports ActiveX controls and ColdFusion can be extended with C++ or Java, thus providing access to back-end C++ or Java objects. We now look at how JSP pages fit into Java frameworksthat is, how they access reusable Java classes, and what role they play in large, distributed Java applications.

1.3.1 The JavaBeans component architecture


JavaBeans is a component architecture for Java. To software developers, the term component refers to reusable logic that can be plugged into multiple applications with ease. The goals of component architectures include abstraction and reusability. That is, new applications dont need to know the details of how a particular component works, and the same component can be used in a variety of applications. Because of this reusability, component architectures increase productivity; code performing the same task does not need to be written, debugged, and tested repeatedly. Think of JavaBeans as Java classes that follow particular conventions designed to promote reusability. JavaBeans can encapsulate data and behaviors. For instance, you might design JavaBeans that represent your customers or products, or you might write a bean that handles a particular type of network call. Because JavaBeans automatically provide information to their environments about how their data can be accessed, they are ideally suited for use by development tools and scripting languages. For example, a scripting language might let you recover the last name of a customer whose data is stored in a JavaBean just by referring to the beans lastName property. Because of JavaBeans conventions, the scripting language can automatically determine, on the fly, the appropriate methods of the JavaBean to call in order to access such a property (as well as the Java data type of the property). JavaBeans can also, because of their generality, be connected and combined to support more sophisticated, application-specific functionality.

14

CHAPTER 1

Introduction

NOTE

Well discuss more about the technical details of JavaBeans in chapter 8. For now, our intent is to explore high-level advantages that JavaBeans provide to JSP applications.

Just as JavaBeans can be used by scripting languages, they can also be used inside JSP pages. Of course, the Java code that is embedded in a JSP page can access JavaBeans directly. In addition, though, JSP provides several standard HTML-like tags to support access to properties within JavaBeans. For instance, if you wanted to print the lastName property of a customer bean, you might use a tag that looks like this:
<jsp:getProperty name="customer" property="lastName"/>

In addition to the typical reusability JavaBean that the JavaBeans architecture offers (figure 1.6), beans thus serve another role in the JSP environment. SpecifiJavaBean cally, they promote the separation of presentation instructions and implementation logic. A customer bean refJSP JSP JSP erenced by a JSP page might have an page page page arbitrarily complex implementation; for instance, it might use the JDBC Data Access API to retrieve customer information or process demographic JavaBean data related to the customer. Regardless of what goes on behind the scenes, JavaBean however, the single line of JSP code above still retrieves the lastName Figure 1.6 The same JavaBeans component can property out of the customer bean. be used in multiple JSP pages. The Java code is thus abstracted out of the JSP page itself, so that an HTML designer editing the page would not even need to see itmuch less be given a chance to modify it accidentally. Note that JavaBeans, while greatly assisting the separation of presentation instructions from back-end program logic, do not provide this separation automatically. JavaBeans properties can contain arbitrary data, and you could easily construct an application that stores HTML tags as data inside JavaBeans. For instance, instead of a lastName property that might store the name Jones, you might instead store a formattedLastName property that looked more like this:

The role of JSP

15

<p><font color=red>Jones</font></p>

Doing this would compromise the separation of HTML from logic, however. Including this HTML inside a JavaBean would limit the beans reusability. Suppose you wanted to start using the bean in a wireless, WML-based application, or in an applet. In such a case, storing HTML inside the bean would not be desirable. Instead, it would be more productive to surround the JSP tag that refers to the bean with HTML formatting. Similarly, JavaBean logic itself should not produce HTML tags. You might be tempted to use a JavaBean to construct an HTML table automatically as the result of a database query, but in most situations, it would be better, instead, to use JSP to construct the table and the JavaBean only to access the database. The separation between logic and presentation that JSP promotes can, as weve hinted, assist with division of labor within development teams. The more Java code that is removed from JSP pages, the more those pages should feel familiar to web designers. When programmers focus their work on Java code and designers manage HTML pages, the need for coordination among team members is reduced, and the team can become more productive. Even on relatively small projects, using JavaBeans might save you work and make your code more maintainable. It is typically easier to debug standalone JavaBeans than Java code embedded in a JSP pageand, as weve discussed, encapsulating code in a bean will let you easily use it in multiple pages.
NOTE

JavaBeans are not the only way to abstract logic out of JSP pages. Custom tags, described in more detail in chapters 1719, provide another means of referencing Java logic within JSP pages without embedding it in the page itself. Chapter 18 covers design considerations that will help you choose between JavaBeans and custom tags.

1.3.2 JSP and Java 2 Platform Enterprise Edition


JSP technology is integral to the Java 2 Platform, Enterprise Edition (J2EE). Because

it focuses on tasks related to presentation and flexibly supports access to back-end functionality, JSP is a natural choice for the web tier of multi-layer applications. J2EE in contrast with the Standard Edition ( J2SE ) and the Micro Edition (J2ME), supports the development of enterprise applications. J2EE includes technologies targeted at designing robust, scalable applications. At J2EEs core is the Enterprise JavaBeans (EJB) specification, which aids developers of enterprise components by managing such things as security, transactions, and component life cycle considerations.

16

CHAPTER 1

Introduction

The J2EE BluePrints, a set of documents and examples from Sun Microsystems that describe recommendations for building enterprise applications, prominently feature JSP technology. In many enterprise environments, JSP provides an effective mechanism for handling the presentation of data, irrespective of the datas source, the use of EJB, and other considerations. JSP is also being used as the basis for emerging standards. For example, the JavaServer Faces initiative, operating under the Java Community Process, had recently begun investigations into a standard mechanism for simplifying the development of graphical web applications using servlets and JSP. Because JSP is regarded as enterprise-quality technology, JSP developers can depend on backwards compatibility from future versions of the JSP specification. While JSP actively continues to evolve, its days as an experimental platform are over. Instead, users of JSP can rely on its platform independence, its status as an enterprise technology, and its basis on standards accepted by the industry.

HTTP and servlets

This chapter covers


I I I I

HTTP basics HTTP GET versus HTTP POST Java servlet basics An example servlet

17

18

CHAPTER 2

HTTP and servlets

Like most web applications, JSP pages require a style of programming different from that of traditional desktop applications. For one thing, you cannot choose how and when your JSP application interacts with its users; JSP pages are limited by the protocols and technologies on which they rest. In this chapter, we look at the Hypertext Transfer Protocol (HTTP) and Java servlets, both of which help define how JSP functions.

2.1

The Hypertext Transfer Protocol (HTTP)


HTTP is the default protocol for JSP, which means that JSP applications typically receive requests and send responses over this protocol. HTTP is also the basic proto-

col of the World Wide Web, and youve almost certainly used it already if youve accessed a web page. For computers on a network to communicate, they need a set of rulesthat is, a protocolfor sending and receiving data. HTTP is one such protocol, and its the one that has been adopted by the web. All web browsers support HTTP, as do the web servers they connect to. HTTP supports both static content, such as HTML files, and dynamic content, including data generated by the technologies we discussed in chapter 1.
DEFINITION

Web server is a general term that can be used to describe both the hardware and the software of a machine that answers requests from web browsers. In this discussion, we usually refer to the softwarethat is, to HTTP-server software running on a networked machine. Examples of HTTP servers include the Apache Server and Microsoft IIS.

2.1.1 HTTP basics


As it turns out, HTTP is simpler than many other protocols. It defines a relatively straightforward model of interaction between a web browser and a server. Specifically, HTTP is oriented around requests and responses. Under HTTP, a browser sends a request for data to a server, and the server responds to that request by providing HTML or some other content.

The Hypertext Transfer Protocol (HTTP)

19

By contrast, some application protocols are bidirectional. For example, when you establish a terminal connection to a host using Telnet, either your client program or the server may arbitrarily decide that it is time to send a message to the other par ty. As suggested in figure 2.1, web servers do not have this flexibility. For a web server to send data to a web browser, it must wait until it receives a request from that browser. While a Windows application like Microsoft Word, or even a terminal application running on top of Telnet, can simply decide to display a message on the users screen when it needs new input, an HTTP based application must follow the request/ response model.
NOTE

Client a

Server

Client . . .

Server

Figure 2.1 a. A request-response protocol such as HTTP. b. A bidirectional protocol such as Telnet. Note that the server can initiate a message once the protocol is established.

To get around some of HTTPs constraints on application flow, web applications can send JavaScript codeor even full programs like Java appletsas part of their responses to browsers. (See chapter 15 for an example of using JavaScript, and see appendix C for more information about applets.) Applets and scripting code are not appropriate for all web applications. For example, not every browser supports JavaScript and Java applets. Furthermore, underneath such code, the requests and responses of HTTP are still present, and you will need to keep them in mind when designing your web applications.

HTTP is also stateless, meaning that once a web server answers a request, it doesnt remember anything about it. Instead, the web server simply moves to the next request, forgetting tasks as it finishes them. You will occasionally need to keep this statelessness of HTTP in mind as you develop web applications. For example, suppose you want to design an application that ties together successive requests; perhaps you want to remember that a user added a product to a shopping cart, or you need to assemble the results of several pages worth of HTML forms. By itself, HTTP does not join together such logically connected requests a task often referred to as session management. As we will see in chapter 4, the JSP environment provides support for session management, but you should keep in mind that you

20

CHAPTER 2

HTTP and servlets

have some control over how your application manages sessions; HTTP does not solve, or even address, this issue for you. Because HTTP is stateless, a web browser must build two separate, complete requests if it needs two pages from a server. In fact, for pages that contain embedded images, music, or other data, the browser might have to send numerous requests to the server in order to load a single page completely.
NOTE

If you have experimented with HTTP, you may have realized that it supports persistent connections, meaning that a browser can keep a single network connection open if it has many requests it needs to send to a server. This ability is just an implementation detail, however: it represents only a low-level performance improvement. As far as web applications are concerned, persistence does not change the way HTTP functions; the protocol is still stateless and oriented around individual requests and their responses.

Although HTML is clearly one of the most popular formats for data on the web, HTTP is a general-purpose protocol and is not limited to serving HTML. For example, HTTP also frequently carries images, sound files, and other multimediaand it can be used for just about anything else. HTTP responses are typically tagged with a content type; that is, they include information about the datas format. This extra information is encoded as part of an HTTP messages headers. A typical HTTP response has a status line, headers, and a Response body (figure 2.2). The body contains the response s payStatus Line loadan HTML file, for examplewhile the header and staHeaders tus line provide information that the browser uses to figure Information about out how to handle the response. Although the web server typthe response ically manages some response headers itself, JSP pages have access to set the headers for the responses they generate. For Body HTML, JPG, or a file example, your JSP page can set the content type of its in another format response; well see how to take advantage of this ability in chapter 15. As described, HTTP is a reasonably simple protocol. Many Figure 2.2 The users of the web think that HTTP does more than it really typical structure of an HTTP response. does. An important point to keep in mind is that HTTP doesnt care what content it carries or how that content was generated. Neither, in fact, do web browsers: a browser does not need to know whether the HTML it renders was transmitted from a static file, a CGI script, an ASP page, or a JSP application. As suggested by figure 2.3, the flow of a typical web application is not very

The Hypertext Transfer Protocol (HTTP)

21

different, as far as a web browser is concerned, from aimless browsing of static pages by a user: the browser transmits a request and gets a response, the user reads the page and takes some action, and the cycle repeats. Request As an example of HTTPs simplicity, consider a User Server web-ser ver feature you might be familiar with. Response . When a browser asks for a URL that corresponds to . . a directory of files instead of a particular file name, Request many servers generate a listing of the files in that Response directory. It is important to realize that the server . . . generates this listing; it automatically fabricates an Request HTML message that represents a directory listing, Response and the browser renders this HTML message just as it would render a static file. (In other words, the browser has no idea that it just requested a list of Figure 2.3 The flow of a typical web application is not substantially files.) The very correspondence between the URL different from that of aimless and a directory is idiosyncratic to the web servers browsing by a web user. Broadly configuration; the web server, on its own, establishes speaking, the web is made up of this mapping. Likewise, it s up to web servers to requests and responses. decide whether a particular request will be served from a simple file or dispatched to a JSP page.

2.1.2 GET versus POST


As we discussed earlier, HTTP servers need to wait for requests from web browsers. These requests can come in a variety of forms, but the two request typesformally called methodsthat are most important to web developers are called GET and POST. Just like HTTP responses, HTTP requests can be broken GET Request GET url HTTP/1.1 up into headers and bodies. However, while most HTTP response messages contain a body, many HTTP requests do Headers not. A simple type of HTTP request just asks for information Information about the request identified by a URL. (To be more specific, browsers don t send the entire URL to servers; they send only the portion of the URL relative to the servers root. When we discuss URLs Figure 2.4 The in HTTP requests, we refer to this type of relative URL.) This typical structure of a kind of request usually consists of a line of text indicating the GET request. desired URL, along with some headers (figure 2.4). Because such requests support simple information retrieval, they are called GET requests. Handling GET requests is relatively simple: the server reads and parses the requested URL and sends an appropriate response. GET methods are often used to

22

CHAPTER 2

HTTP and servlets

retrieve simple files, such as static HTML or images. However, they are not limited to this simple functionality. URLs come in many shapes and sizes, and as weve discussed, servers have discretion in processing them: URLs dont necessarily map to files in a filesystem, JSP pages, or anything else. Furthermore, information can be encoded dynamically into a URL. For example, a value you type into an HTML form might be added to the end of a URL. A web server can process this information on the fly, taking customized action depending on the information that a URL contains. As an example, suppose a web server is configured to respond with a custom greeting based on information that it parses out of the URL. When the server receives a request corresponding to a URL such as
http://example.taglib.com/hello?name=Name

it responds with HTML output of the form


<html><body><p> Hello, Name </p></body></html>

The server is well within its rights to respond to a request in this manner; again, a URL doesn t necessarily correspond to a particular file on the server, so no file called hello or hello?name= or anything similar needs to exist on the example.taglib.com server. The server can simply make an arbitrary decision to respond to the request in this way. As it turns out, many real-life web applications handle GET POST Request POST url HTTP/1.1 requests in a very similar fashion when responding to HTML forms. Web browsers have a standard format for submitting Headers the information that users enter through such forms. (ThereInformation about the request fore, when servers parse this information, they can know what to expect.) One way that browsers submit this kind of Body encoded information is by appending it to the URL in a GET Information sent as request. part of the request, usually intended for POST requests are similar to GET requests. However, in a web application addition to transmitting information as part of the structure of the URL, POST requests send data as part of the requests Figure 2.5 The body (figure 2.5). As with GET requests, this information typical structure of a might be in any format, but web browsers and server-side POST request. applications generally use standard encoding rules. When requesting URLs as the result of an <a>, <img>, or similar HTML element, web browsers use GET requests. When submitting the result of an HTML <form>, browsers use GET by default but can be told to use POST by specifying the method attribute of <form> as POST, as follows:

Java servlets

23

<form method=POST>

Why is there a need for both GET and POST, considering how similarly they function? For one thing, many web applications require the browser to transmit a large volume of data back to the server, and long URLs can get unwieldy. Although there is no formal length limitation on URLs, some softwaresuch as HTTP proxieshas historically failed to function properly when URLs are greater than 255 characters. POST is therefore useful to get around this limitation. The HTTP standard also draws a logical difference between the two types of requests. The standard suggests that GET methods, by convention, should not cause side effects. For example, a properly functioning web application should not store information in a database in response to a GET request; actions that cause side effects should be designed, instead, to use POST requests. In practice, this guideline is not always followed, and in most cases, it does not have many practical ramifications. A more important consideration raised by the HTTP standard is that software engaged in the processing of URLs including web browsers, proxies, and web serversoften stores these URLs as they are processed. For instance, browsers often keep histories of visited URLs, and servers often maintain logs of URLs that have been requested. Therefore, if your web application passes sensitive data, such as a users password, using an HTML form, it should POST the data instead of sending it as part of the URL in a GET request. Data sent as the body of a POST is not typically logged by browsers, proxies, or servers.
TIP

As you develop web applications, youll probably find that you use POST requests more frequently than GET requests for submitting web forms, given the volume and sensitivity of the data youll need to transfer. GET requests are useful, however, if you want to access dynamic content from an <a> or <img> tag; these tags cause browsers to use the GET method. Well see an example of this use of <a> in the servlet example.

2.2

Java servlets
A Java servlet is a special type of web-based Java program. As we saw in chapter 1, JSP pages depend intricately on servlets. In fact, every JSP page ultimately becomes a servlet before it's used. Therefore, before jumping into JSP, you might want to familiarize yourself with how servlets work.

24

CHAPTER 2

HTTP and servlets

2.2.1 How a web server uses servlets


A web server, as we have seen, has fairly wide discretion in how it decides to respond to HTTP requests. It might serve files from a disk, or it might call a program and produce a response based on that programs output. More sophisticated servers, such as the Apache Server, have rich configuration mechanisms that allow modules to be installed and run from within the web servers process. One such program might be a servlet container.
DEFINITION

A program that manages servlets is called a servlet container, or a servlet engine. If a web server is configured to respond to certain types of requests by running a servlet, a servlet container is responsible in part for handling these requests. For example, the container sets up and shuts down servlets as necessary and provides information to servlets to facilitate their processing. The servlet container also calls the appropriate methods on servlet objects in order to cause specific servlets logic to run.

A servlet container might Browser Web server Servlet continer be implemented as a sepaprocess process rate operating-system pro- a cess from the web server it Browser Web server communicates with, or it process might be configured to run b Servlet inside the web servers procontainer cess (figure 2.6). The model of communication between web ser vers and Figure 2.6 A servlet container may run in a separate operatingsystem process from the web server logic that depends on it (a). servlet containers is fairly A servlet container may also run inside a web servers process (b). general; as long as the container can manage servlets appropriately, hand them requests, and deliver their responses, servlet and JSP developers can be shielded from the details of the backend interaction between servlet containers and the generic web-server logic that drives them.

2.2.2 The anatomy of a servlet


Like HTTP, servlets are based on the request/response model. In fact, a servlet is essentially a Java class that implements a particular, formal interface for producing responses based on requests. The Java interface javax.servlet.Servlet, which defines how servlets function, has a method that looks like

Java servlets

25

public void service(ServletRequest req, ServletResponse res)

The ServletRequest and ServletResponse interfaces, both in the javax.servlet package, represent the requests that a servlet processes and the responses that a servlet generates. Because all servlets implement the javax.servlet.Servlet interface, each provides an implementation of the service() method. (Implementing a Java interface requires that a class provide implementations of all of the methods declared in that interface.) Therefore, all servlets have logic for processing a request and producing a response. The Servlet interface has other methods that servlets must implement. JSP developers do not typically need to deal with these methods directly, but it may be useful to know that servlets can provide logic to handle initialization in an init() method and cleanup in a destroy() method. The most common type of servlet is tied specifically to HTTP, which the Servservice() let specification requires every ser vlet GET request POST request container to support. The servlet standa r d d e fin e s a cl ass, j a v a x . s e r v doGet() doPost() let.http.HttpServlet, that represents HTTP -capable ser vlets and contains Figure 2.7 The mapping of GET and POST some convenience logic for their pro- requests within an HttpServlet implementation. grammers. Specifically, authors of HTTP servlets do not usually need to write a service() method manually; instead, they can extend the HttpServlet class and override one or more of the higher-level methods it provides. Since HttpServlet is aware of HTTP, it has Java methods that correspond to HTTP methods: for instance, it specifies a doGet() method to handle GET requests and a doPost() method to handle POST requests. As figure 2.7 suggests, the service() method of HttpServlet calls these methods when the servlet receives GET or POST requests. Because service() provides this switching mechanism to differentiate among different types of HTTP requests, the developer of an HTTP servlet does not need to analyze each request, determine its type, and decide how to handle it. Instead, HTTP servlet authors can simply plug in logic to respond to GET or POST requests, as appropriate to their applications. The doGet() and doPost() methods accept arguments of type HttpServletRe que st and H ttp Ser vl etR es pon se , both of which are located in the javax.servlet.http package. These two interfaces extend their more generic equivalents and provide HTTP-specific request information and response directives. For example, because the type of message headers we discussed earlier are an HTTP

26

CHAPTER 2

HTTP and servlets

concept and might not be present in another protocol, the method getHeaders() is defined in HttpServletRequest, not in the base ServletRequest interface. That is, the general interface does not need to have any concept of HTTP headers, but HTTP-specific request objects do. Similarly, the HttpServletResponse interface lets a servlet set HTTP cookies, which are described in more detail in chapters 4 and 14; cookie functionality would not be appropriate in the generic interface. Consider another use of the ServletRequest interface. As we discussed earlier, browsers have a standard mechanism for encoding the data that users enter on HTML forms. In the servlet environment, it is the job of the servlet container to understand this encoding and represent it to the servlet. It does this through a ServletRequest object, which has methods like getParameter() that let the servlet easily recover the information entered by the user. Servlet authors therefore dont need to parse the encoded form data themselves; they can use the simple Java API that the container provides. HttpServletRequest objects will resurface when we begin to discuss the details of JSP functionality.
NOTE

For more information on the servlet and JSP APIs, including the classes and interfaces shown in this chapter, see appendix F.

2.2.3 A servlet example


Even though detailed knowledge of servlets is not necessary for JSP developersin fact, one of JSPs great advantages is that it lets developers create Java-based web applications without having to write servlets by handa simple servlet example might help you understand how servlets function. As we discussed, the servlet container does a lot of work behind the scenes, so a simple servlet is actually fairly straightforward to write. A basic HTTP ser vlet just needs to provide logic to respond to GET or POST request, which it can do by overriding the doGet() or doPost() methods in HttpServlet. The source code to a basic servlet that greets the user and prints extra information is shown in listing 2.1.
Listing 2.1 A servlet that greets and prints

import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class BasicServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {

Java servlets

27

// output to the browser via the "response" object's Writer PrintWriter out = res.getWriter(); // print out some unchanging template "header" text out.println("<html>"); out.println("<body>"); out.println("<p>"); // print some dynamic information based on the request String name = req.getParameter("name"); if (name != null) out.println("Hello, " + name + "."); else out.println("Welcome, anonymous user."); out.println("You're accessing this servlet from " + req.getRemoteAddr() + "."); // print out some unchanging template "footer" text out.println("</p>"); out.println("</body>"); out.println("</html>"); } }

This servlet implements only the doGet() method; it does not concern itself with POST requests. From doGet(), the servlet prints unchanging information, often called template data, to a java.io.PrintWriter object it has retrieved from the HttpServletResponse object it was passed. Then, it greets the user by retrieving a particular parameter from the HTTP request, much as the web server in our prior discussion did. It also prints the IP address from which the request originated. (Some applications use this information for gathering statistics or auditing users.)
TIP

It is relatively easy to install a servlet container and run the servlet from listing 2.1. See appendix B for more information on Jakarta Tomcat, a free servlet and JSP container that provides the official reference implementation for the Java servlets and JSP platforms.

Notice how the servlet makes multiple calls of the form out.println() in order to display HTML and other miscellaneous text. Servlets that print HTML become unwieldy quickly because they output a large amount of text from within program logic. As we saw in chapter 1, this awkward use of servlets is one of the motivating factors behind JSP.

28

CHAPTER 2

HTTP and servlets

Figure 2.8

Output of the basic servlet when no name is specified.

Figures 2.8 and 2.9 show the servlet responding to two different requests. Note the differences between the two trial runs of the servlet. In figure 2.8, no name parameter is specified, so the test against such a parameter in the code causes an anonymous greeting to be displayed; figure 2.9 greets the user by name. Note also that the IP addresses shown in the two windows are different; the servlet detects the IP address of each new request as its processed. The servlet determines the name parameter from the HTTP request by parsing it according to the standard rules we mentioned before; the details of these rules are not important for now, but as you can probably see from the example, strings of the form
name=value

following a question mark (?) in the URL are interpreted as request parameters. URLs containing such parameters can also be constructed manuallyfor example, as references from an <a> element. A file containing the following HTML might allow a user to click two different links and be greeted by two different names:
<a href=BasicServlet?name=Justin> Say hello to Justin. </a> <a href=BasicServlet?name=Melissa> Say hello to Melissa. </a>

More dynamically, an HTML form containing the element


<input type=text name=name />

could allow the user to enter his or her name and be greeted appropriately.

Figure 2.9

Output of the basic servlet when a name is specified.

Java servlets

29

This crash course in servlets was not designed to turn you into a servlet programmer overnight. As weve discussed, JSP makes it easy to develop dynamic web pages without having to use servlets. But many JSP programmers find a basic understanding of servlets useful as they approach more complex problems. Some applications, as we will see in chapter 10, can be built using both JSP and servlets. In other situations, having experimented with servlets will give you a deeper understanding of the JSP environment; well discuss more about how JSP pages and servlets interrelate in chapter 4.

This chapter covers


I I I I

3
30

First steps

Writing your first JSP page Simple dynamic content with JSP Basic session management Abstracting logic behind JSP pages

Simple text

31

Now were ready to see what JSP looks like. This chapter explores some of JSPs capabilities, giving you a quick tour of its basic functionality. The goal isn t to swamp you with technical details; well begin to consider those in the next two chapters, when we introduce the syntax and back-end implementation of JSP. The examples in this chapter should familiarize you with JSP pages look and feel, which will be helpful when we discuss the syntax more formally.

About the examples As indicated in chapter 1, a strength of JSP is that it lets you produce dynamic content using a familiar, HTML-like syntax. At the same time, however, the mixture of JSP elements and static text can make it difficult to look at a file and quickly find the JSP elements. To help remedy this problem for the examples in this book that mix JSP elements with static text, we have adopted the convention of marking JSP tags in such examples in boldface. All of the examples presented in this chapter (except for one) are real, usable JSP, and youre encouraged to experiment with them yourself before moving forward. If you do not yet have a JSP environment in which to experiment, appendix B contains a quick installation guide for Tomcat, a free JSP container that provides the reference implementation for the JSP platform.
DEFINITION

A JSP container is similar to a servlet container, except that it also provides support for JSP pages.

3.1

Simple text
No programming book would be complete without an example that prints Hello, world! This simple task serves as an excellent starting point for experimentation. Once you can use a language to print a text string of your choice, youre well on your way to becoming a programmer in that language. For the web, it makes sense to print Hello, world! inside an HTML file. Heres a JSP page that does this:
<html> <body> <p> Hello, world! </p> </body> </html>

32

CHAPTER 3

First steps

At this point, youre probably thinking, Wait! Thats nothing but a plain HTML file. And youre exactly right; this example is almost disappointingly simple. But it emphasizes an important point about JSP pages: they can contain unchanging text, just as normal HTML files do. Typically, a JSP page contains more than simple static content, but this staticor templatetext is perfectly valid inside JSP pages. If a JSP container were to use the JSP page in the example code to respond to an HTTP request, the simple HTML content would be included in the generated HTTP response unchanged. This would be a roundabout way of delivering simple, static HTML to a web browser, but it would certainly work. Unfortunately, this example didnt show us much about what JSP really looks like. Heres a JSP page that prints the same Hello, world! string using slightly more of JSPs syntax:
<html> <hody> <p> <%= "Hello, world!" %> </p> </body> </html>

This example differs from the previous one because it includes a tag, or element, that has special meaning in JSP. In this case, the tag represents a scripting element. Scripting elements are marked off by <% and %>, and they let you include Java code on the same page as static text. While static text simply gets included in the JSP pages output, scripting elements let Java code decide what gets printed. In this case, the Java code is trivial: its simply a literal string, and it never changes. Still, the processing of this page differs from that of the prior example: the JSP container notices the scripting element and ends up using our Java code when it responds to a request.

3.2

Dynamic content
If JSP pages could only print unchanging text, they wouldnt be very useful. JSP supports the full range of Javas functionality, however. For instance, although the scripting element in the last example contained only a simple Java string, it might have contained any valid Java expression, as in
<%= customer.getAddress() %>

or
<%= 17 * n %>

Dynamic content

33

NOTE

As well see in chapter 5, JSP is not strictly limited to Java code. The JSP standard provides for the possibility that code from other languages might be included between <% and %>. However, Java is by far the most common and important case, and well stick with it for now.

Let s take a closer look at some examples of JSP pages that produce content dynamically.

3.2.1 Conditional logic


One of the simplest tasks for a Java program, and thus for a JSP page, is to differentiate among potential courses of action. That is, a program can make a decision about what should happen next. You are probably familiar with basic conditional logic in Java, which might look like this:
if (Math.random() < 0.5) System.out.println("Your virtual coin has landed on heads."); else System.out.println("Your virtual coin has landed on tails.");

This Java code, which simulates the flip of a coin, can transfer to a JSP page with only small modifications:
<html> <body> <p>Your virtual coin has landed on <% if (Math.random() < 0.5) { %> heads. <% } else { %> tails. <% } %> </p> </body> </html>

This example is similar to the Java code, except that JSP takes care of the output for us automatically. That is, we dont need to call System.out.println() manually. Instead, we simply include template text and let the JSP container print it under the right conditions. So what, exactly, does this latest example do? Up until the first <%, the page is very similar to our first example: it contains just static text. This text will be printed for every response. However, the template text is interrupted by the Java code between the <% and %> markers. In this case, the Java code uses Math.random() to generate a pseudorandom number, which it uses to simulate the flip of a coin. If this

34

CHAPTER 3

First steps

number is less than 0.5, the block of JSP between the first two { and } braces gets evaluated. This block consists of static text ( heads. ), so this text simply gets included if the conditional check succeeds. Otherwise, the value tails. will be printed. Finally, the template text after the final %> marker gets included, unconditionally, into the output. Therefore, this JSP page can result in two different potential outputs. Ignoring white space, one response looks like this:
<html> <body> <p>Your virtual coin has landed on heads. </p> </body> </html>

The other potential response is identical, except that the line containing the word heads is replaced with one containing tails. In either case, the browser renders the resulting HTML. Recall from chapter 2 that browsers do not need to know how the HTML was generated; they simply receive a file and process it.

3.2.2 Iteration
Another fundamental task for programs is iterationthat is, looping. Like conditional logic, iterative code can be moved into JSP pages as well. Lets take the previous example and turn it into a page that flips five coins instead of one:
<html> <body> <% for (int i = 0; i < 5; i++) { %> <p> Your virtual coin has landed on <% if (Math.random() < 0.5) { %> heads. <% } else { %> tails. <% } %> </p> <% } %> </body> </html>

How have we modified the example from the conditional logic section (other than by indenting it for clarity)? Weve simply added a Java for() loop around part of it, embedded between the same <% and %> markers that we used earlier. As shown in figure 3.1, this loop causes its body to be executed five times.

Dynamic content

35

Figure 3.1

A sample run of our iteration example.

To get more of a feel for iteration, lets look at a simple JSP page that prints a traditional multiplication table in HTML (figure 3.2). This table would be tedious to type by hand, even for the most capable mathematicians. JSP turns the problem into a simple programming task that can be solved using two loops, one nested inside the other:
<table border="1"> <% for (int row = 1; row < 11; row++) { %> <tr> <% for (int column = 1; column < 11; column++) { %> <td><tt><%= row * column %></tt></td> <% } %> </tr> <% } %> </table>

How does this example work? First, we set up an HTML table with the <table> element. Then, for each number in the outer loop, we start a new row with the <tr> element. Within each row, we create columns for each number in the inner loop using the HTML <td> element. We close all elements appropriately and, finally, close the table. Figure 3.3 shows the HTML source (from our browsers View Source command) for the HTTP response sent when the multiplication-table page runs. Note how, as weve emphasized before, the browser plays no part in the generation of this HTML. It does not multiply our numbers, for instance. It simply renders the HTML that the JSP engine generates.

36

CHAPTER 3

First steps

Figure 3.2

A multiplication table printed in a web browser

WARNING

You might not have expected JSP processing to add some of the white space that appears in figure 3.3. JSP processing preserves the spaces in the source JSP file. For example, the body of the inner loop in our multiple-table example begins by starting a new line, for a line starts immediately after the inner for() loops closing %> tag. In the majority of cases, you wont need to worry about the spacing of your output, but on rare occasions, you may need to eliminate extra white space in your source file.

This is the first example weve shown that mixes the simple <% marker with the <%= marker. As in the ASP environment, the <% marker introduces code that will simply be executed. By contrast, <%= introduces an expression whose result is converted to a string and printed. In the JSP code in the multiplication table example, the for() loops are structural and thus appear in blocks beginning with <%. When it comes time to print our row * column value, however, we include the Java code inside a block that starts with <%=.
NOTE

Well cover the details of these special markup tagsand describe more about iteration and conditional logicin chapter 5.

Dynamic content

37

Figure 3.3 Output of the multiplication-table JSP page

3.2.3 Non-HTML output


JSP doesnt care about the form of static, template text. To demonstrate that JSP isnt tied to HTML exclusively, heres a simple JSP page that can be used as a time service for cell phones. It outputs WML, a form of XML thats used by some wireless devices:
<%@ page contentType="text/vnd.wap.wml;charset=UTF-8" import="java.text.*, java.util.*" %><?xml version="1.0"?> <% SimpleDateFormat df = new SimpleDateFormat("hh:mm a"); %> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml"> <wml> <card id="time" title="Time"> <p>It's <%= df.format(new Date()) %>.</p> <p>(Do you know where your laptop is?)</p> </card> </wml>

38

CHAPTER 3

First steps

Dont worry about the details of WML. JSP doesnt, and WML specifics are beyond the scope of this book. This example just demonstrates an application of JSP beyond the traditional, HTML -based web. Figure 3.4 shows sample output on an emulator for a particular wireless device, the Ericsson R320s.
NOTE

For further details on the generation of non-HTML content, see chapter 15.

3.3

Processing requests and managing sessions


So far, our examples have performed simple tasks that arent inherently web based. That is, you could write a command-line or Windows program analogous to each of the JSP examples presented so far. Lets move on to JSP pages that are web specific. In JSP, several Java objects are exposed automatically to scripting code. When you write scripting code, you can refer to these objects without having to declare them by hand. Known as implicit objects, these variableswith names such as request, session, and responsegive you a simple mechanism to access requests, manage Figure 3.4 Output of a WML emulator sessions, and configure responses, among other tasks. The next few receiving input examples rely on features that the JSP container exposes through from a sample JSP implicit objects. They make sense only in environments that are, like page the Web, based on the request/response model described in chapter 2. We ll go into further detail about implicit objects in chapter 6. For now, we introduce them just to demonstrate some more of JSPs functionality.

3.3.1 Accessing request parameters


In chapter 2, we saw how the Java Servlets API gives servlets access to information sent as part of the request. We also saw an example of a servlet that uses this information to greet the user by name. Compared to the servlet in listing 2.1, the JSP code to perform the same task is even simpler. Heres a JSP page that works just like the servlet in the last chapter:
<% String name = request.getParameter("name"); %> <html> <body> <p> <% if (name != null) { %>

Processing requests and managing sessions

39

Hello, <%= name %>. <% } else { %> Welcome, anonymous user. <% } %> You're accessing this servlet from <%= request.getRemoteAddr() %>. </p> </body> </html>

This example pulls out two pieces of information from the request: the value of the name parameter and the IP address of the machine that sent the request. (The calls work just as they did in listing 2.1.) Notice that we didn t need to declare the request variable; the environment has done so for us. The call to request.getRemoteAddr() means, Get the IP address of the current request; every time the JSP page runs, the value of the request object automatically represents the then-current request. Accessing requests is very common in JSP, for access to requests lets JSP pages retrieve information from users. The request object is, by default, an instance of the same HttpServletRequest interface that we saw in chapter 2. All of the functionality of HttpServletRequest is thus available through the request object. For example, you can access the data entered into an HTML form by calling request.getParameter(), just as our example does.

3.3.2 Using sessions


Recall that HTTP is stateless, meaning that a web server starts with a blank slate as it processes each new request it receives. If you need to tie different requestsfor example, all requests from the same userinto a session, you need either to program this yourself or to use a platform that handles the task for you. Fortunately, JSP is one such platform. Well see how JSP actually manages sessions later, in chapters 4 and beyond, but lets take a look now at how sessions might be used. As we mentioned, scripting elements in JSP pages have access to an implicit session object. You can store and retrieve session-related data by using methods this object provides. As an example, imagine that during the processing of a request, you have built up an object called userData for a particular user. Suppose you wish to remember this object for subsequent requests that come from the same user. The session object lets you make this association. First, you would write a call like session.setAttribute("login", userData) to tie the userData object to the session. Then, for the rest of the session, even for different requests, you would be able to call session.getAttribute("login") to recover the same userData

40

CHAPTER 3

First steps

object. The session object keys data under particular names, much as a typical hash table, or an implementation of java.util.Map, does. In this case, the userData object is keyed under the name login. Lets see how sessions work in practice by converting our virtual coin-flip page from before into one that keeps track of how many times heads and tails have been chosen. Listing 3.1 shows the source code for such a page.
Listing 3.1
<% // determine the winner String winner; if (Math.random() < 0.50) winner = "heads"; else winner = "tails"; synchronized (session) { // initialize the session if appropriate if (session.isNew()) { session.setAttribute("heads", new Integer(0)); session.setAttribute("tails", new Integer(0)); } // increment the winner int oldValue = ((Integer) session.getAttribute(winner)).intValue(); session.setAttribute(winner, new Integer(oldValue + 1)); } %> <html> <body> <h1>Current standings:</h1> <table border="1"> <tr> <th>Heads</th> <th>Tails</th> </tr> <tr> <td><%= session.getAttribute("heads") %></td> <td><%= session.getAttribute("tails") %></td> </tr> </table> </body> </html>

A small application that uses sessions

Separating logic from presentation

41

At its heart, this page is similar to the one fr om be for e th at emulates a coin flip. However, the page contains extra logic to keep a tally of prior coin flips in the session object. Without getting too caught up in the details, the page initializes the session if it s new that is, if session.isNew() returns trueand then it keeps track of the tally for heads and tails, keying the data, imaginatively Figure 3.5 A stateful tally of prior events, made enough, under the names heads possible by session management. and tails. Every time you reload the page, it updates the tallies and displays them for you in an HTML table (figure 3.5). If you reload the page, the tallies change. If your friend, however, begins accessing the application from a different computer, the session object for your friends requests would refer to a new session, not yours. When different users access the page, they will all receive their own, individual tallies of heads and tails. Behind the scenes, the JSP container makes sure to differentiate among the various users sessions.

3.4

Separating logic from presentation


In the examples so far, Java code has been mixed right in with HTML and other static text. A single JSP file might contain some HTML, then some Java code, and finally some more HTML . While this mixture is a convenient way to generate dynamic content, it might be difficult for a large software-development team to maintain. For instance, programmers and HTML designers would need to manage the same combined JSP files. If problems are encountered, they might not be immediately clear whether they come from HTML problems or logic errors. To help address these issues and provide for greater maintainability, JSP provides another mechanism for generating on-the-fly content. In addition to the simple scripting elements weve shown, JSP allows special, XML-based tags called actions to abstract Java code away from the JSP page itself. Many actions look just like HTML tags, but they work like a signal to the JSP container to indicate that some processing needs to occur. When processing of a JSP

42

CHAPTER 3

First steps

page hits a block of static HTML text, like <p>Hello!</p>, such text is simply passed through to the JSP pages output. Processing for actions is different: when the JSP page hits an action, such as <jsp:include>, it runs extra code to figure out how processing should proceed. Unlike the Java between scripting elements <% and %> tags, however, the code for actions does not appear directly on the JSP page. Instead, it can either be built into the container or provided as a custom add-on by developers. Well cover actions in more depth in chapters 4 and 6. For now, lets take a look at how these tags might help you manage your JSP applications.

3.4.1 Reusing logic with JavaBeans


One common use of the special XML-based tags weve mentioned is to communicate with JavaBeans. In fact, JSP provides several standard action tags to help you communicate with these beans. As we discussed in chapter 1, JavaBeans are reusable Java components: they are Java classes that follow conventions, defined in the JavaBeans standard, that promote modularity and reusability. The details of this standard, as it relates to JSP pages, will be covered in chapter 8. For now, lets look at a simple JavaBean class so that we can present a JSP page that uses it:
package com.taglib.wdjsp.firststeps; public class HelloBean implements java.io.Serializable { String name = "world"; public String getName() { return name; } public void setName(String name) { this.name = name; } }

Indeed, this is a very simple Java class. It contains a single instance variable, name, which refers to a string. By default, this string has the value world, but it can be changed using the method setName(), which takes an instance of the Java String class as its parameter. Code outside the bean can retrieve the name by using getName(). These methods have names that the JavaBeans framework will look for, by default, when it needs to modify or retrieve the name variable, which in bean terms is called a property. A JSP page may use this bean as follows:
<html> <body> <p> <jsp:useBean id="hello" class="com.taglib.wdjsp.firststeps.HelloBean"/>

Separating logic from presentation

43

<jsp:setProperty name="hello" property="name"/> Hello, <jsp:getProperty name="hello" property="name"/>! </p> </body> </html>

The first action tag that appears is the <jsp:useBean> tag. As its name suggests, this tag lets the JSP page begin using a bean, specified by a particular class name and page-specific ID. In this case, we have indicated that we wish to use an instance of the HelloBean class and, for the purposes of the page, to call it hello. The appearance of the <jsp:setProperty> tag in the code causes the request parameter called nameif it exists and isnt an empty stringto be passed as the String parameter in a call to the beans setName() method. We could have written
<% if (request.getParameter("name") != null && !request.getParameter("name").equals("")) hello.setName(request.getParameter("name")); %>

and it would have had a similar effect, but <jsp:setProperty> is both easier to use and provides us with a level of abstraction. If we needed to set multiple properties in the HelloBean, <jsp:setProperty> would make our page substantially easier to read and less prone to errors. The final action tag that appears in the example is <jsp:getProperty>, which retrieves the name property from the HelloBean and includes it in the JSP pages output. Therefore, the example prints a personalized greeting if it can retrieve the users name from the request; if not, it simply prints Hello, world!, just like our first example. The bean-centered approach gives our page several advantages in readability and maintainability. As we just mentioned, the tags beginning with <jsp: take care of various operations for us behind the scenes. This way, we dont have to write Java code that manually sets and retrieves information out of the bean. Suppose that HelloBean were a little more complex. Instead of a bean that simply stores a name, imagine one that capitalizes names correctly or that uses the name as part of a database query that retrieves more information about the user. Even if HelloBean performed these extra tasks, its interface with the JSP page would be the same: <jsp:getProperty> and <jsp:setProperty> would still work just as they do in the example we just saw. If multiple pages in your applicationor even multiple applicationsneed to use the logic contained inside the bean, they can all simply use different copies of the beanor even the same copyvia the <jsp:useBean> tag. Beans therefore let you move more of your own Java code outside the JSP page itself, and they let you reuse this code among multiple pages. By

44

CHAPTER 3

First steps

contrast, Java logic that appears between <% and %> might need to be replicated in a number of different pages.
NOTE

We cover JavaBeans and bean-based design strategies in detail, beginning with chapter 7.

3.4.2 Abstracting logic with custom tags


Action tags thus have some of the benefits as do functions in a language like Java; they let you hide and reuse logic. Tags have an additional benefit, too: their syntax, being XML-based, is similar to that of HTML. Therefore, if you are working as a developer on part of a team that also includes nonprogramming HTML designers, you might decide that you want to expose your back-end functionality through tags instead of through simple function calls. As well discuss further in the next chapter, JSP lets you write your own new actions and expose them in tag libraries. Writing new tags is an advanced JSP topic that we leave until chapters 1719, but lets briefly look, for now, at how we might use one of the tags we demonstrate in those later chapters. One such tag is <mut:ifProperty>, which, in its simplest usage, conditionally includes the text contained between it and its ending </mut:ifProperty> tag if the specified property of a JavaBean is true instead of false. Once we import the appropriate tag library a procedure we'll learn more about in chapter 5we can use the <mut:ifProperty> tag in a JSP page as follows:
<mut:ifProperty name="user" property="important"> Welcome! Thanks for visiting again. </mut:ifProperty> <mut:ifProperty name="user" property="unimportant"> Oh, it's you again. Sigh. </mut:ifProperty>

WARNING

As we mentioned, this JSP fragment depends on advanced JSP features. You wont be able to run it just as it appears. See chapters 1719 for more information on custom tag libraries.

As with <jsp:setProperty>, we could have written functionally similar code by using Java inside <% and %> delimiters, but these tags give us a level of abstraction and allow us to reuse logic.

Review of examples

45

3.5

Review of examples
The goal in this chapter wasnt to cover any syntactic specifics or to explain behindthe-scenes operation; well have ample time for that later. For now, our progression of examples has given you a first look at JSP. Youve seen that JSP pages can contain
I

static HTML text static non-HTML text embedded Java code that supports iteration, conditionalization, and other abstract logic standard tags that, among other benefits, hide logic and let you access JavaBeans custom tags that youve written yourself, or that other developers have written

Now, were ready to look more formally at how JSP pages are composed and how they get processed before they execute.

How JSP works

This chapter covers


I I I I

JSP directives and scripting elements JSP action elements Phases in processing a JSP page Advantages of the JSP environment

46

The structure of JSP pages

47

In chapter 3, we jumped into JSP by looking at some of its capabilities. Lets now take a closer look at the structure of JSP pages, studying the building blocks of JSP pages in more detail. Full syntax and functionality will be covered in chapter 5 and beyond; our goal for now is to discuss how JSP works, what happens to JSP pages behind the scenes before and while they run, and how the JSP container provides services on which you will rely as you learn more about JSP.

4.1

The structure of JSP pages


As we saw in chapter 3, JSP pages JSP Page are a combination of text and special markup tags (figure 4.1). Template Scripting text is static text that s passed Directives elements through to the output, while the special JSP markup tags allow JSP Actions pages to be dynamic. For example, a markup tag might cause on-the-fly Standard Custom HTML to get generated, or it might actions actions decide whether static text will be displayed. A markup tag might also take some behind-the-scenes action, Template text such as sending an email or checking a database. One group of such dynamic JSP Figure 4.1 Elements that can appear, in any tags is reminiscent of ASPs syntax; order, in a JSP page this variety of tags supports configuration and scripting. Another class of tags is based on the syntax of the XML and lets JSP developers produce dynamic content without including Java code directly on a JSP page.

4.1.1 Directives and scripting elements


Some JSP tags begin with the characters <% and end with %>, the same delimiters used in the ASP environment. In JSP, an additional character may appear after the leading <% to further describe the purpose of the tag. Tags of this style have one of two purposes: either they include Java code in the JSP page, or they contain instructions for the JSP container.

48

CHAPTER 4

How JSP works

DEFINITION

If a tag introduces Java code into a JSP page, it is called a scripting element. A JSP directive, by contrast, provides instructions to the JSP container; it either requests action on the part of the container, or it specifies information about the JSP page.

The following tags are examples of scripting elements:


<%! int count = 0; %> <%= 2 * Math.PI * radius %> <% if (radius > 10.0) { out.println(Exceeds recommended maximum. } %>

Stress analysis advised.);

Similarly, examples of directives include:


<%@ page isErrorPage=true %> <%@ include file=header.html %>

NOTE

These tags are not compatible with XML; an XML document could not contain elements that begin with <% and end with %>, with somewhat arbitrary content in between. Since JSP 1.2 allows authorship of JSP pages in XMLcompliant syntax, as chapter 1 described, these tags pose a problem. JSP solves this issue by specifying a corresponding XML-compliant element for each type of non-XML tag. Chapter 5, in addition to covering the full use and functionality of directives and scripting elements, will go into further detail about the dual, XML-compliant elements.

4.1.2 Standard and custom actions


The rest of the JSP special markup tags are based on XML syntax. That is, they follow the style and conventions of XML. Before going into too much detail about how these tags work, lets first describe some of the basics of XML syntax, in case it is new to you.

Basic XML syntax XML looks a lot like HTML, but it is specified a more strictly. For example, XML tags are case sensitive, while HTML tags are not. When designing a page in HTML, you might choose to write either <p> or <P>, and it doesnt much matter which one you pick. In XML, these two tags are entirely different elements.

The structure of JSP pages

49

XML also requires that all attribute values be placed within quote marks. HTML is often written without quote characters surrounding attributes, as in
<a href=http://www.taglib.com/>

This tag would be illegal in XML; instead, the URL specified for the href attribute would need to be surrounded with either single or double quotes. XML also requires that every nonempty tagthat is, any tag that contains text or other tagshave an appropriate closing counterpart. It is common to see HTML that looks like this:
<ul> <li> First list item <li> Second list item </ul>

This fragment could not be part of a legal XML document. For use in XML, closing tags would need to be provided. For example:
<ul> <li> First list item </li> <li> Second list item </li> </ul>

Not every tag contains text or other tags, however. For instance, the HTML <br> tag stands alone and cant sensibly contain anything else. To differentiate such tags from those that do require a closing counterpart, XML uses /> as the ending delimiter for the tag. For instance, a standalone tag like HTMLs <br> would be written as <br/> in XML. (Technically, you could also write <br></br>, but there is generally little reason not to use the /> shortcut.) While HTML has a fixed set of tags, you can extend XML in application-specific ways by defining sets of tags that have meaning in a particular context. For instance, if you wanted to store a database of jokes in an XML file, you might define tags such as <joke>, <setup>, <punchline>, and so on, and then include them in a file as follows:
<joke quality=poor> <setup> ... </setup> <punchline>. ... and she said, No, silly, its a servlet container! </punchline> </joke>

To allow tags defined for different applications to appear unambiguously in the same file, XML uses namespaces, which are essentially collections of tag and attribute

50

CHAPTER 4

How JSP works

names. An XML file can refer to a namespace by attaching the namespace identifier, followed by a colon (:), to the beginning of a tags name. In this manner, a single XML file can use two different tags with the same name, as long as they are part of different namespaces. For example, if our joke-oriented tags were qualified with the namespace identifier joke, and a separate namespace identified by the name configuration had a <setup> element, namespaces would allow a single document to use both elements by specifying them as <joke:setup> and <configuration:setup>. (We leave it to your imagination to concoct a file that would appropriately contain both configuration directives and jokes.)

JSP action elements JSP actions are XML-style tags that cause special processing to occur at a specific point in the run-time execution of a JSP page. This processing might involve the text contained by the action tag, or it might simply involve calling some stand-alone Java code that performs a task. JSP action tags come in two varieties, standard and custom. First, JSP defines several tags known as standard actions.
DEFINITION

A standard action is an action tag that has been defined by the JSP standard. For JSP, standard actions are associated with the namespace jsp, and standard actions appear in JSP pages with a prefix of jsp:, even for JSP pages that are not written using the XML-compliant syntax mentioned earlier.

JSP defines actions that cover several commonly used features, like forwarding a request to a new page. Standard actions, however, are not the only actions supported in JSP pages. A powerful feature of JSP is the ability to program new actions. DEFINITION

A custom action is an action tag whose behavior is added to the environment through an API provided by the JSP standard. Collections of custom actions are usually called tag libraries.

Tag libraries are incorporated into JSP pages using the JSP <%@ taglib %> directive. This directive associates a prefix with each tag library imported into a page. As with namespaces, these prefixes prevent clashes between two tags with the same name but from different tag libraries. (In fact, in the XML view of a JSP page, tag libraries are imported using the actual XML namespace mechanism.)

The structure of JSP pages

51

NOTE

In some organizations that use JSP to develop large applications, custom tag libraries provide a means of abstracting logic away from JSP pagesand even for eliminating Java code from them, if this is desired. A complex operation, such as a database update, might be hidden behind a custom tag. In some cases, this abstraction can simplify maintenance of JSP pages. Some organizations have adopted the approach of separating JSP developers from tag developers: the former group is familiar with HTML and JSP tags, and the latter group programs in Java and exposes all custom application logic through tags. The premise, in short, is that HTML developers can easily learn how to use custom JSP tag libraries because the syntax of JSP tags is so similar to that of HTML. This organizational style is just one of many options for developing web applications, but it might help you envision one benefit of JSPs ability to expose Java logic through XML-like tags. We discuss several architectures and organizational models for JSP pages in chapter 10.

Although JSP actions are, as weve discussed, based primarily on XML syntax, JSP departs from XML syntax by allowing tags to be embedded within one another. This can happen in two different ways. First, any JSP tagincluding directives or scripting expressions can appear arbitrarily inside an HTML tag, supplying dynamic content to fill in the HTML tags attributes (or even part of its name). For example, the following is legal JSP:
<a href=<%= sourceVariable %>>

This is not a major issue, though; the JSP container can regard HTML merely as arbitrary text. Since JSP doesnt process HTML tags, it can treat them as plain text. And since JSP tags can clearly be embedded in plain text, it is not problematic to embed them in HTML or other tag-based content. Second, more interesting use of JSP tags occurs inside other JSP tags. Specifically, a JSP scripting expression can specify the value of a JSP actions attribute. For example, the following can be legal JSP:
<myTagLibrary:customAction attribute=<%= value %> />

As a real-life example of this feature, consider the following use of a standard action tag:
<jsp:setProperty name=login property=visits value=<%= previousVisits + 1 %>/>

52

CHAPTER 4

How JSP works

Such embedded tags are referred to as request-time attribute expressions or requesttime attribute values, for the attributes value is determined when the page is run in response to a request, not when the page is initially processed. These embedded expression tags may look strange, but they are very useful in practice. Well see more about request-time attribute values, including the restrictions placed on their use, in the next three chapters. The syntax weve shown here for request-time attribute values is not valid in XML. But like other constructs valid in JSP but not in XML, the JSP standard defines an XML-attribute equivalent that can be used when authoring pages in XML syntax. The particulars of this mechanism are not important for now, however.
NOTE

Details on most JSP actions will be presented in chapters 5 and 6. A few action tags, however, are specific to JSPs built-in support for the JavaBeans component programming model. Descriptions of these tags will be covered in chapter 7.

4.2

Behind the scenes


Once a JSP container has been installed and configured, using it is relatively straightforward. JSP files that are added to the appropriate directory hierarchyor otherwise marked off in a manner agreed upon by the web server and the JSP server, such as by using a file extension of .jsp or another configured valueare simply handled by the JSP container when appropriate. (Chapter 13 describes the process of deploying JSP applications in more detail.) Although you can rely on this process and ignore the details of how the JSP container works most of the time, some knowledge of its operation will help you get more out of the JSP environment.

4.2.1 Translation to servlets


Like most source code, JSP pages start life as text files and end up being compiled. A JSP file, though, takes a somewhat more circuitous route through this process than does a typical Java program. Before being run, JSP pages are translated to servlets. This translation involves conversion of JSP source code into servlet source code by the JSP container. (This step is sometimes referred to as compilation of a JSP page into a servlet, but it should be differentiated from compilation of Java code into bytecodes.) After this translation, the servlet class is, itself, compiled. Because JSP pages are translated to servlets, they inherit servlets dependence on the request/response model. JSP pages, like servlets, are called in response to

Behind the scenes

53

requests, and they produce responses. When the JSP container translates the body of a JSP page into a ser vlet, it produces a new class that implements the javax.servlet.Servlet interface. This class has a method called _jspService() that is built from the body of the JSP page. Furthermore, unless the page author specifically requests greater control via the extends attribute of the <%@ page %> directivewhich is extremely rarethe container bases the generated class on a class whose service() calls _jspService(). In short, a JSP page is translated into a method that maps requests to responses based on the contents of the JSP page. How do the contents get translated? The easiest part of the JSP source file to translate is the template textthat is, the part of the page that isnt a directive, a scripting element, an action, or anything else specific to JSP (such as JSP comments, which will be introduced in chapter 5). This template text might be HTML, or it could be XML or text in an arbitrary format. The JSP container doesnt care what it is; it simply outputs it as part of the response. For example, the following text:
<p>Template text</p>

might be converted into a call that looks like


out.println(<p>Template text</p>);

Scripting expressions are also easy to translate and incorporate into the servlet, for the Java code embedded in them is passed through as is. The Java code will be included at the right place in the servlet, and it will be run as appropriate when the servlet is run.
WARNING

As we will see again in chapter 5, JSP technically allows scripting languages other than Java to be included in scripting expressions. However, the JSP 1.2 standard doesnt provide formal rules for what happens when a JSP page uses a language other than Java for scripting elements. The discussion here applies only to cases where Java is used as the scripting languagewhich is, for now, the vast majority.

Action elements are somewhat more complicated to transfer, but the end result is that the JSP container writes calls to appropriate Java code at the correct spots in the generated servlets source code. If the action is a custom action youve written yourself, the translation will involve creating calls to your custom code. Once the translation from the JSP page into a servlet is complete, the behindthe-scenes servlet is compiled into Java bytecodes.

54

CHAPTER 4

How JSP works

4.2.2 Translation versus execution


JSP defines two stages of processing for JSP pages: the translation phase and the exe-

cution phase. (It is common to speak of the execution phase as the request phase or simply as run time). Weve just discussed what occurs during translation: the JSP page is converted into a servlet. Subsequently, when a request is received by the container, this servlet is run. The distinction between the purposes of the two phases is clear, but there are still some differences worth emphasizing.

Performance implications The translation phase occurs only when necessary, not as a response to ever y request. As you can imagine, the process of parsing a JSP page, translating it to a servlet, and then compiling that servlet can be time-consuming. Fortunately, the JSP container does not need to repeat the process of translation for each request that it handles. As long as the underlying JSP page hasnt been changed, theres no reason to generate a new servlet. A typical JSP container, therefore, will check the last modification time on a JSP file, and it will translate the file only if necessary. This extra check does not reduce the amount of time necessary for translation upon the first request for a JSP page; however, all subsequent requests will proceed much more quickly, for these requests can simply be served from a compiled servlet. (This process is summarized in figure 4.2.)
TIP

JSP also supports precompilation of JSP pages into servlets to avoid the performance hit associated with compiling a JSP page the first time it is requested. If the JSP page is compiled before any user requests it, the first request will proceed smoothly. For details, see chapter 13.

The separation of translation and request phases gives JSP a performance edge over many other web-based development environments. In many scripting environments, script code needs to be interpreted for every request. Since JSP can take care of expensive parsing and compilation operations before requests are processed, the JSP containers delay during a response is greatly reduced. Furthermore, since JSP pages depend on servlets, the JSP environment automatically yields the benefits of servlets performance improvements. Recall from chapter 1 that servlets are multithreaded, which makes them substantially faster than environments such as CGI that depend on spawning new processes at request time.

Behind the scenes

55

Web request JSP container

JSP servlet current?

No

Translate JSP into servlet

Compile servlet

Compiled servlet Process request using logic from JSP page

Web response
Figure 4.2 The typical process for translating and running JSP pages

Error handling Another difference between the translation and request phases concerns how errors are handled. Translation-time errors in JSP are analogous to compile-time errors in traditional Java programming: some, but not all, errors can be caught before the program even runs, but the rest must, unfortunately, show up at run time. Broadly speaking, there are two sorts of translation-time errors a container might encounter. First, there are errors in the structure of the JSP page. For instance, a scripting expression might not contain its closing %>, or a directives name might be misspelled. In cases like this, the container might be able to

56

CHAPTER 4

How JSP works

pinpoint the errors location in the JSP file and return a reasonably useful message to help you fix the problem. The second class of errors is more insidious; these errors show up only once the JSP page is translated into a servlet. Recall that the JSP container does not necessarily process Java code embedded within scripting elements; it merely includes this code directly as part of the servlets source code. Therefore, errors in such code only show up as a failure of the generated servlet to compile. If this embedded Java code leads to a compile-time error, the error can be somewhat difficult to track down. The container might provide you with only the errors line number in the offending servlets source code, for example. You might get lucky and be able to correlate a misspelling highlighted by the compilers error with a misspelling in the original JSP code, but if not, you might need to look through the generated servlets source code to identify the problem. (The location of the servlets source code is container-specific; check your JSP containers documentation to find out what it does with its generated servlets.) The way that containers report errors is implementation dependent, but if the problematic translation occurred in response to a web request for a newly changed JSP file, it is likely that the error will be reported as part of the HTTP response to that request. That is, youll get the error message in your web browser, instead of getting the output you expected. This often lets you debug without having to search through log files to find error messages. As we mentioned, not all errors can be caught at translation time. Request-time errors occur by virtue of a Java exception (or, more strictly, a Java Throwable object) being thrown as the JSP page s compiled servlet is run in response to a request. JSP provides a mechanism to let developers catch request-time errors gracefully; well discuss the advantages of this mechanism in the next section and detail its operation in chapter 14.

4.3

What the environment provides


JSP inherits convenience features from servlets, and it provides features of its own. Lets take a look at some of these advantages and go into detail about how JSP con-

tainers provide them. These services are some of the features youll come to rely on as you design and write JSP applications.

4.3.1 Automatic servlet generation


As weve seen, an obvious difference between writing servlets and JSP pages is that JSP authors dont need to write servlets manually. Instead, the JSP container creates

What the environment provides

57

servlets automatically. In fact, JSP might be looked ator even usedas a convenient platform for developing stand-alone servlets rapidly. (In practice, though, most JSP authors think of servlets as a behind-the-scenes detail.) Besides the simple convenience of not having to write doGet() and doPost() methods by hand, the automatic creation of servlets has another important advantage: it supports an organizational model that separates presentation tasks from back-end implementation tasks. That is, JSP provides for a productive division of labor for web-application development. Because the JSP environment takes care of the compilation process automatically and hides the details of the Java methods that need to be written, JSP pages become more accessible to nonprogrammers or novice programmers. JSP authors do not need to know the detailed structure of a Java class or the syntax for declaring methods; instead, they can write Java code as if it were simple scripting code. Furthermore, as we noted earlier, some uses of JSP that rely heavily on tag libraries can even push Java code entirely out of JSP pages.
NOTE

Engineers working under the Java Community Process are striving to provide a standard tag library for JSP with some of these goals in mind. Automatic servlet generation made JSP pages accessible to novice programmers, and a standard tag library would continue the trend by providing new standard tags for common operations within JSP page. These tags could help minimize the use of Java code in JSP pages. For example, instead of writing a simple conditional block using Java code inside scripting expressions, a JSP author could use a standard conditional tag to provide for control flow.

Even advanced Java programmers can appreciate the convenience that comes with automatic generation of a servlet. If a programmer needs to add dynamic content to a web page, adding a simple scripting element is much easier than manually writing a servlet that prints out a large block of HTML with calls like out.println().

4.3.2 Buffered output


As we saw in chapter 2, HTTP places constraints on the way that web applications can interact with web browsers. In that discussion, we saw that HTTP responses typically contain a status line, followed by headers, followed by a body. This sequence is not negotiable; that is, once the body of an HTTP response begins transmission on the network, the web server has lost its opportunity to specify headers or the status line. Because the pre-body structures support error reporting (among many other features), this constraint might have been a problem for fault-tolerant JSP

58

CHAPTER 4

How JSP works

JSP Page Generated response

JSP Page Generated response

Buffer
modify clear send

Figure 4.3

Unbuffered versus buffered output. When output is unbuffered, it leaves the JSP pages control immediately and cannot be retracted.

applications. Suppose that halfway through the code that generates a response, an error occurs, and the JSP page decides that it needs to set a status code to describe the error or a header to forward the user to a new page. If the web server has already sent part of the responses body, it will not be able to go back and edit the headers or status line. JSP solves this problem by buffering the output of JSP pages.
DEFINITION

A buffer is a temporary space for storing information. Buffering involves using such temporary space to hold data before sending it on to its ultimate destination.

Instead of sending the output generated by a JSP page directly to web browsers, the JSP container first buffers the output. This buffering gives the JSP page leeway if it needs to add or modify a header after generation of the pages output has begun. That is, the JSP page can simply modify the buffer before sending it on the network. If the JSP page decides to forward the request to another page, it can simply clear the buffer (figure 4.3).
WARNING

JSP output buffers do not grow automatically; that is, they have a fixed size. We will see in the next chapter how to configure this size, but it is important to understand how the buffer size might affect the functionality of a JSP

What the environment provides

59

page. By default, when the buffer fills up, its contents are sent to the browser. Therefore, once the initial buffer for a response has filled up and is sent, the JSP page no longer has an opportunity to set headers. If seamless error reporting or header handling is essential to an application, the JSP container can be configured to throw an exception when the buffer becomes full. This prevents a partial response from being sent to the web browser, and it ensures that a JSP page will never run into a situation where it unexpectedly finds it cant set a header. In practice, however, it is rare for an output buffer to be filled by a JSP application; the default size must be at least 8 kilobytes (KB) on any container, and this is enough for a typical JSP page. For details, see chapter 5.

Because the JSP container, by default, automatically builds output buffering into the servlets it generates for JSP pages, JSP authors can simply forget about the issue in most cases. For example, you can use the mechanisms well discuss in chapter 6 to modify the responses headers, and you will not typically need to remember how HTTP response messages are structured. The container takes care of the ugly details for you.

4.3.3 Session management


As we saw in chapter 2, HTTP is stateless, meaning in part that HTTP servers do not remember requests once theyve processed them. If a server gets three requests in a row from the same web browser, it sees these as three separate requests; nothing binds them together.

Cookies One common way to connect requests together is through HTTP cookies, which work specifically to bind requests together. Cookies work as follows: in response to a request, a web server decides to send a cookie to a browser. It does this by adding a particular header to its response. If the browser supports cookies, it processes the header and finds the cookie, which it stores for later use. For all subsequent requests the browser sends, the browser checks its lists of cookies and finds the ones whose properties indicate that the cookie is appropriate for the request. Keep in mind that the server does not subsequently request cookies it has sent. Instead, the server relies on the browser to send cookies automatically once the browser receives them. (This process is depicted in figure 4.4.) If a server wants to link requests together into a session, it is easy to see how it might accomplish this via cookies. Suppose a ser ver stores a unique session

60

CHAPTER 4

How JSP works

Browser a

Request Response

Server

Headers Cookie

Body

Headers Cookie

Body

Browser

Request Response

Server

Time

Request Response

Request Response

Figure 4.4

Setting and using an HTTP cookie. Step 1, a cookie is sent to the browser as part of the response headers (a). Step 2, once the cookie is sent, it is sent back by the browser automatically for all requests in the cookies scope. The server does not subsequently request the cookie; it gets it automatically (b).

identifier in the cookie that it sends to a browser. When the server processes subsequent requests and notices this session ID in a cookie sent back to it, it knows that the request came from the same user to whom the server sent the cookie in the past.
NOTE

Because not every browser supports cookies, other mechanisms have been devised for handling session management. A session ID can be sent back to the server as part of the URL (a practice generally known as URL rewriting), or for form-based applications, it can be included in HTML forms as

What the environment provides

61

an <input type=hidden> element. Since environments such as JSP can dynamically generate HTML, including the URLs and forms it contains, web developers can add the appropriate session IDs to HTML output as part of their applications responses.

Sessions are extremely popular in web applications, since they allow an application to remember previous actions of the user and provide a level of continuity in the user interface. For instance, any e-commerce web site that lets a user browse products and store them in a shopping cart needs some way to manage sessions. Applications that support data entry across multiple HTML forms also require some way to associate the various forms with one another. Portal sites may allow a user to receive a customized view of an application without having to repeatedly enter their preferences; to do so, they needs sessions. Fortunately, the JSP environment supports sessions automatically, for it inherits the session support that comes with the servlet platform. By default, a JSP page has access to an implicit object called session that represents the session for the current request. The author of the JSP page can store data in this session and retrieve it later, during a different request. The JSP container takes care of session-management automatically; individual JSP pages do not typically need to handle session IDs or decode session cookies automatically. There is a small caveat: if an alternative to cookies is used, more work may need to be handled manually by the JSP page; for instance, if URL rewriting is used, URLs need to be generated dynamically and cant appear simply as static text in the page.

Session pitfalls JSPs session management facilities usually let JSP developers ignore the underlying mechanism; for the most part, JSP pages can assume that session management is handled properly by the container. However, two issues related to session management might complicate the design and deployment of web applications. First, a session-based web application that serves a large base of users should consider how much storage each session requires. Even if you store data as small as 5 KB in the session, supporting 1,000 simultaneous users takes up 5 megabytes (MB) of storage. For a million active sessions, the requirement becomes 5 gigabytes (GB ). There is no need for all of this storage to be physical memory, of course; typical operating systems support virtual memory as well. Still, an application that has a large base of users requires careful planning and an understanding of storage requirements imposed by sessions; the size of the data stored in a session has a

62

CHAPTER 4

How JSP works

direct impact on the number of simultaneous users that can be practically supported on a particular hardware configuration.
TIP

Java has no analog of the sizeof operator in C or C++, but you can estimate the storage requirements of a Java object in several ways. In some cases, you can make this estimate by writing a stand-alone program that calls the freeMemory() method of java.lang.Runtime before and after instantiating the object. Another strategy is to use Javas serialization facility. If the object you are measuring implements the java.io.Serializable interface, you can write it out to disk using the writeObject() method of java.io.ObjectOutputStream. The size of the resulting file will provide a conservative estimate of the objects memory footprint.

Weve discussed active or simultaneous users, but this concept is somewhat vague. Because HTTP is stateless, JSP containers have no way of knowing or not whether a session is still in use. A user might simply be taking a long time to fill in a form, or that user might have exited the web browser and walked away from the computer. JSP and servlets base session expiration on time-outs. After a configurable period of inactivity, the session and its contents will be removed from memory. Applications can also provide an explicit mechanism to let a user log out; for example, an application can display a link labeled Log Out and clear out a session in response to that link. (Of course, there is no guarantee that users will click such a link before leaving the application, so the inactivity time-out is useful in these cases as well.) A second issue is that sessions have an effect on the scalability of your application. Suppose an application has too many users to run with acceptable performance on a single server. A common response might be to spread the application out among many servers. This strategy is known as load balancing or load distribution. However, session management complicates such a solution, for the session object represents an actual, in-memory Java object on a particular computer. This object is not automatically available on every server that might need to take part in the processing of the application. One way around this is to make sure the users browser always communicates with the server that happens to store that particular users session. For instance, the application might have a front page that chooses one of several load-balancing servers randomly and then redirects the user to that server. All of the users subsequent interactions will be with that server, and the application will therefore be able to recover the users session state easily, for it exists as a simple object on that server.

What the environment provides

63

In some cases, this approach is not good enough. For example, if a high degree of fault tolerance is required, it might not be acceptable to associate a particular server with a user; if this server goes down, the user may be left stranded. In other situations, a higher granularity of load-balancing might be necessary; an application or container might need to decide to pass off a user to a new machine in the middle of that users session. In some cases, it may therefore be necessary to make sure that all servers that take part in an application are able to recover a users session. This is handled by a mechanism known as session migration , which involves copying a users session object from one server to another as needed.
NOTE

Web applications in a servlet environment may be marked as distributable using a feature defined in the servlet standard. When an application is marked in this manner, objects stored in the session should implement the same java.io.Serializable interface that we noted earlier. Keep this in mind when using sessions from within JSP pages that are part of a distributable application. Making sure that the objects you store in your sessions are serializable is good practice in general, since it also allows sessions to be stored on server shutdown under JSP containers that support this behavior.

4.3.4 Exception handling


JSP uses Javas exception-handling mechanism, which helps keep code readable by

letting developers focus on the tasks theyre trying to solve, instead of on handling errors manually. A key principle of Javas exception support is that it lets errors propagate up to the code thats appropriate to handle them. For instance, a library function might be able to deal with some errors, but it should pass any errors it cant handle up to its caller. A JSP page works similarly: if a JSP page wants to handle certain types of unexpected events, it certainly can do so. But a JSP page can also ignore certain errors and let them be handled by code that gets built into the servlets that the JSP container generates. Specifically, JSP allows you to specify an error page that handles unexpected errors that occur during its processing. Suppose you write a JSP page that connects to a database, but the database is down. You dont need to catch this unexpected event by writing code in your JSP page. Instead, you can use the errorPage mechanism to let the environment catch the error for you, thus giving you less to worry about for each new JSP page you write.
NOTE

The errorPage mechanism is described further in chapters 5 and 14.

64

CHAPTER 4

How JSP works

4.3.5 Implicit objects


The Servlet API specifies a Java mapping to functionality that is useful for web applications. For example, through the HttpServletRequest and HttpServletResponse interfaces introduced in chapter 2, Java web applications can easily access requests and configure responses. Since JSP inherits functionality from the servlet API, JSP applications can take advantage of the convenient Java mappings provided by the servlet environment. JSP takes things a step further, too, by giving simple names to commonly used objects. These names can be accessed from within scripting elements to give Java code within JSP pages easy access to its environment. For instance, in a JSP page operating over HTTP, the name request is given to the HttpServletRequest object, and request parameters can be accessed simply through calls to request.getParameter(). This explains the convenient syntax we demonstrated in chapter 2.
NOTE

There are implicit objects for accessing the request, the response, the session, and other useful functionality, including the exception-handling features we just mentioned. Implicit objects will be covered in detail in chapter 6.

4.3.6 Support for JavaBeans and HTML forms


Recall that JavaBeans are reusable Java components that can simplify application development. JSP includes built-in support for JavaBeans through standard actions that let you easily set and retrieve properties from JavaBeans without having to write Java code to do so. Recall also that the servlet environment, and hence JSP, also supports automatic parsing of request parameters for example, data from HTML forms. Servlets and JSP pages have simple access to request parameters through an object of type HttpServletRequest. Using these two features together can simplify one of the most common tasks that web developers need to implement: reading and storing information from HTML forms. JSP provides a standard action, <jsp:setProperty>, that has a mode that causes data from an entire form to be stored in an appropriately constructed JavaBean. This means that in many cases, you can process an HTML form without writing more than a single line of code.
NOTE
<jsp:setProperty> and other features of JSPs JavaBean support are dis-

cussed in detail in chapter 7.

Programming JSP scripts

This chapter covers


I I I I

Using JSP directives JSP scripting elements Flow of control via scriptlets Comments in JSP pages

65

66

CHAPTER 5

Programming JSP scripts

In chapter 1, emphasis was placed on leveraging component-centric design to promote the separation of presentation and implementation. By taking advantage of JSPs built-in support for server-side JavaBeans, it is possible to write JSP pages that contain only HTML and HTML-like tags. Doing so yields considerable benefits with respect to code reuse, application maintainability, and division of labor. This purist approach to JSP development is not always the most practical solution, however. Circumstances may dictate the use of an alternative approach: JSP pages with embedded scripts, typically referred to as scripting elements. For example, when developing an application prototype, the schedule may not provide developers with sufficient time for a full-scale component design effort. Of course, if the design is not based on JavaBeans, then the JSP bean tags (see chapter 7) will be of little use. The scripting tags, however, can apply the full expressive power of the underlying Java language, and are, therefore, fully compatible with whatever data model you select, JavaBeans or otherwise. Furthermore, even if you are using JavaBeans, the capabilities of the built-in JSP bean tags are somewhat limited. If your needs go beyond the creation of server-side JavaBeans and the access and modification of their properties, you will either need to use (and perhaps even write) a custom tag library, or take advantage of the existing scripting tags. Like JavaBeans component design, creating a custom tag library requires a considered approach that your development schedule may not permit. Designing a custom tag library is only justified when you know you will be using its custom tags over and over again. Reusability is a key element of tag library design, and a key reason that good library design tends to be difficult and time-consuming. If such an effort is infeasible, the scripting tags are available to supply any required functionality not provided by the standard bean tags. What scripts lack in abstraction, then, they more than make up for in power. This power results, of course, from the ability of scripts to express arbitrary computations in the associated scripting language. With the full strength of a programming language at their disposal, scripts are the ultimate tool of last resort when developing JSP: if you cant find another way to do something, you can always write a script. And, as suggested earlier, there are also times when scripts are the first tool of choice.

5.1

Scripting languages
The default scripting language for JSP is, naturally enough, Java. Unless otherwise specified, the JSP parser assumes that all scripting elements on a page are written in

Scripting languages

67

Java. Given that JSP pages are compiled into Java servlets, this assumption makes the translation of scripts into servlet code very straightforward. The JSP specification, however, allows JSP implementers to support alternative scripting languages as well. To be acceptable for use with JSP, a scripting language must meet three requirements:
I

It must support the manipulation of Java objects. This includes creating objects and, in the case of JavaBeans, accessing and modifying their properties. It must be able to invoke methods on Java objects. It must include the ability to catch Java exceptions, and specify exception handlers.

More succinctly, for a scripting language to be compatible with JSP, it needs to have sufficient expressive power to take advantage of the capabilities provided by the JSP platform. For example, if a scripting language cannot access Java objects and call their methods, it cannot read request parameters, participate in session management, or set cookies. The core functionality of JSP is made accessible to web developers via Java objects, so a scripting language that cannot use these objects is of limited utility. If a scripting language is able to interact with Java objects, or can be extended to interact with Java objects, then it is a good candidate for integration with a JSP container. Caucho Technology, for example, has developed a JSP container called Resin, which is integrated with the companys Java-based implementation of JavaScript. As a result, Resin supports both Java and JavaScript as its scripting languages. Support for alternative scripting languages makes JSP accessible to a larger development community by giving developers who are uncomfortable with Java syntax the option to use a different programming language in their JSP pages. Unfortunately, while alternative languages for JSP scripting are supported by the JSP specification, portable mechanisms for integrating scripting languages with JSP containers are not. Such a mechanism is under consideration for a future version of JSP, but the only JSP scripting language that is universally available is Java. For this reason, we will use Java as the scripting language for all of the examples in this book. If you are using a JSP container that supports scripting languages other than Java, please consult your software documentation for further details on the use of those alternatives.

68

CHAPTER 5

Programming JSP scripts

5.2

JSP tags
JSP provides four major categories of markup tags. The first, directives, is a set of tags for providing the JSP container with page-specific instructions for how the document containing the directives is to be processed. Directives do not affect the handling of individual requests, but instead affect global properties of the JSP page that influence its translation into a servlet. Scripting elements are used to embed programming instructions, written in the designated scripting language for the page, which are to be executed each time the page is processed for a request. Some scripting elements are evaluated purely for their side effects, but they may also be used to generate dynamic content that appears in the output of the page. Comments are used for adding documentation strings to a JSP page. JSP supports multiple comment styles, including one which enables documentation to appear in the output from the page. Other JSP comments can only be viewed in the original JSP file, or in the source code for the servlet into which the page is translated. Actions support several different behaviors. Like scripting elements, actions are processed for each request received by a page. Actions can transfer control between pages, specify applets, and interact with server-side JavaBeans components. Like scripting elements, actions may or may not generate dynamic content. All custom tags incorporated via extended tag libraries take the form of actions. The remaining sections of this chapter cover the first three categories of JSP tags, while the fourth will be presented in chapters 6 and 7. The individual tags included in these categories are introduced, and their use is described.

5.3

JSP directives
Directives are used to convey special processing information about the page to the JSP container. For example, directives may be used to specify the scripting language for the page, to include the contents of another page, or to indicate that the page uses a custom tag library. Directives do not directly produce any output that is visible to end users when the page is requested; instead, they generate side effects that change the way the JSP container processes the page.

5.3.1 Page directive


The page directive is the most complicated JSP directive, primarily because it supports such a wide range of attributes and associated functionality. The basic syntax of the page directive is as follows:

JSP directives

69

<%@ page attribute1="value1" attribute2="value2" attribute3= %>

White space after the opening <%@ and before the closing %> is optional, but recommended to improve readability. Like all JSP tag elements, the page directive has an XML-based form, as well:
<jsp:directive.page attribute1="value1" attribute2="value2" attribute3= />

Attribute specifications are identical for the two tag styles, and there are twelve different attributes recognized for the page directive. In the examples to follow, we will use the first style, which is much more amenable to manual page creation. To use the XML format, the entire JSP page must be specified as an XML document, such as is produced when a page using the first style is parsed by the page compiler (see chapter 20 for further details).
Table 5.1 Attributes supported by the page directive

Attribute
info language contentType

Value
Text string Scripting language name MIME type, character set Character set Class name Class and/or package names Boolean flag Buffer size, or
false

Default
None
"java"

Examples
info="Registration form." language="java" contentType="text/html; charset=ISO-8859-1" contentType="text/xml" pageEncoding="ISO-8859-1" extends="com.taglib.wdjsp.MyJspPage" import="java.net.URL" import="java.util.*, java.text.*" session="true" buffer="12kb" buffer="false" autoFlush="false" isThreadSafe="true" errorPage="results/failed.jsp" isErrorPage="false"

See first example


"ISO-8859-1"

pageEncoding extends import session buffer autoFlush isThreadSafe errorPage isErrorPage

None None
"true" "8kb" "true" "true"

Boolean flag Boolean flag Local URL Boolean flag

None
"false"

A summary of the twelve attributes supported by the page directive is presented in table 5.1, and individual discussions of each attribute follow. In view of this large number of attributes, you will likely find it very convenient that JSP allows you to specify multiple page directives on a single page. With the exception of the import

70

CHAPTER 5

Programming JSP scripts

attribute, however, no individual page directive attribute may be specified multiple times on the same page. This means an attribute cannot appear multiple times within the same directive, nor can it appear in multiple directives on the same page. For example, the following sequence of page directives is valid, since the only attribute that is repeated is import:
<%@ page info="This is a valid set of page directives." %> <%@ page language="java" import="java.net.*" %> <%@ page import="java.util.List, java.util.ArrayList" %>

The following page directive, however, is not valid, because the session attribute occurs twice:
<%@ page info="This is an invalid page directive" session="false" buffer="16k" autoFlush="false" session="false" %>

Similarly, this sequence of page directives is invalid because the info attribute is repeated:
<%@ page info="This is not a valid set of page directives." %> <%@ page extends="com.taglib.wdjsp.MyJspPage" info="Use my superclass." %>

Unrecognized attributes are also invalid. If a JSP page contains any invalid page directives, a translation-time error will result when the JSP container attempts to generate the source code for the corresponding servlet.

Info attribute The info attribute allows the author to add a documentation string to the page that summarizes its functionality. This string will then be available for use by the JSP container or other tools in a programmatic manner for displaying the summary information. There are no restrictions on the length or contents of the documentation string, but author, version, and copyright information are commonly included, as in the following example:
<%@ page info="The CLU homepage, Copyright 1982 by Kevin Flynn." %>

The default value for the info attribute is the empty string.

Language attribute The language attribute specifies the language to be used in all scripting elements on the page. All JSP containers are required to support Java as a scripting language, and this is the default if the language attribute is not explicitly specified. As indicated earlier in the chapter, support for other scripting languages is optional, and

JSP directives

71

varies among JSP implementations. Here is how the language attribute is used to specify Java as the scripting language:
<%@ page language="java" %>

Note that if the include directive is employed, scripting elements in the included page must use the same scripting language as the current page.

ContentType attribute This attribute is used to indicate the MIME type of the response being generated by the JSP page. Although MIME stands for Multipurpose Internet Mail Extensions, MIME types are also used to indicate the type of information contained in an HTTP response, and this is the context in which they are used in JSP. The most common MIME types for JSP are "text/html", "text/xml", and "text/plain", indicating responses in HTML, XML, and plain text formats, respectively. To specify that a JSP document is generating XML content, for example, this attribute is specified as follows:
<%@ page contentType="text/xml" %>

The default MIME type for JSP pages is "text/html". The contentType attribute can also be used to specify an alternate character set for the JSP page. This enables page authors to deliver localized content using the language encoding most appropriate for that content. The character set is specified via the contentType attribute by appending a semicolon, the string charset=, and the name of the desired character set to the end of the attribute value. (An optional space is permitted between the semicolon and charset=.) For example, to specify an HTML response using the (default) ISO-8859-1 character set, the following directive would be used:
<%@ page contentType="text/html; charset=ISO-8859-1" %>

Note that if the response to be generated by a JSP uses an alternate character set, the JSP page must itself be written in that character set. Of course, the JSP container cant know a page is using an alternate character set until it reads the page directive that specifies the character set, so only character sets that allow specification of this directive are valid for use in a JSP page. Once the directive has been read by the JSP container (i.e., using the default character set), it can switch to the indicated character set for the remainder of the page. All the characters read before switching character sets, however, must be compatible with the final character set. The official registrar for both MIME types and character sets is the Internet Assigned Numbers Authority (IANA). This standards body maintains lists of all valid MIME types and character set names.

72

CHAPTER 5

Programming JSP scripts

PageEncoding attribute The pageEncoding attribute, introduced in JSP 1.2, provides an alternate means for specifying the character set used by the JSP page. Instead of supplying the character set as part of the contentType attributes value, it can be declared independently via the pageEncoding attribute, as in:
<%@ page pageEncoding="ISO-8859-1" %>

The default character set for JSP pages is ISO-8859-1, also known as latin-1. The various caveats regarding alternate character sets presented in the discussion of the contentType attribute apply to the pageEncoding attribute, as well.

Extends attribute The extends attribute identifies the superclass to be used by the JSP container when it is translating the JSP page into a Java servlet, and is specified as follows:
<%@ page extends="com.taglib.wdjsp.myJspPage" %>

There is no default value for this attribute. If this attribute is not specified, the JSP container is free to make its own choice of JSP servlet class to use as the superclass for the page. Note that if you specify this attribute, JSP imposes certain restrictions on the specified superclass. If, as is typically the case, the JSP page is being delivered via the HTTP protocol, then the specified superclass must implement the javax.servlet.jsp.HttpJspPage interface. If an alternate protocol is being used, then the specified superclass must implement the javax.servlet.jsp.JspPage interface. (The API documentation for these classes is available from Sun Microsystems, and is included with the JSP reference implementation described in appendix B.) In practice, this attribute is very rarely used because the default behavior, letting the JSP container select the superclass for the page, typically yields the best performance. The vendors of JSP containers devote considerable resources to tuning their implementations, including optimization of their default page superclasses. Except when you have very specific needs not anticipated by your JSP vendor, it is unlikely that writing and optimizing your own page superclass will be worth the effort.

Import attribute Unlike the extends attribute, use of the import attribute is quite common, because it extends the set of Java classes which may be referenced in a JSP page without having to explicitly specify class package names (in other words, because it saves typing). All Java classes and interfaces are associated with a package name; to

JSP directives

73

completely specify a class, the package name must be prepended to the class name. For example, the discussion of the extends attribute makes mention of the interface javax.servlet.jsp.HttpJspPage . This is actually a reference to an interface named HttpJspPage, which resides in the javax.servlet.jsp package.
NOTE

Java programmers will notice from the discussion that follows that the import attribute of the page directive has an analogous role to Javas import statement, used when writing Java class files. This is, of course, no coincidence. When a JSP page is compiled into a servlet, any import attributes are translated directly into the corresponding import statements.

The advantages of packages are twofold. First, packages make it easy to keep track of classes that are related in functionality and origin, since these are typically used as the criterion for grouping a set of classes into a package. Second, they make it possible to avoid class naming collisions between different developers (or groups of developers). As long as the developers put their classes into separate packages, there will not be any conflicts if some of the classes share the same name. For example, the J2SE platform includes two classes (actually, one class and one interface) named List. One resides in the java.awt package, and represents a user interface component for selecting one or more items from a scrolling list. The second resides in the java.util package, and represents an ordered collection of objects. Users of these classes distinguish between the two via their package names. It can become very tedious, however, to always have to refer to classes using their package names. The import attribute can be used to identify classes and/or packages that will be frequently used on a given page, so that it is no longer necessary to use package names when referring to them. This is referred to as importing a class or package into the JSP page. To import a specific class, simply specify its name (including the package) as the value of the import attribute, as in:
<%@ page import="java.util.List" %>

If this directive is present in a JSP page, the java.util.List class can be referred to on that page by simply using the unqualified class name, List, also called its base name. This will hold true anywhere on the page a class name might appear in a JSP element including both scripting elements and Bean tags except in the <jsp:plugin> tag (appendix C). It is also possible to import an entire package into a JSP page, in cases where multiple classes from the same package are being used. This is accomplished by

74

CHAPTER 5

Programming JSP scripts

specifying the name of the package, followed by a period and an asterisk, as the value of the import attribute:
<%@ page import="java.util.*" %>

This example directive has the effect of importing all of the classes in the java.util package into the current JSP page, such that any class in the java.util package may now be referred to using only its base name. As mentioned previously in this chapter, import is the only attribute of the page directive that may occur multiple times within a single JSP page. This allows JSP developers to import multiple classes and/or packages into the same page, via multiple page directives with import attributes, or multiple import attributes within the same page directive, or a combination. In addition, the import attribute itself supports importing multiple classes and/or packages via a single attribute value, by separating the items to be imported using commas. For example, the following directive imports an interface, a class, and a package using a single import attribute:
<%@ page import="java.util.List, java.util.ArrayList, java.text.*" %>

The space character following the comma is optional, but recommended for improved readability. You may be wondering what would happen if you tried to import two classes that have the same base name, as in the following:
<%@ page import="java.util.List, java.awt.List" %>

The JSP container considers this to be an illegal statement, and will refuse to process a JSP page that includes such an ambiguity. You might instead try to import these two classes using their packages, as follows:
<%@ page import="java.util.*, java.awt.*" %>

In this case, however, the conflict is resolved by allowing neither of the two List classes to be referred to by its base name. Instead, both must use their fully qualified class names, which include their package names. In order to be able to refer to one of the two classes by its base name, you will have to explicitly import that class, as in the following:
<%@ page import="java.util.*, java.awt.List" %>

Using this last directive, the List class from the java.awt package can be referred to via its base name, but the List class from the java.util package must be referred to using its full name, java.util.List.

JSP directives

75

Finally, note that, as a convenience for JSP developers, every page for which Java is selected as the scripting language automatically imports all of the classes from the following four packages: java.lang, javax.servlet, javax.servlet.http, and javax.servlet.jsp.

Session attribute The session attribute is used to indicate whether or not a JSP page participates in session management (as described in chapter 4). The value for this attribute is a simple boolean indicator, either true or false. For example, to specify that a page is not part of a session, the following form is used:
<%@ page session="false" %>

The default value for this attribute is true; by default then, all pages participate in session management. If a JSP does not interact with the session, then a slight performance gain can be obtained by setting this attribute to false. Note, however, that the session implicit object, described in chapter 6, is available only on pages for which the session attribute is set to true.

Buffer attribute The buffer attribute controls the use of buffered output for a JSP page. To turn off buffered output, so that all JSP content is passed immediately to the HTTP response, this attribute should be set to none, as follows:
<%@ page buffer="none" %>

Alternatively, this attribute can be used to set the size of the output buffer in kilobytes, by specifying the attribute value as an integer, followed by the character string kb. For example:
<%@ page buffer="12kb" %>

The default value for this attribute is "8kb". Note that the JSP container is allowed to use an output buffer larger than the requested size, if it so chooses; the specified value can therefore be thought of as the minimum buffer size for the page. This allows the JSP container to optimize performance by creating a pool of output buffers and using them as needed, instead of creating a new output buffer for every JSP page request. Buffering the output of JSP pages is generally a good practice to follow, primarily because it enables transferring control from one page to another (e.g., via the <jsp:forward> action, described in chapter 6). This enables you to retract all of the

76

CHAPTER 5

Programming JSP scripts

output generated so far by a page, including headers and cookies, for replacement with the contents of another page. In particular, output buffering allows you to make full use of the errorPage attribute of the page directive, discussed later, to forward control to a user-friendly error page when exceptions arise in the course of JSP processing. Such custom error pages are greatly preferred over the output of JVM error messages in the middle of what otherwise appears to be normal output. In addition, error pages can be scripted to notify the webmaster or the development team when a run-time error occurs, yielding a dual benefit: the end user sees an unintimidating and perhaps apologetic message that there was a problem in responding to their request, while the implementers receive a full report detailing the context and circumstances of the error. (For further details, see the error-handling example in chapter 15.) If, as recommended, you elect to use buffered output, it is key that you select an appropriate buffer size. This is because, as indicated in chapter 4, if the output from the page is able to fill the buffer, most of the benefits of bufferingincluding the ability to forward to an alternate pagewill be lost. Fortunately, estimating the size of your output is a rather straightforward, if tedious, exercise. If your output is primarily English text, then one character of output will consume 1 byte of data in your output buffer. Other encodings use multiple bytes of data for representing individual characters. Once you know the size of the characters you will be using, the next step is to estimate the number of characters that will be generated by the page. Each character of static text in the original JSP page will of course translate into one characters worth of data in the final output. For dynamically generated content, a conservative approach is to estimate the maximum number of characters corresponding to each JSP element which generates output. After summing all of these character counts, multiply by the number of bytes per character to compute the required buffer size, dividing by 1,024 to convert bytes into kilobytes. You will likely find that the default value of 8 KB is sufficient for most JSP pages, but pages which generate significant amounts of dynamic content may need correspondingly larger output buffers.

AutoFlush attribute This attribute is also used for controlling buffered output. In particular, this attribute controls the behavior of the JSP container when the pages output buffer becomes full. If this attribute is set to true (the default), the output buffer will automatically be flushed, and its current contents sent to the HTTP server for transmission to the requesting web browser. Page processing then resumes, with any and

JSP directives

77

all new content being buffered until the buffer once again becomes full, or the end of the page is reached. This attribute is set as follows:
<%@ page autoFlush="true" %>

As mentioned in chapter 4, note that once the buffer has been flushed and its initial contents sent to the browser, it is no longer possible for the JSP page to set response headers or forward processing to a different JSP page. If autoFlush is set to false, the JSP container will not automatically flush the buffer when it becomes full. Instead, it will raise an exception, which will have the effect of halting processing of the JSP page and displaying an error page in the browser that originally requested the page. The class of the exception raised under these circumstances is implementation-specific. Also, keep in mind that it is illegal to set the autoflush attribute to false when the buffer attribute is set to none. In other words, the JSP container cannot be set to signal an exception when the output buffer becomes full if there is no output buffer in the first place. The best setting for this attribute will vary from page to page. If the amount of output that might be generated by a page is unpredictable, the autoFlush attribute should be set to true. Under such circumstances, overflowing the output buffer is a very real possibility, so you need to ensure that the pages contents will be delivered to the browser, rather than an error message. If you also might need to set response headers on this page, or conditionally forward to another page, the decision to do so should be made near the beginning of the page, in order to guarantee that these actions will take place before the buffer might be flushed and the opportunity for taking these actions is lost. If, however, you need to keep your options open as long as possible with respect to setting response headers or forwarding to another page, then setting autoFlush to false is the appropriate choice. In this case, it is critical that the pages output buffer be large enough for any conceivable output that might be generated by the page. If not, you again risk the possibility that, if it turns out the output buffer must be flushed, the end user will see an error message rather than your page contents.

IsThreadSafe attribute The isThreadSafe attribute is used to indicate whether your JSP page, once it is compiled into a servlet, is capable of responding to multiple simultaneous requests. If not, this attribute should be set to false, as in the following:
<%@ page isThreadSafe="false" %>

When this attribute is set to false, the JSP container will dispatch outstanding requests for the page sequentially, in the order they were received, waiting for the

78

CHAPTER 5

Programming JSP scripts

current request to finish processing before starting the next. When this attribute is set to true (the default), a thread is created to handle each request for the page, such that multiple requests for the page are handled simultaneously. This attribute should be set to its default value of true. If not, performance will suffer dramatically whenever multiple users try to access the JSP page at the same time, since each subsequent user will have to wait until all previously submitted requests have been handled before processing of their request can begin. If the page is heavily trafficked, or its content generation is at all computationally intensive, this delay will likely not be acceptable to users. Whether or not this attribute can be set to true, however, is usually dependent upon its use of resources. For example, if your JSP page creates and stores a database connection that can be used by only one end user at a time, then, unless special measures are taken to control the use of that connection, the page cannot safely be accessed by multiple threads simultaneously. In this case, the isThreadSafe attribute should be set to false, or else your users are likely to encounter run-time errors when accessing the page. If, however, your JSP page accesses a pool of database connections and waits for a free connection before it begins processing, then the isThreadSafe attribute can probably be set to true. Setting isThreadSafe to false is certainly the more conservative approach. However, this yields a significant performance penalty. Fortunately, the thread safety of a JSP page is typically dependent more upon how resources are used, rather than what resources are used. If you are not a Java developer and are concerned about whether or not your page is safe for multithreading, the best approach is to consult an experienced programmer; if the page is not thread-safe as is, it can usually be made so.
TIP

Judicious use of Javas synchronized keyword is the best approach to ensuring thread safety. All access to objects that are shared across multiple JSP pages, or across multiple invocations of the same JSP page, should be synchronized if there is the potential for inconsistency or deadlocks should those objects be simultaneously accessed and/or modified by multiple threads. In this vein, you should carefully examine all static variables, and all objects used by JSP pages whose scope is either session or application (as discussed in chapter 6), for potential thread safety issues.

Finally, you also need to be aware that, even if a JSP page sets the isThreadSafe attribute to false , JSP implementations are still permitted to create multiple instances of the corresponding servlet in order to provide improved performance. In

JSP directives

79

this way, the individual instances handle only one request at a time, but by creating a pool of servlet instances, the JSP container can still handle some limited number of simultaneous requests. For this reason, you still must consider the resource usage even of pages that are not marked thread-safe, to make sure there are no potential conflicts between these multiple instances. Given this harsh reality, you are usually better off biting the bullet and making sure that your page is fully thread-safe. This discussion of the isThreadSafe attribute is presented here in the interest of completeness, but the bottom line is that if youre tempted to set this attributes value to false, you will be doing both yourself and your users a favor if you reconsider.

ErrorPage attribute This attribute is used to specify an alternate page to display if an (uncaught) error occurs while the JSP container is processing the page. This alternate page is indicated by specifying a local URL as the value for this attribute, as in the following:
<%@ page errorPage="/misc/error.jsp" %>

The error page URL must specify a JSP page from within the same web application (see chapter 14) as the original page. As in this example, it may be an absolute URL, which includes a full directory specification. Such URLs are resolved within the context of that web application; typically, this means a top-level directorycorresponding to the name under which the web application was deployed will be appended to the beginning of the URL. Alternatively, a relative URL may be specified, in which case any directory information included in the URL is appended to the directory information associated with the current page, in order to form a new URL. In the context of the errorPage attribute, absolute URLs start with a forward slash, while relative URLs do not. The default value for this attribute is implementation-dependent. Also, note that if the output of the JSP page is not buffered and any output has been generated before the error occurs, it will not be possible to forward to the error page. If the output is buffered and the autoFlush attribute is set to true , once the buffer becomes full and is flushed for the first time, it will likewise become impossible to forward to the error page. As you might expect, if autoFlush is false, then the exception raised when the buffer is filled will cause the JSP container to forward control to the page specified using the errorPage attribute.

IsErrorPage attribute The isErrorPage attribute is used to mark a JSP page that serves as the error page for one or more other JSP pages. This is done by specifying a simple boolean attribute value, as follows:

80

CHAPTER 5

Programming JSP scripts

<%@ page isErrorPage="true" %>

When this attribute is set to true, it indicates that the current page is intended for use as a JSP error page. As a result, this page will be able to access the exception implicit object, described in chapter 6, which will be bound to the Java exception object (i.e., an instance of the java.lang.Throwable class) which caused control to be forwarded to the current page. Since most JSP pages do not serve as error pages, the default value for this attribute is false.

5.3.2 Include directive


The second JSP directive enables page authors to include the contents of one file in another. The file to be included is identified via a local URL, and the directive has the effect of replacing itself with the contents of the indicated file. The syntax of the include directive is as follows:
<%@ include file="localURL" %>

Like all JSP tags, an XML translation of this directive is also available. Its syntax is as follows:
<jsp:directive.include file="localURL" />

There are no restrictions on the number of include directives that may appear in a single JSP page. There are also no restrictions on nesting; it is completely valid for a JSP page to include another JSP page, which itself includes one or more other JSP pages. As mentioned earlier, however, all included pages must use the same scripting language as the original page. As in the URL specification for the errorPage attribute of the page directive, the value of the include directives file attribute can be specified as an absolute path within the current web application (chapter 14), or relative to the current page, depending upon whether or not it starts with a forward slash character. For example, to include a file in a subdirectory of the directory that the current JSP page is in, a directive of the following form would be used:
<%@ include file="includes/navigation.jspf" %>

To include a file using an absolute path within a web application, the following form would be used:
<%@ include file="/shared/epilogue/copyright.html" %>

JSP directives

81

<%@ include... %>

Including and Included Pages


Figure 5.1

Combined Source

Combined Page Servlet

Effect of the include directive on page compilation

The decision whether to use a common top-level directory for shared content, versus directory-specific files, depends upon the overall design of your web site or application hierarchy. A combination of both approaches may also be appropriate. It is recommended that the .jsp file extension be reserved for JSP pages that will be viewed as top-level documents (i.e., pages that are expected to be referenced explicitly in URLs requested by an end user). An alternate extension, such as .jspf or .jsf, is preferred for JSP fragments meant to be included as elements of other JSP pages. As indicated in figure 5.1, the include directive has the effect of substituting the contents of the included file before the page is translated into source code and compiled into a servlet. The contents of the included file may be either static text (e.g., HTML) or additional JSP elements that will be processed as if they were part of the original JSP page. This means that it is possible to make reference in the included page to variables that are local to the original page, and vice versa, since the included page effectively becomes part of that original page. In practice, this approach can lead to software maintenance problems, since it breaks the modularity of the individual files. If used in a disciplined manner, though, it can be helpful to isolate code that appears repeatedly across a set of JSP pages into a single file, and use the include directive to share this common code.
NOTE

For C and C++ developers, the JSP include directive is a direct analog of the #include directive provided by the preprocessor for those two languages.

82

CHAPTER 5

Programming JSP scripts

As described in chapter 4, the JSP container will automatically rebuild and recompile the servlet associated with a JSP page whenever it detects that the file defining the pages contents has been modified. This only applies to the file for the JSP page itself, however, not to any files which have been incorporated via the include directive. The JSP container is not required to keep track of file dependencies resulting from the use of this directive, so modifications to included files will not automatically trigger the generation of a new JSP servlet. The easiest way to force the construction of a new servlet is to manually update the modification date on the file for the including page.
TIP

On the UNIX platform, the easiest way to update a files modification date is via the touch command. Unfortunately, there is no direct equivalent on the Windows platform. Alternate Windows command shells are available which provide this functionality, or you can simply open the file in an editor and save its contents, unchanged.

JSP also provides an alternative means for including the contents of one JSP file

within another, via the <jsp:include> action, described in chapter 6. Unlike the include directive, which treats the contents of the file to be included as if it were part of the original page, the <jsp:include> action obtains the contents of the file to be included at the time the request for the original page is being handled, by forwarding the request to the included page and then inserting the results of processing this secondary request into the results of the original page.

5.3.3 Tag library directive


This directive is used to notify the JSP container that a page relies on one or more custom tag libraries. A tag library is a collection of custom tags that can be used to extend the functionality of JSP on a page-by-page basis. Once this directive has been used to indicate the reliance of a page on a specific tag library, all of the custom tags defined in that library become available for use on that page. The syntax of this directive is as follows:
<%@ taglib uri="tagLibraryURI" prefix="tagPrefix" %>.

Here, the value of the uri attribute indicates the location of the Tag Library Descriptor ( TLD) file for the library, and the prefix attribute specifies the XML namespace identifier that will be prepended to all occurrences of the librarys tags on the page. For example, the following directive loads in a tag library whose TLD is accessible via the local URL /EncomTags:
<%@ taglib uri="/EncomTags" prefix="mcp" %>

Scripting elements

83

Within the page in which this directive appears, the tags defined by this library are accessed using the prefix mcp. A tag from this library named endProgram, then, would be referenced within the page as <mcp:endProgram/>. Note that all custom tags follow XML syntax conventions. In addition, the prefix names jsp, jspx, java, javax, servlet, sun, and sunw are reserved by the JSP specification; you may not provide them as the value for the prefix attribute of the taglib directive within your own JSP pages.
NOTE

Unlike the other directives introduced in this chapter, there is no direct XML version of the taglib directive. Instead, when constructing a JSP page as an XML document, the use of a custom tag library is specified as an attribute of the documents root element. For further details, see chapter 20.

Because the custom tag prefix is specified external to the library itself, and on a pagespecific basis, multiple libraries can be loaded by a single page without the risk of conflicts between tag names. If two libraries both define tags with the same name, a JSP page would still be able to load and use both libraries since it can distinguish those tags via their prefixes. As such, there are no restrictions on how many tag library directives may appear on a page, as long as each is assigned a unique prefix. If, however, the JSP container cannot find the TLD at the indicated location, or the page references a tag that is not actually defined in the library (based on the contents of the TLD), an error will result when the JSP container tries to compile the page. The construction of custom tag libraries and their associated TLDs is described in chapter 18. The deployment of custom tag libraries is presented in chapter 14.
WARNING For security reasons, the JSP specification mandates that the Java classes imple-

menting a librarys custom tags must be stored locally, as part of the deployed web application which uses them (see chapter 13). Some JSP containers, however, allow page authors to specify URLs referencing complete tag library JAR files in the uri attribute of the taglib directive, including JAR files stored on remote servers. Support for this behavior is intended to ease development, but keep in mind that downloading arbitrary Java code from a remote URL and running that code on your web server is a rather risky proposition.

5.4

Scripting elements
Whereas the JSP directives influence how the page is processed by the JSP container, scripting elements enable developers to directly embed code in a JSP page, including code that generates output to appear in the results sent back to the user. JSP

84

CHAPTER 5

Programming JSP scripts

provides three types of scripting elements: declarations, scriptlets, and expressions. Declarations allow the developer to define variables and methods for a page, which may be accessed by other scripting elements. Scriptlets are blocks of code to be executed each time the JSP page is processed for a request. Expressions are individual lines of code. Like scriptlets, they are executed for every request. The results of evaluating an expression, however, are automatically inserted into the page output in place of the original expression tag. All scripting elements in a page are written in the scripting language designated for the page via the language attribute of the page directive. In the absence of an explicit specification of the scripting language, it is assumed by the JSP container that the scripting language is Java. Recall, as well, that if the include directive is used to incorporate the contents of one JSP page into another, both pages must use the same scripting language. Finally, none of the tags for the JSP scripting elements supports attributes.

5.4.1 Declarations
Declarations are used to define variables and methods specific to a JSP page. Declared variables and methods can then be referenced by other scripting elements on the same page. The syntax for declarations is:
<%! declaration(s) %>

Note that multiple declarations may appear within a single tag, but each declaration must be a complete declarative statement in the designated scripting language. Also note that white space after the opening delimiter and before the closing delimiter is optional, but recommended to improve readability. For JSP pages specified as XML documents, the corresponding syntax is:
<jsp:declaration> declaration(s) </jsp:declaration>

The two forms are identical in effect.

Variable declarations Variables defined as declarations become instance variables of the servlet class into which the JSP page is translated and compiled. Consider the following declaration of three variables:
<%! private int x = 0, y = 0; private String units = "ft"; %>

This declaration will have the effect of creating three instance variables in the servlet created for the JSP page, named x, y, and units. These variables can be referenced

Scripting elements

85

by any and all other scripting elements on the page, including those scripting elements that appear earlier in the page than the declaration itself. When declaring JSP instance variables, it is important to keep in mind the potential that multiple threads will be accessing a JSP simultaneously, representing multiple simultaneous page requests. If a scripting element on the page modifies the value of an instance variable, all subsequent references to that instance variable will use the new value, including references in other threads. If you wish to create a variable whose value is local to the processing of a single request, this may be done in a scriptlet. Declared variables are associated with the page itself (through the servlet class), not with individual requests. Since variables specified via JSP declarations are directly translated into variables of the corresponding servlet class, they may also be used to declare class variables. Class, or static, variables, are those whose values are shared among all instances of a class, rather than being specific to an individual instance. When the scripting language is Java, class variables are defined using the static keyword, as in the following example:
<%! static public int counter = 0; %>

The effect of this declaration is to create an integer variable named counter that is shared by all instances of the pages servlet class. If any one instance changes the value of this variable, all instances see the new value. In practice, because the JSP container typically creates only one instance of the servlet class representing a particular JSP page, there is little difference between declaring instance variables and declaring class variables. As explained earlier, the major exception to this rule is when a JSP page sets the isThreadSafe attribute of the page directive to false, indicating that the page is not thread-safe. In this case, the JSP container may create multiple instances of the pages servlet class, in order to handle multiple simultaneous requests, one request per instance. To share a variables value across multiple requests under these circumstances, the variable must be declared as a class variable, rather than an instance variable. When the isThreadSafe attribute is true, however, it makes little practical difference whether a variable is declared as an instance variable or a class variable. Declaring instance variables saves a little bit of typing, since you don t have to include the static keyword. Class variables, though, do a somewhat better job of conveying the typical usage of declared JSP variables, and are appropriate regardless of the setting of the isThreadSafe attribute.

86

CHAPTER 5

Programming JSP scripts

Method declarations Methods defined via declarations become methods of the servlet class into which the JSP page is compiled. For example, the following declaration defines a method for computing factorials:
<%! public long fact (long x) { if (x == 0) return 1; else return x * fact(x-1); } %>

As with variable declarations, declared methods can be accessed by any and all scripting elements on the page, regardless of the order in which the method declaration occurs relative to other scripting elements.
DEFINITION The factorial of a number is the product of all of the integers between

that number and 1. The factorial function is only valid for non-negative integers, and the factorial of zero is defined to be one. The standard mathematical notation for the factorial of a variable x is x! Thus, x! = x * (x 1) * (x 2) * ... * 1. For example, 5! = 5 * 4 * 3 * 2 * 1 = 120. The method definition provided here implements this definition in a recursive manner, by taking advantage of the fact that 0! = 1, and the observation that, for x > 0, it is true that x! = x * (x-1)!

In addition, multiple method definitions can appear within a single declaration tag, as can combinations of both variable and method declarations, as in the following:
<%! static private char[] vowels = { a, e, i, o, u, A, E, I, O, U }; public boolean startsWithVowel (String word) { char first = word.charAt(0); for (int i = 0; i < vowels.length; ++i) { if (first == vowels[i]) return true; } return false; } static private String[] articles = { "a ", "an " }; public String withArticle (String noun) { if (startsWithVowel(noun)) return articles[1] + noun; else return articles[0] + noun; } %>

This declaration introduces two methods and two class variables. The withArticle() method, which relies upon the other variables and methods included in the

Scripting elements

87

declaration, can be used to prepend the appropriate indefinite article to whatever character string is provided as its argument. As with class variables, class methods may be specified using JSP declarations. Class methods, also known as static methods, are methods associated with the class itself, rather than individual instances, and may be called without requiring access to an instance of the class. In fact, class methods are typically called simply by prepending the name of the class to the name of the method. Class methods may reference only class variables, not instance variables. In practice, because it is generally not possible to obtain (or predict) the name of the servlet class corresponding to a particular JSP page, class methods have little utility in the context of JSP.

Handling life-cycle events One particularly important use for method declarations is the handling of events related to the initialization and destruction of JSP pages. The initialization event occurs the first time the JSP container receives a request for a JSP page. The destruction event occurs when the JSP container unloads the servlet class, either because the JSP container is being shut down, or because the page has not been requested recently and the JSP container needs to reclaim the resources (e.g., system memory) associated with its servlet class. These events are handled by declaring special life-cycle methods that will automatically be called by the JSP container when the corresponding event occurs. The initialization event is handled by jspInit(), and the destruction event is handled by jspDestroy(). Neither method returns a value nor takes any arguments, so the general format for declaring them is:
<%! public void jspInit () { // Initialization code goes here... } public void jspDestroy () { // Destruction code goes here... } %>

Both methods are optional. If a JSP life-cycle method is not declared for a JSP page, the corresponding event is simply ignored. If jspInit() is defined, the JSP container is guaranteed to call it after the servlet class has been instantiated, but before the first request is processed. For example, consider a JSP page that relies upon a pool of database connections in order to collect the data used to generate its contents. Before the page can handle any requests, it needs to ensure that the connection pool has been created, and is available for

88

CHAPTER 5

Programming JSP scripts

use. The initialization event is the standard JSP mechanism for enforcing such requirements, as in:
<%! static private DbConnectionPool pool = null; public void jspInit () { if (pool == null) { String username = "sark", password = "mcpr00lz"; pool = DbConnectionPool.getPool(this, username, password); } } %>

Here, a class variable is declared for storing a reference to the connection pool, an instance of some hypothetical DbConnectionPool class. The jspInit() method calls a static method of this class named getPool(), which takes the page instance as well as a username and password for the database as its arguments, and returns an appropriate connection pool, presumably either reusing an existing connection pool or, if necessary, creating one. In a similar manner, if jspDestroy() is defined, it will be called after all pending requests have been processed, but just before the JSP container removes the corresponding servlet class from service. To continue the example introduced above, imagine the following method declaration for the page destruction event:
<%! public void jspDestroy () { pool.maybeReclaim(this); } %>

Here, the connection pool is given a chance to reclaim its resources by calling its maybeReclaim() method with the page instance as its sole argument. The implication here is that if this page is the only consumer of connection pools that is still using this particular pool, the pool can reclaim its resources because this page no longer needs them.

5.4.2 Expressions
Declarations are used to add variables and methods to a JSP page, but are not able to directly contribute to the page s output, which is, after all, the objective of dynamic content generation. The JSP expression element, however, is explicitly intended for output generation. The syntax for this scripting element is as follows:
<%= expression %>

An XML version is also provided:


<jsp:expression> expression </jsp:expression>

Scripting elements

89

In both cases, the expression should be a valid and complete scripting language expression, in whatever scripting language has been specified for the page. The effect of this element is to evaluate the specified expression and substitute the resulting value into the output of the page, in place of the element itself. JSP expressions can be used to print out individual variables, or the result of some calculation. For example, the following expression, which uses Java as the scripting language, will insert the value of into the pages output, courtesy of a static variable provided by the java.lang.Math class:
<%= Math.PI %>

Assuming a variable named radius has been introduced elsewhere on the page, the following expression can be used to print the area of the corresponding circle:
<%= Math.PI * Math.pow(radius, 2) %>

Again, any valid scripting language expression is allowed, so calls to methods are likewise permitted. For example, a page including the declaration of the fact() method could then insert factorial values into its output using expressions of the following form:
<%= fact(12) %>

This particular expression would have the effect of substituting the value 479001600 into the contents of the page. These three expressions all return numeric values, but there are no restrictions on the types of values that may be returned by JSP expressions. Expressions can return Java primitive values, such as numbers, characters, and booleans, or fullfledged Java objects, such as strings and JavaBeans. All expression results are converted to character strings before they are added to the pages output. As indicated in table 5.2, various static toString() methods are used to convert primitive values into strings, while objects are expected to provide their own toString() methods (or rely on the default implementation provided by the java.lang.Object class).
Table 5.2 Methods used to convert expression values into strings

Value Type
boolean byte char double int

Conversion to String
java.lang.Boolean.toString(boolean) java.lang.Byte.toString(byte) new java.lang.Character(char).toString() java.lang.Double.toString(double) java.lang.Integer.toString(int)

90

CHAPTER 5

Programming JSP scripts

Table 5.2

Methods used to convert expression values into strings (continued)

Value Type
float long object

Conversion to String
java.lang.Float.toString(float) java.lang.Long.toString(long) toString() method of objects class

Notice that no semicolon was provided at the end of the Java code used in the example JSP expressions. This is because Javas semicolon is a statement delimiter. A semicolon has the effect of transforming a Java language expression into a program statement. In Java, statements are evaluated purely for their side effects; they do not return values. Thus, leaving out the semicolon in JSP expressions is the right thing to do, because the JSP container is interested in the value of the enclosed code, not its side effects. Given that this scripting element produces output only from expressions, not statements, you may be wondering if there is a convenient way to do conditional output in a JSP page. Javas standard if/then construct, after all, is a statement, not an expression: its clauses are evaluated purely for side effects, not value. Fortunately, Java supports the oft-forgotten ternary conditional operator, which does return a value based on the result of a conditional test. The syntax of Javas ternary operator is as follows:
test_expr ? true_expr : false_expr

Each operand of the ternary operator is itself an expression. The test_expr expression should evaluate to a boolean value. If the value of test_expr expression is true, then the true_expr expression will be evaluated and its result returned as the result of the ternary operator. Alternatively, if the value of test_expr expression is false, then the false_expr expression is evaluated and its result will be returned. The ternary operator can thus be used in a JSP expression as in the following:
<%= (hours < 12) ? "AM" : "PM" %>

In this particular example, the value of the hours variable is checked to determine whether it is less than twelve. If so, the ternary operator returns the string "AM", which the JSP expression then inserts into the page. If not, the operator returns "PM" and, again, the JSP expression adds this result to the page output.
TIP

The ternary operator is particularly convenient for use in JSP expressions not just for its functionality, but also for its brevity.

Scripting elements

91

5.4.3 Scriptlets
Declarations and expressions are intentionally limited in the types of scripting code they support. For general purpose scripting, the appropriate JSP construct is the scriptlet. Scriptlets can contain arbitrary scripting language statements which, like declarations, are evaluated for side effects only. Scriptlets do not, however, automatically add content to a JSP pages output. The general syntax for scriptlets is:
<% scriptlet %>

Scriptlets can also be specified using XML notation, as follows:


<jsp:scriptlet> scriptlet </jsp:scriptlet>

For either tag style, the scriptlet should be one or more valid and complete statements in the JSP pages scripting language. Alternatively, a scriptlet can leave open one or more statement blocks, which must be closed by subsequent scriptlets in the same page. In the case where the JSP scripting language is Java, statement blocks are opened using the left brace character (i.e., {) and closed using the right brace character (i.e., }). Here is an example of a scriptlet which contains only complete statements:
<% GameGrid grid = GameGrid.getGameGrid(); Recognizer r1 = new Recognizer(new Coordinates(grid, 0, 0)); Recognizer r2 = new Recognizer(new Coordinates(grid, 100, 100)); r1.findProgram("Flynn"); r2.findProgram("Flynn"); %>

This scriptlet fetches one object via a class method, which it then uses to instantiate two new objects. Methods are then called on these objects to initiate some computation. Note that a pages scriptlets will be run for each request received by the page. For the previous example, this means that two instances of the Recognizer class are created every time the JSP page containing this scriptlet is requested. Furthermore, any variables introduced in a scriptlet are available for use in subsequent scriptlets and expressions on the same page (subject to variable scoping rules). The foregoing scriptlet, for example, could be followed by an expression such as the following:
<%= r1.statusReport() %>

This expression would then insert the results of the statusReport() method call for instance r1 into the pages output. Later scriptlets or expressions could make additional references (such as method calls, or inclusion in argument lists) to this instance and the r2 instance, as well the grid object.

92

CHAPTER 5

Programming JSP scripts

If you wish to control the scoping of a variable introduced by a scriptlet, you can take advantage of JSPs support for leaving code blocks open across multiple scriptlets. Consider, for example, the following JSP page which reproduces the above scriptlet, with one small but important modification:
<html> <body> <h1>Intruder Alert</h1> <p>Unauthorized entry, dispatching recognizers...</p> <% GameGrid grid = GameGrid.getGameGrid(); { Recognizer r1 = new Recognizer(new Coordinates(grid, 0, 0)); Recognizer r2 = new Recognizer(new Coordinates(grid, 100, 100)); r1.findProgram("Flynn"); r2.findProgram("Flynn"); %> <h2>Status</h2> <ul> <li>First Recognizer: <%= r1.statusReport() %> <li>Second Recognizer: <%= r2.statusReport() %> </ul> <% } %> Alert Level: <%= grid.alertLevel() %> </body> </html>

In this case, the first scriptlet introduces a new program block before creating the two Recognizer instances. The second scriptlet, toward the end of the page, closes this block. Within that block, the r1 and r2 instances are said to be in scope, and may be referenced freely. After that block is closed, these objects are out of scope, and any references to them will cause a compile-time error when the page is compiled into a servlet by the JSP container. Note that because the grid variable is introduced before the block is opened, it is in the pages top-level scope, and can continue to be referenced after the second scriptlet closes the block opened by the first, as in the call to its alertLevel() method near the end of the page. The reason this works has to do with the translation of the contents of a JSP page into source code for a servlet. Static content, such as HTML code, is translated into Java statements which print that text as output from the servlet. Similarly, expressions are translated into Java statements which evaluate the expression, convert the result to a string, and print that string value as output from the servlet. Scriptlets, however, undergo no translation at all, and are simply inserted into the source code of the servlet as is. If a scriptlet opens a new block without also closing it, then the Java statements corresponding to any subsequent static content or JSP elements simply become part of this new block. The block must ultimately be closed by another scriptlet, or else compilation will fail due to a Java syntax error.

Flow of control

93

NOTE

Java statements corresponding to a JSP pages static content, expressions, and scriptlets are used to create the _jspService() method of the corresponding servlet. This method is responsible for generating the output of the JSP page. Directives and declarations are also translated into servlet code, but do not contribute to the _jspService() method and so are not affected by scoping due to scriptlets. On the other hand, the JSP Bean tags, discussed in chapter 7, are translated into Java statements for the _jspService() method and therefore are subject to scoping restrictions introduced via scriptlets.

5.5

Flow of control
This ability of scriptlets to introduce statement blocks without closing them can be put to good use in JSP pages to affect the flow of control through the various elements, static or dynamic, that govern page output. In particular, such scriptlets can be used to implement conditional or iterative content, or to add error handling to a sequence of operations.

5.5.1 Conditionalization
Javas if statement, with optional else if and else clauses, is used to control the execution of code based on logical true/false tests. Scriptlets can use the if statement (or the appropriate analog if the scripting language is not Java) to implement conditional content within a JSP page. The following page fragment, for example, uses the fact() method introduced earlier in this chapter to compute the factorial of a page variable named x, as long as it is within the appropriate range:
<% if (x < 0) { %> <p>Sorry, cant compute the factorial of a negative number.</p> <% } else if (x > 20) { %> <p>Sorry, arguments greater than 20 cause an overflow error.</p> <% } else { %> <p align=center><%= x %>! = <%= fact(x) %></p> <% } %>

Three different blocks of statements are created by these scriptlets, only one of which will actually be executed. If the value of x is negative, then the first block will be executed, causing the indicated static HTML code to be displayed. If x is greater than 20, the second block is executed, causing its static HTML to be displayed. Otherwise, the output from the page will contain the static and dynamic content specified by the third block, including the result of the desired call to the fact() method.

94

CHAPTER 5

Programming JSP scripts

5.5.2 Iteration
Java has three different iteration constructs: the for loop, the while loop, and the do/while statement. They may all be used via scriptlets to add iterative content to a JSP page, and are particularly useful in the display of tabular data. Here, for example, is a page fragment which uses the fact() method defined earlier in this chapter to construct a table of factorial values:
<table> <tr><th><i>x</i></th><th><I>x</I>! </th></tr> <% for (long x = 01; x <= 201; ++x) { %> <tr><td><%= x %></td><td><%= fact(x) %></td></tr> <% } %> </table>

Static HTML is used to create the table and its headers, while a for loop is used to generate the contents of the table. Twenty-one rows of data are created in this manner (figure 5.2). The other iteration constructs may be used in a similar manner. In addition to generating row data for HTML tables, another common use for iteration scriptlets is looping through a set of results from a database query.

5.5.3 Exception handling


As described in chapter 4, the default behavior when an exception is thrown while processing a JSP page is to display an implementation-specific error message in the browser window. In this chapter, we have also seen how the errorPage attribute of the page directive can be used to specify an alternative page for handling any uncaught errors thrown by a JSP page. A third option allows even finer control over errors by incorporating the standard Java exception-handling mechanisms into a JSP page using scriptlets. If a block of code on a JSP page has the potential of signaling an error, Javas exception handling construct, the try block, may be used in a set of scriptlets to catch the error locally and respond to it gracefully within the current page. By way of example, consider the following alternative declaration for the factorial method presented earlier:
<%! public long fact (long x) throws IllegalArgumentException { if ((x < 0) || (x > 20)) throw new IllegalArgumentException("Out of range."); else if (x == 0) return 1; else return x * fact(x-1); } %>

Flow of control

95

Figure 5.2

Tabular results generated by the iteration example

This version of the method verifies that the methods argument is within the valid range for this calculation, signaling an IllegalArgumentException if it is not. Using this version of the method, we could consider an alternative implementation of the example presented in the foregoing section on conditionals, as follows:
<% try { %> <p align=center> <%= x %>! = <%= fact(x) %></p> <% } catch (IllegalArgumentException e) { %> <p>Sorry, factorial argument is out of range.</p> <% } %>

96

CHAPTER 5

Programming JSP scripts

Figure 5.3

Failure results generated by the first exception handler example

Like the earlier example, the intent here is to print the result of a factorial calculation, or display an error message if the calculation cannot be made. In this case, a try block is established around the expression which calls fact(). If this call raises an IllegalArgumentException the catch block will handle it by printing an error message. If no exception is raised, the content enclosed by the catch block will be ignored, and only the successful results are displayed. In figure 5.3 an attempt to calculate the factorial of 42 has been made, but this is out of the range of permitted values for the fact() method. (This is because Java integer values of type long are limited to 64 bits. Twenty is the largest integer whose factorial can be expressed using 64 bits.) As a result, the IllegalArgumentException is thrown, and then caught. Notice that all of the output generated up until the call to the fact() method appears on the page. This is because the corresponding servlet code for this output does not raise any exceptions, and therefore is executed when the page is processed. As soon as the call to fact() occurs, however, the exception is raised and control is transferred to the catch block, which then prints the error message. In order to suppress the equation output altogether, the code on the JSP page must be rearranged to call the fact() method before any of that output is generated. One possible approach is to rewrite the first scriptlet:
<% try { long result = fact(x); %> <p align=center> <%= x %>! = <%= result %></p> <% } catch (IllegalArgumentException e) { %> <p>Sorry, factorial argument is out of range.</p> <% } %>

Comments

97

In this case, the factorial value is computed in the scriptlet itself, at the beginning of the try block, and stored in a new local variable named result. This variable is then used in the expression which displays the factorial value, rather than directly calling the method, as before. And because the method call now precedes any output, if an exception is thrown, control will be transferred to the catch block before the output in the try block begins.

5.5.4 A word of caution


As you can see from these examples, scriptlets that introduce enclosing blocks are very powerful. Short of using custom tag libraries, they are the only means available in JSP to implement conditional or iterative content, or to add custom exception handlers to a page. At the same time, excessive use of these scriptlets can lead to maintainability problems. The primary reason for this is readability. The fact that Java delimiters (i.e., { and }) appear adjacent to the HTML-like scriptlet delimiters (i.e., <% and %>) introduces a syntax clash, which can make these tags difficult to follow. Adhering to an indentation convention, as the examples here do, can help address this issue, particularly when there are several lines of content interleaved between the scriptlet that opens a block and the scriptlet that closes it. As discussed in chapter 1, maintenance of JSP pages is often shared by individuals skilled in Java programming and others who are skilled in page design and HTML. While it is certainly true that HTML has tags that must appear in pairs in order to have meaning, the notion that some scriptlets are stand-alone while others are mutually dependent is somewhat foreign to those familiar with HTML syntax but not Java syntax. As the preceding examples demonstrate, there are cases where three or more scriptlets are required to implement conditional logic or exception handling, a scenario that has no parallels in HTML. As a result, modifying and debugging pages that make heavy use of scriptlets such as these can be complicated. If the web designers on a team are uncomfortable with the syntax issues, it is not unlikely that they will involve the programming staff when making even minor changes to a page. Likewise, if there is a problem with the display of a page, a joint effort may be required to resolve it.

5.6

Comments
If the number of ways comments can be expressed in a language is an indication of its power, then JSP must be the most powerful dynamic content system around: there are three different ways to insert comments into a JSP page. These three styles

98

CHAPTER 5

Programming JSP scripts

of comments themselves divide into two major types, comments that are transmitted back to the browser as part of the JSP response, and those that are only visible in the original JSP source file.

5.6.1 Content comments


Only one of the three comments styles falls into the first group. These are referred to as content comments, because they use the comment syntax associated with the type of content being generated by the JSP page. To write a comment that will be included in the output of a JSP page that is generating web content, the following syntax is used:
<!-- comment -->

Those familiar with HTML and XML will recognize that this is the standard comment syntax for those two markup languages. Thus, a JSP page that is generating either HTML or XML simply uses the native comment syntax for whichever form of content it is constructing. Such comments will then be sent back to the browser as part of the response. Since they are comments, they do not produce any visible output, but they may be viewed by the end user via the browsers View Source menu item. Since these comments are part of the output from the page, you can, if you wish, include dynamic content in them. HTML and XML comments can, for example, include JSP expressions, and the output generated by these expressions will appear as part of the comment in the pages response. For example:
<!-- Java longs are 64 bits, so 20! = <%= fact(20) %> is the upper limit. -->

In this case, the computed value of the factorial expression will appear in the comment that is actually sent to the browser.

5.6.2 JSP comments


JSP comments are independent of the type of content being produced by the

page. They are also independent of the scripting language used by the page. These comments can only be viewed by examining the original JSP file, and take the following form:
<%-- comment --%>

The body of this comment is ignored by the JSP container. When the page is compiled into a servlet, anything appearing between these two delimiters is skipped while translating the page into servlet source code.

Comments

99

For this reason, JSP comments such as this are very useful for commenting out portions of a JSP page, as when debugging. In the following page fragment, for example, only the first and last expressions, displaying the factorials of 5 and 9, will appear in the page output:
5! = <%-6! = 7! = 8! = --%> 9! = <%= fact(5) %><br> <%= fact(6) %><br> <%= fact(7) %><br> <%= fact(8) %><br> <%= fact(9) %><br>

All of the other expressions have been commented out, and will not appear in the pages output. Keep in mind that these comments do not nest. Only the content between the opening comment delimiter, <%--, and the first occurrence of the closing delimiter, --%>, is ignored.

5.6.3 Scripting language comments


Finally, comments may also be introduced into a JSP page within scriptlets, using the native comment syntax of the scripting language. Java, for example, uses /* and */ as comment delimiters. With Java as the JSP scripting language, then, scripting language comments take the following form:
<% /* comment */%>

Like JSP comments, scripting language comments will not appear in the pages output. Unlike JSP comments, though, which are ignored by the JSP container, scripting language comments will appear in the source code generated for the servlet. Scripting language comments can appear by themselves in scriptlets or may accompany actual scripting code, as in the following example:
<% long valid = fact(20); long overflow = fact(21); /* Exceeds 64-bit long! */ %>

In this case, the comment will again appear in the source code of the corresponding servlet. Scripting language comments can also appear in JSP expressions, as long as they are also accompanied by, or part of, an expression. For example, all of the following JSP expressions are valid:
<%= /* Comment before expression */ fact(5) %> <%= fact(7) /* Comment after expression */ %> <%= fact(9 /* Comment inside expression */) %>

100

CHAPTER 5

Programming JSP scripts

A JSP expression that contains only a comment, but not a scripting language expression, is not valid, and will result in a compilation error. Java also supports a second comment syntax, in which the characters // are the opening delimiter, and the closing delimiter is the end of the line. This comment syntax can also be used in JSP pages, as long as the scriptlet or expression in which it is used is careful to include the end-of-line delimiter, as in the following examples:
<% long valid = fact(20); long overflow = fact(21); %> // This one fits in a 64-bit long. // This one doesnt.

5! = <%= fact(5) // Getting tired of factorial examples yet? %>

If the scriptlet or expression does not include the end-of-line delimiter, there is a danger that the content immediately following it may be commented out when the JSP page is translated into a servlet. Consider, for example, the following JSP page fragment:
Loras brother is over <%= fact(3) // Strange ruler... %> feet tall!

Depending upon the implementation of the JSP container, it is possible that the code generated to print out the character string "feet tall!" may appear in the servlet source code on the same line as the code corresponding to the JSP expression. If so, this code will be commented out in the servlet source code and never appear in the output from the page. In fact, it is also possible that part of the code generated for the expression itself will be commented out, in which case a syntax error will result the first time the page is compiled. For this reason, the fully delimited Java comment syntax (i.e., /* ... */) is the preferred style for JSP usage, particularly in JSP expressions.

Actions and implicit objects

This chapter covers


I I I I

Types of JSP implicit objects Accessing and applying implicit objects Attributes and scopes Action tags for transfer of control

101

102

CHAPTER 6

Actions and implicit objects

Three types of JSP tags were introduced in chapter 5: directives, scripting elements, and comments. The remaining type, actions, will be introduced here. Actions encapsulate common behavior into simple tags for use from any JSP page. Actions are the basis of the custom tag facility described in chapters 1820, but a number of standard actions are also provided by the base JSP specification. These standard actions, presented later in this chapter, are supported by all JSP containers. Before we look at the standard actions, however, we will first consider the set of Java objects that the JSP container makes available to developers from each page. Through their class APIs, these objects enable developers to tap into the inner workings of the JSP container and leverage its functionality. These objects can be accessed as built-in variables via scripting elements. They may also be accessed programmatically by JavaBeans (chapter 7), servlets (chapter 10) and JSP custom tags (chapters 1820).

6.1

Implicit objects
As the examples presented in chapter 5 suggest, the JSP scripting elements provide a great deal of power for creating, modifying, and interacting with Java objects in order to generate dynamic content. Application-specific classes can be instantiated and values from method calls can be inserted into JSP output. Network resources and repositories, such as databases, can be accessed to store and retrieve data for use by JSP pages. In addition to objects such as these, which are completely under the control of the developer, the JSP container also exposes a number of its internal objects to the page author. These are referred to as implicit objects, because their availability in a JSP page is automatic. The developer can assume that these objects are present and accessible via JSP scripting elements. More specifically, these objects will be automatically assigned to specific variable names in the pages scripting language. Furthermore, as summarized in table 6.1, each implicit object must adhere to a corresponding API, in the form of a specific Java class or interface definition. Thus, it will either be an instance of that class or interface, or of an implementationspecific subclass.
Table 6.1 JSP implicit objects and their APIs for HTTP applications

Object
page config request

Class or Interface
javax.servlet.jsp.HttpJspPage javax.servlet.ServletConfig javax.servlet.http.HttpServletRequest

Description
Pages servlet instance. Servlet configuration data. Request data, including parameters.

Implicit objects

103

Table 6.1

JSP implicit objects and their APIs for HTTP applications (continued)

Object
response out session application pageContext exception

Class or Interface
javax.servlet.http.HttpServletResponse javax.servlet.jsp.JspWriter javax.servlet.http.HttpSession javax.servlet.ServletContext javax.servlet.jsp.PageContext java.lang.Throwable

Description
Response data. Output stream for page content. User-specific session data. Data shared by all application pages. Context data for page execution. Uncaught error or exception.

The nine implicit objects provided by JSP fall naturally into four major categories: objects related to a JSP pages servlet, objects concerned with page input and output, objects providing information about the context within which a JSP page is being processed, and objects resulting from errors. Beyond this functional categorization, four of the JSP implicit objects request, session, application, and pageContexthave something else in common: the ability to store and retrieve arbitrary attribute values. By setting and getting attribute values, these objects are able to transfer information between and among JSP pages and servlets as a simple data-sharing mechanism. The standard methods for attribute management provided by the classes and interfaces of these four objects are summarized in table 6.2. Note that attribute keys take the form of Java String objects, while their values are referenced as instances of java.lang.Object.
WARNING

Note that attribute names beginning with the prefix java are reserved by the JSP specification, and should therefore not be used within your application. An example of this is the javax.servlet.jsp.jspException attribute associated with requests, as presented in chapter 10.

Table 6.2

Common methods for storing and retrieving attribute values

Method
setAttribute(key, value) getAttributeNames() getAttribute(key) removeAttribute(key)

Description
Associates an attribute value with a key (i.e., a name). Retrieves the names of all attributes associated with the session. Retrieves the attribute value associated with the key. Removes the attribute value associated with the key.

104

CHAPTER 6

Actions and implicit objects

6.1.1 Servlet-related objects


The two JSP implicit objects in this category are based on the JSP pages implementation as a servlet. The page implicit object represents the servlet itself, while the config object stores the servlets initialization parameters, if any.

Page object The page object represents the JSP page itself or, more specifically, an instance of the servlet class into which the page has been translated. As such, it may be used to call any of the methods defined by that servlet class. As indicated in the previous chapter, the extends attribute of the page directive may be used to specify a servlet superclass explicitly, otherwise an implementation-specific class will be used by the JSP container when constructing the servlet. In either case, the servlet class is always required to implement the javax.servlet.jsp.JspPage interface. In the specific case of web-based JSP applications built on HTTP, the servlet class must implement the javax.servlet.jsp.HttpJspPage interface. The methods of this class are presented in appendix F. In practice, the page object is rarely used when the JSP scripting language is Java, because the scripting elements will ultimately be incorporated as method code of the constructed servlet class, and will automatically have access to the classs other methods. (More specifically, when the scripting language is Java, the page object is the same as the this variable.) For other scripting languages, however, the scripting variable for this implicit object grants access to all of the methods provided by the javax.servlet.jsp.JspPage interface, as well as any methods that have been defined for the page via method declarations. Here is an example page fragment that utilizes this implicit object:
<%@ page info="Page implicit object demonstration." %> Page info: <%= ((javax.servlet.jsp.HttpJspPage)page).getServletInfo() %>

This expression will insert the value of the pages documentation string into the output from the page. In this example, note that because the servlet class varies from one page to another, the standard type for the page implicit object is the default Java type for nonprimitive values, java.lang.Object. In order to access methods defined by the javax.servlet.jsp.HttpJspPage interface, the page object must first be cast to that interface.

Config object The config object stores servlet configuration datain the form of initialization parametersfor the servlet into which a JSP page is compiled. Because JSP pages are

Implicit objects

105

seldom written to interact with initialization parameters, this implicit object is rarely used in practice. This object is an instance of the javax.servlet.ServletConfig interface. The methods provided by that interface for retrieving servlet initialization parameters are listed in table 6.3.
Table 6.3 Methods of javax.servlet.ServletConfig interface for accessing initialization parameters

Method
getInitParameterNames() getInitParameter(name)

Description
Retrieves the names of all initialization parameters. Retrieves the value of the named initialization parameter.

Due to its role in servlet initialization, the config object tends to be most relevant in the initialization of a pages variables. Consider the following declaration and scriptlet, which provide similar functionality to the sample jspInit() method presented in the previous chapter:
<%! static private DbConnectionPool pool = null; %> <% if (pool == null) { String username = config.getInitParameter("username"); String password = config.getInitParameter("password"); pool = DbConnectionPool.getPool(this, username, password); } %>

In this case, rather than storing the username and password values directly in the JSP page, they have been provided as initialization parameters and are accessed via the config object. Values for initialization parameters are specified via the deployment descriptor file of a web application. Deployment descriptor files are described in chapter 14.

6.1.2 Input/Output
These implicit objects are focused on the input and output of a JSP page. More specifically, the request object represents the data coming into the page, while the response object represents its result. The out implicit object represents the actual output stream associated with the response, to which the pages content is written.

Request object The request object represents the request that triggered the processing of the current page. For HTTP requests, this object provides access to all of the information associated with a request, including its source, the requested URL, and any headers, cookies, or parameters associated with the request. The request object is required to implement the javax.servlet.ServletRequest interface. When the protocol is

106

CHAPTER 6

Actions and implicit objects

HTTP, as is typically the case, it must implement a subclass of this interface, javax.servlet.http.HttpServletRequest. The methods of this interface fall into four general categories. First, the request object is one of the four JSP implicit objects that support attributes, by means of the methods presented in table 6.2. The HttpServletRequest interface also includes methods for retrieving request parameters and HTTP headers, which are summa-

rized in tables 6.4 and 6.5, respectively. The other frequently used methods of this interface are listed in table 6.6, and provide miscellaneous functionality such as access to the request URL and the session. Among the most common uses for the request object are looking up parameter values and cookies. Here is a page fragment illustrating the use of the request object to access a parameter value:
<% String xStr = request.getParameter("num"); try { long x = Long.parseLong(xStr); %> Factorial result: <%= x %>! = <%= fact(x) %> <% } catch (NumberFormatException e) { %> Sorry, the <b>num</b> parameter does not specify an integer value. <% } %>

In this example, the value of the num parameter is fetched from the request. Note that all parameter values are stored as character strings, so conversion is required before it may be used as a number. If the conversion succeeds, this value is used to demonstrate the factorial function. If not, an error message is displayed.
WARNING

When naming your request parameters, keep in mind that parameter names beginning with the prefix jsp are reserved by the JSP specification. You must therefore avoid the temptation of using them in your own applications, since the container is likely to intercept them and may block access to them from your JSP pages. An example of this is the jsp_precompile request parameter, presented in chapter 14.

When utilizing the <jsp:forward> and <jsp:include> actions described at the end of this chapter, the request object is also often used for storing and retrieving attributes in order to transfer data between pages.

Implicit objects

107

Table 6.4

Methods of the javax.servlet.http.HttpServletRequest interface for accessing request parameters

Method
getParameterNames() getParameter(name) getParameterValues(name)

Description
Returns the names of all request parameters Returns the first (or primary) value of a single request parameter Retrieves all of the values for a single request parameter.

Table 6.5

Methods of the javax.servlet.http.HttpServletRequest interface for retrieving request headers

Method
getHeaderNames() getHeader(name) getHeaders(name) getIntHeader(name) getDateHeader(name) getCookies()

Description
Retrieves the names of all headers associated with the request. Returns the value of a single request header, as a string. Returns all of the values for a single request header. Returns the value of a single request header, as an integer. Returns the value of a single request header, as a date. Retrieves all of the cookies associated with the request.

Table 6.6

Miscellaneous methods of the javax.servlet.http.HttpServletRequest interface

Method
getMethod() getRequestURI() getRequestURL() getQueryString() getRequestDispatcher(path) getRemoteHost() getRemoteAddr() getRemoteUser() getSession(flag)

Description
Returns the HTTP (e.g., GET, POST) method for the request. Returns the path information (directories and file name) for the requested URL. Returns the requested URL, up to, but not including any query string. Returns the query string that follows the request URL, if any. Creates a request dispatcher for the indicated local URL. Returns the fully qualified name of the host that sent the request. Returns the network address of the host that sent the request. Returns the name of user that sent the request, if known. Retrieves the session data for the request (i.e., the session implicit object), optionally creating it if it doesnt exist.

Response object
The response object represents the response that will be sent back to the user as a result of processing the JSP page. This object implements the javax.servlet.ServletResponse interface. If it represents an HTTP response, it will furthermore

108

CHAPTER 6

Actions and implicit objects

implement a subclass of this interface, the javax.servlet.http.HttpServletResponse interface.

The key methods of this latter interface are summarized in tables 6.76.10. Table 6.7 lists a pair of methods for specifying the content type and encoding of a response. Table 6.8 presents methods for setting response headers, while those in table 6.9 are for setting response codes. The two methods in table 6.10 provide support for URL rewriting, which is one of the techniques supported by JSP for session managment. For a full listing of all the methods associated with the javax.servlet.http.HttpServletResponse interface, consult appendix F.
Table 6.7 Methods of the javax.servlet.http.HttpServletResponse interface for specifying content

Method
setContentType() getCharacterEncoding()

Description
Sets the MIME type and, optionally, the character encoding of the response s contents. Returns the character encoding style set for the response s contents.

Table 6.8

Methods of the javax.servlet.http.HttpServletResponse interface for setting response headers

Method
addCookie(cookie) containsHeader(name) setHeader(name, value) setIntHeader(name, value) setDateHeader(name, date) addHeader(name, value) addIntHeader(name, value) addDateHeader(name, date)

Description
Adds the specified cookie to the response. Checks whether the response includes the named header. Assigns the specified string value to the named header. Assigns the specified integer value to the named header. Assigns the specified date value to the named header. Adds the specified string value as a value for the named header. Adds the specified integer value as a value for the named header. Adds the specified date value as a value for the named header.

Table 6.9

Response code methods of the javax.servlet.http.HttpServletResponse interface

Method
setStatus(code) sendError(status, msg) sendRedirect(url)

Description
Sets the status code for the response (for nonerror circumstances). Sets the status code and error message for the response. Sends a response to the browser indicating it should request an alternate (absolute) URL.

Implicit objects

109

Table 6.10

Methods of the javax.servlet.http.HttpServletResponse interface for performing URL rewriting

Method
encodeRedirectURL(url) encodeURL(name)

Description
Encodes a URL for use with the sendRedirect() method to include session information. Encodes a URL used in a link to include session information.

Here, for example, is a scriptlet that uses the response object to set various headers for preventing the page from being cached by a browser:
<% response.setDateHeader("Expires", 0); response.setHeader("Pragma", "no-cache"); if (request.getProtocol().equals("HTTP/1.1")) { response.setHeader("Cache-Control", "no-cache"); } %>

The scriptlet first sets the Expires header to a date in the past. This indicates to the recipient that the pages contents have already expired, as a hint that its contents should not be cached.
NOTE

For the java.util.Date class, Java follows the tradition of the UNIX operating system in setting time zero to midnight, December 31, 1969 (GMT). That moment in time is commonly referred to as the UNIX epoch.

The no-cache value for the Pragma header is provided by version 1.0 of the HTTP protocol to further indicate that browsers and proxy servers should not cache a page. Version 1.1 of HTTP replaces this header with a more specific Cache-Control header, but recommends including the Pragma header as well for backward compatibility. Thus, if the request indicates that the browser (or its proxy server) supports HTTP 1.1, both headers are sent.

Out object This implicit object represents the output stream for the page, the contents of which will be sent to the browser as the body of its response. The out object is an instance of the javax.servlet.jsp.JspWriter class. This is an abstract class that extends the standard java.io.Writer class, supplementing it with several of the methods provided by the java.io.PrintWriter class. In particular, it inherits all of the standard write() methods provided by java.io.Writer, and also implements all of the print() and println() methods defined by java.io.PrintWriter.

110

CHAPTER 6

Actions and implicit objects

For example, the out object can be used within a scriptlet to add content to the generated page, as in the following page fragment:
<P>Counting eggs <% int count = 0; while (carton.hasNext()) { count++; out.print("."); } %> <BR> There are <%= count %> eggs.</P>

The scriptlet in this fragment, in addition to counting the elements in some hypothetical iterator named carton, also has the effect of printing a period for each counted element. If there are five elements in this iterator, this page fragment will produce the following output:
Counting eggs..... There are 5 eggs.

By taking advantage of this implicit object, then, output can be generated from within the body of a scriptlet without having to temporarily close the scriptlet to insert static page content or JSP expressions. In addition, the javax.servlet.jsp.JspWriter class defines a number of methods that support JSP-specific behavior. These additional methods are summarized in table 6.11, and are primarily used for controlling the output buffer and managing its relationship with the output stream that ultimately sends content back to the browser. The full set of methods for this class appears in appendix F.
Table 6.11 JSP-oriented methods of the javax.servlet.jsp.JspWriter interface

Method
isAutoFlush()

Description
Returns true if the output buffer is automatically flushed when it becomes full, false if an exception is thrown. Returns the size (in bytes) of the output buffer. Returns the size (in bytes) of the unused portion of the output buffer. Clears the contents of the output buffer, discarding them. Clears the contents of the output buffer, signaling an error if the buffer has previously been flushed. Writes a (platform-specific) line separator to the output buffer. Flushes the output buffer, then flushes the output stream. Closes the output stream, flushing any contents.

getBufferSize() getRemaining() clearBuffer() clear() newLine() flush() close()

Implicit objects

111

Here is a page fragment that uses the out object to display the buffering status:
<% int total = out.getBufferSize(); int available = out.getRemaining(); int used = total available; %> Buffering Status: <%= used %>/<%= total %> = <%= (100.0 * used)/total %>%

Local variables are created to store the buffer size parameters, and expressions are used to display the values of these local variables. This page fragment is particularly useful when tuning the buffer size for a page, but note that the values it prints are only approximate, because the very act of displaying these values on the page uses up some of the output buffer. As written, the displayed values are accurate for all of the content that precedes this page fragment, but not for the fragment itself (or any content that follows it, of course). Given, however, that this code would most likely be used only during page development and debugging, this behavior is not only acceptable, but also preferable: the developer needs to know the buffer usage of the actual page content, not of the debugging message. The methods provided for clearing the buffer are also particularly useful. In the discussion of exception handling, recall that it was necessary to rewrite our original example in order to make the output more user-friendly when an error condition arose. More specifically, it was necessary to introduce a local variable and precompute the result we were interested in. Consider, instead the following approach:
<% out.flush(); try { %> <p align=center> <%= x %>! = <%= fact(x) %></p> <% } catch (IllegalArgumentException e) { out.clearBuffer(); %> <p>Sorry, factorial argument is out of range.</p> <% } %>

In this version, the flush() method is called on the out object to empty the buffer and make sure all of the content generated so far is displayed. Then the try block is opened and the call to the fact() method, which has the potential of throwing an IllegalArgumentException, is made. If this method call successfully completes, the code and content in the catch block will be ignored. If the exception is thrown, however, then the clearBuffer() method is called on the out object. This will have the effect of discarding any content that has been generated since the last time the output buffer was flushed. In this particular case, the output buffer was flushed just before opening the try block. Therefore, only the content generated by the try block before the exception occurred would be in the output buffer, so only that content will be removed when the output buffer is

112

CHAPTER 6

Actions and implicit objects

cleared. The output buffer will then be overwritten with the error message indicating that the argument was out of range.
WARNING There is, of course, a down side to this approach. Recall from the discussion

of buffered output in chapter 4, that once the output buffer has been flushed, it is no longer possible to change or add response headers, or forward to another page. The call to the flush() method at the beginning of this page fragment thus limits your options for processing the remainder of the page.

6.1.3 Contextual objects


The implicit objects in this category provide the JSP page with access to the context within which it is being processed. The session object, for example, provides the context for the request to which the page is responding. What data has already been associated with the individual user who is requesting the page? The application object provides the server-side context within which the page is running. What other resources are available, and how can they be accessed? In contrast, the pageContext object is focused on the context of the JSP page itself, providing programmatic access to all of the other JSP implicit objects which are available to the page, and managing their attributes.

Session object This JSP implicit object represents an individual users current session. As described in the section on session management in chapter 4, all of the requests made by a user that are part of a single series of interactions with the web server are considered to be part of a session. As long as new requests by that user continue to be received by the server, the session persists. If, however, a certain length of time passes without any new requests from the user, the session expires. The session object, then, stores information about the session. Applicationspecific data is typically added to the session by means of attributes, using the methods in table 6.12. Information about the session itself is available through the other methods of the javax.servlet.http.HttpSession interface, of which the session object is an instance. The most commonly used methods of this interface are summarized in table 6.12, and the full API appears in appendix F.

Implicit objects

113

Table 6.12

Relevant methods of the javax.servlet.http.HttpSession interface

Method
getId() getCreationTime() getLastAccessedTime() getMaxInactiveInterval() setMaxInactiveInterval(t) isNew() invalidate()

Description
Returns the session ID. Returns the time at which the session was created. Returns the last time a request associated with the session was received. Returns the maximum time (in seconds) between requests for which the session will be maintained. Sets the maximum time (in seconds) between requests for which the session will be maintained. Returns true if users browser has not yet confirmed the session ID. Discards the session, releasing any objects stored as attributes.

One of the primary uses for the session object is the storing and retrieving of attribute values, in order to transmit user-specific information between pages. As an example, here is a scriptlet that stores data in the session in the form of a hypothetical UserLogin object:
<% UserLogin userData = new UserLogin(name, password); session.setAttribute("login", userData); %>

Once this scriptlet has been used to store the data via the setAttribute() method, another scripting elementeither on the same JSP page or on another page later visited by the user could access that same data using the getAttribute() method, as in the following:
<% UserLogin userData = (UserLogin) session.getAttribute("login"); if (userData.isGroupMember("admin")) { session.setMaxInactiveInterval(60*60*8); } else { session.setMaxInactiveInterval(60*15); } %>

Note that when this scriptlet retrieves the stored data, it must use the casting operator to restore its type. This is because the base type for attribute values is java.lang.Object, which is therefore the return type for the getAttribute() method. Casting the attribute value enables it to be treated as a full-fledged instance of the type to which it has been cast. In this case, a hypothetical isGroupMember() method is called to determine whether or not the user is a member of the administrator group. If so, the session time-out is set to eight hours. If not, the session is set to expire after fifteen minutes of inactivity. The implication is that

114

CHAPTER 6

Actions and implicit objects

administrators (who are presumably more responsible about restricting access to their computers) should not be required to log back in after short periods of inactivity during the workday, while access by other users requires stricter security. Note that JSP provides a mechanism for objects to be notified when they are added to or removed from a users session. In particular, if an object is stored in a session and its class implements the javax.servlet.http.HttpSessionBindingListener interface, then certain methods required by that interface will be called whenever session-related events occur. Details on the use of this interface are presented in chapter 8. Unlike most of the other JSP implicit objects which can be accessed as needed from any JSP page, use of the session object is restricted to pages that participate in session management. This is indicated via the session attribute of the page directive, as described earlier in this chapter. The default is for all pages to participate in session management. If the session attribute of the page directive is set to false, however, any references to the session implicit object will result in a compilation error when the JSP container attempts to translate the page into a servlet.

Application object This implicit object represents the application to which the JSP page belongs. It is an instance of the javax.servlet.ServletContext interface. JSP pages are deployed as a group (in combination with other web-based assets such as servlets, images, and HTML files) in the form of a web application. This grouping is then reflected by the JSP container in the URLs by which those assets are exposed. More specifically, JSP containers typically treat the first directory name in a URL as an application. For example, http://server/ games/index.jsp, http://server/games/ matrixblaster.jsp, and http:/ /server/ games/space/paranoids.jsp are all elements of the same games application. Specification of this grouping and other properties of the web application is accomplished via Web Application Descriptor files, as described in chapter 14. The key methods of the javax.servlet.ServletContext interface can be grouped into five major categories. First, the methods in table 6.13 allow the developer to retrieve version information from the ser vlet container. Next, table 6.14 lists several methods for accessing server-side resources represented as file names and URLs. The application object also provides support for logging, via the methods summarized in table 6.15. The fourth set of methods supported by this interface are those for getting and setting attribute values, presented in table 6.2. A final pair of methods (identical to those in table 6.3) provides access to initialization parameters associated with the application as a whole (as opposed to

Implicit objects

115

the page-specific initialization parameters accessed via the config implicit object). For the full API of the javax.servlet.ServletContext interface, see appendix F.
Table 6.13 Container methods of the javax.servlet.ServletContext interface

Method
getServerInfo() getMajorVersion() getMinorVersion()

Description
Returns the name and version of the servlet container. Returns the major version of the Servlet API for the servlet container. Returns the minor version of the Servlet API for the servlet container.

Table 6.14

Methods of the javax.servlet.ServletContext interface for interacting with server-side paths and files

Method
getMimeType(y) getResource(path)

Description
Returns the MIME type for the indicated file, if known by the server. Translates a string specifying a URL into an object that accesses the URLs contents, either locally or over the network. Translates a string specifying a URL into an input stream for reading its contents. Translates a local URL into a pathname in the local filesystem. Returns the application context for the specified local URL. Creates a request dispatcher for the indicated local URL.

getResourceAsStream(path) getRealPath(path) getContext(path) getRequestDispatcher(path)

Table 6.15

Methods of the javax.servlet.ServletContext interface for message logging

Method
log(message) log(message, exception)

Description
Writes the message to the log file. Writes the message to the log file, along with the stack trace for the specified exception.

As indicated in tables 6.136.15, the application object provides a number of methods for interacting with the HTTP server and the servlet container in an implementation-independent manner. From the point of view of JSP development, however, perhaps the most useful methods are those for associating attributes with an application. In particular, a group of JSP pages that reside in the same application can use application attributes to implement shared resources. Consider, for example, the following expression, which implements yet another variation on the construction and initialization of a database connection pool:

116

CHAPTER 6

Actions and implicit objects

<% DbConnectionPool pool = (DbConnectionPool) application.getAttribute("dbPool"); if (pool == null) { String username = application.getInitParameter("username"); String password = application.getInitParameter("password"); pool = DbConnectionPool.getPool(this, username, password); application.setAttribute("dbPool", pool); } %>

In this case, the connection pool is constructed in the same manner, but is stored in a local variable instead of a class variable. This is done because the long-term storage of the connection pool is handled via an application attribute. Before constructing the connection pool, the application attribute is first checked for a pool that has already been constructed. If a pool is not available via this application attribute, a new connection pool must be constructed. In this case, construction proceeds as before, with the added step of assigning this pool to the application attribute. The other significant difference is that, in this version, the initialization parameters are retrieved from the application object, rather than from the config object. Initialization parameters associated with the application can be accessed by any of the applications JSP pages. Such parameters need only be specified once, using the Web Application Descriptor file (see chapter 14), whereas the initialization parameters associated with the config object must be specified on a pageby-page basis. Reliance on application initialization parameters enables reuse of this code across multiple JSP pages within the application, without having to specify the initialization parameters multiple times. Such reuse can be facilitated by making use of the JSP include directive, and enables you to ensure that the connection pool will only be constructed once, and then shared among all of the pages.
TIP

Like session attributes, the base type for application attributes is java.lang.Object. When attribute values are retrieved from an application, they must be cast back to their original type in order to access their full functionality. Initialization parameters take the form of String objects.

As indicated in table 6.13, the application implicit object also provides access to information about the environment in which the JSP page is running, through the getServerInfo(), getMajorVersion(), and getMinorVersion() methods. Keep in mind, however, that the data returned by these methods is with respect to the servlet container in which the JSP page is running. To obtain the corresponding information about the current JSP container, the JSP specification provides an

Implicit objects

117

abstract class named javax.servlet.jsp.JspEngineInfo that provides a method for retrieving the JSP version number. Since this is an abstract class, a somewhat convoluted path is necessary in order to access an actual instance. The required steps are implemented by the following JSP page fragment:
<%@ page import="javax.servlet.jsp.JspFactory" %> <% JspFactory factory = JspFactory.getDefaultFactory(); %> JSP v. <%= factory.getEngineInfo().getSpecificationVersion() %>

For further details on the JspEngineInfo and JspFactory classes, see appendix F.

PageContext object The pageContext object provides programmatic access to all other implicit objects. For the implicit objects that support attributes, the pageContext object also provides methods for accessing those attributes. In addition, the pageContext object implements methods for transferring control from the current page to another, either temporarily to generate output to be included in the output of the current page or permanently to transfer control altogether. The pageContext object is an instance of the javax.servlet.jsp.PageContext class. The full API for this class in presented in appendix F, but the important methods of this class fall into four major groups. First, there is a set of methods for programmatically accessing all of the other JSP implicit objects, as summarized in table 6.16. While these methods are not particularly useful from a scripting perspective (since these objects are already available as scripting variables), we will discover their utility in chapter 18 when we look at how JSP custom tags are implemented. The second group of javax.servlet.jsp.PageContext methods enables the dispatching of requests from one JSP page to another. Using the methodslisted in table 6.17, the handling of a request can be transferred from one page to another either temporarily or permanently. Further details on the application of this functionality will be provided when we look at the <jsp:forward> and <jsp:include> actions toward the end of this chapter.
Table 6.16 Methods of the javax.servlet.jsp.PageContext class for programatically retrieving the JSP implicit objects

Method
getPage() getRequest() getResponse()

Description
Returns the servlet instance for the current page (i.e., the page implicit object). Returns the request that initiated the processing of the page (i.e., the request implicit object). Returns the response for the page (i.e., the response implicit object).

118

CHAPTER 6

Actions and implicit objects

Table 6.16

Methods of the javax.servlet.jsp.PageContext class for programatically retrieving the JSP implicit objects (continued)

Method
getOut() getSession() getServletConfig() getServletContext() getException()

Description
Returns the current output stream for the page (i.e., the out implicit object). Returns the session associated with the current page request, if any (i.e., the session implicit object). Returns the servlet configuration object (i.e., the config implicit object). Returns the context in which the page s servlet runs (i.e., the application implicit object). For error pages, returns the exception passed to the page (i.e., the exception implicit object).

Table 6.17

Request dispatch methods of the javax.servlet.jsp.PageContext class

Method
forward(path) include(path)

Description
Forwards processing to another local URL. Includes the output from processing another local URL.

The remaining two groups of methods supported by the pageContext object deal with attributes. This implicit object is among those capable of storing attributes. Its class therefore implements all of the attribute access methods listed in table 6.2. In keeping with its role as an avenue for programmatically accessing the other JSP implicit objects, however, the javax.servlet.jsp.PageContext class provides a set of methods for managing their attributes, as well. These methods are summarized in table 6.18.
Table 6.18 Methods of the javax.servlet.jsp.PageContext class for accessing attributes across multiple scopes

Method
setAttribute(key, value, scope) getAttributeNamesInScope(scope) getAttribute(key, scope) removeAttribute(key, scope) findAttribute(name) getAttributesScope(name)

Description
Associates an attribute value with a key in a specific scope. Retrieves the names of all attributes in a specific scope. Retrieves the attribute value associated with the key in a specific scope. Removes the attribute value associated with the key in a specific scope. Searches all scopes for the named attribute. Returns the scope in which the named attribute is stored.

Implicit objects

119

As indicated earlier in this chapter, four different implicit objects are capable of storing attributes: the pageContext object, the request object, the session object, and the application object. As a result of this ability, these objects are also referred to as scopes, because the longevity of an attribute value is a direct result of the type of object in which it is stored. Page attributes, stored in the pageContext object, only last as long as the processing of a single page. Request attributes are also shortlived, but may be passed between pages as control is transferred during the handling of a single request. Session attributes persist as long as the user continues interacting with the web server. Application attributes are retained as long as the JSP container keeps one or more of an applications pages loaded in memoryconceivably, as long as the JSP container is running.
NOTE

Only a single thread within the JSP container can access attributes stored with either page or request scope: the thread handling the processing of the associated request. Thread safety is more of a concern, then, with session and application attributes. Because multiple requests for an applications pages will be handled simultaneously, objects stored with application scope must be robust with respect to access by these multiple threads. Similarly, because a user may have multiple browser windows accessing a servers JSP pages at the same time, it must be assumed that objects stored with session scope may also be accessed by more than one thread at a time.

In conjunction with the methods listed in table 6.18 whose parameters include a scope specification, the javax.servlet.jsp.PageContext class provides static variables for representing these four different scopes. Behind the scenes, these are just symbolic names for four arbitrary integer values. Since the actual values are hidden, the symbolic names are the standard means for indicating attribute scopes, as in the following page fragment:
<%@ page import="javax.servlet.jsp.PageContext" %> <% Enumeration atts = pageContext.getAttributeNamesInScope(PageContext.SESSION_SCOPE); while (atts.hasMoreElements()) { %> Session Attribute: <%= atts.nextElement() %><BR> <% } %>

These variables are summarized in table 6.19.

120

CHAPTER 6

Actions and implicit objects

Table 6.19

Class scope variables for the javax.servlet.jsp.PageContext class

Variable
PAGE_SCOPE REQUEST_SCOPE SESSION_SCOPE APPLICATION_SCOPE

Description
Scope for attributes stored in the pageContext object. Scope for attributes stored in the request object. Scope for attributes stored in the session object. Scope for attributes stored in the application object.

The last two methods listed in table 6.18 enable developers to search across all of the defined scopes for an attribute with a given name. In both cases, the pageContext object will search through the scopes in orderfirst page, then request, then session, and finally applicationto either find the attributes value or identify in which scope (if any) the attribute is defined.
WARNING The session scope is accessible only to pageContext methods on pages that

actually participate in session management.

6.1.4 Error handling


This last category of JSP implicit objects has only one member, the exception object. As its name implies, this implicit object is provided for the purpose of error handling within JSP.

Exception object The ninth and final JSP implicit object is the exception object. Like the session object, the exception object is not automatically available on every JSP page. Instead, this object is available only on pages that have been designated as error pages using the isErrorPage attribute of the page directive. On those JSP pages that a r e er r or p ag es , the e x c e p t i o n ob je ct will be an instance of the java.lang.Throwable class corresponding to the uncaught error that caused control to be transferred to the error page. The methods of the java.lang.Throwable class that are particularly useful in the context of JSP are summarized in table 6.20.

Actions

121

Table 6.20

Relevant methods of the java.lang.Throwable class

Method
getMessage() printStackTrace(output) toString()

Description
Returns the descriptive error message associated with the exception when it was thrown. Prints the execution stack in effect when the exception was thrown to the designated output stream. Returns a string combining the class name of the exception with its error message (if any).

Here is an example page fragment demonstrating the use of the exception object:
<%@ page isErrorPage="true" %> <H1>Warning!</H1> The following error has been detected:<BR> <B><%= exception %></B><BR> <% exception.printStackTrace(new java.io.PrintWriter(out)); %>

In this example, the exception object is referenced in both an expression and a scriptlet. As you may recall, expression values are converted into strings for printing. The expression here will therefore call exception objects toString() method in order to perform this conversion, yielding the results described in table 6.20. The scriptlet is used to display the stack trace for the exception, by wrapping the out implicit object in an instance of java.io.PrintWriter and providing it as the argument to the printStackTrace() method.

6.2

Actions
In chapter 5 we examined three types of JSP tags, directives, scripting elements, and comments. Actions are the fourth and final major category of JSP tags, and themselves serve three major roles. First, JSP actions allow for the transfer of control between pages. Second, actions support the specification of Java applets in a browser-independent manner. Third, actions enable JSP pages to interact with JavaBeans component objects residing on the server. In addition, all custom tags defined via tag libraries take the form of JSP actions. The creation and use of custom tags is described in chapter 18. Finally, note that unlike directives and scripting elements, actions employ only a single, XML-based syntax.

122

CHAPTER 6

Actions and implicit objects

Request

<jsp:forward... /> Request

Original page

Forwarded page

Response
Figure 6.1 Effect of the <jsp:forward> action on the processing of a request

6.2.1 Forward
The <jsp:forward> action is used to permanently transfer control from a JSP page to another location within the same web application (see chapter 13) as the original page. Any content generated by the current page is discarded, and processing of the request begins anew at the alternate location. The basic syntax for this JSP action is as follows:
<jsp:forward page="localURL" />

The page attribute of the <jsp:forward> action is used to specify this alternate location to which control should be transferred, which may be a static document, a servlet, or another JSP page. Note that the browser from which the request was submitted is not notified when the request is transferred to this alternate URL. In particular, the location field at the top of the browser window will continue to display the URL that was originally requested. The behavior of the <jsp:forward> action is depicted in figure 6.1. As with the include directive described in the previous chapter, if the string value identifying the URL for the page attribute starts with a forward slash character, it is resolved relative to the top-level URL directory of the web application. If not, it is resolved relative to the URL of the JSP page containing the <jsp:forward> action. For added flexibility, the <jsp:forward> action supports the use of request-time attribute values (as described in chapter 4) for the page attribute. Specifically, this means that a JSP expression can be used to specify the value of the page attribute, as in the following example:
<jsp:forward page=<%= "message" + statusCode + ".html" %> />

Every time the page is processed for a request and the <jsp:forward> action is to be taken, this expression will be evaluated by the JSP container, and the resulting

Actions

123

value will be interpreted as the URL to which the request should be forwarded. In this particular example, the URL value is constructed by concatenating two constant String values with the value of some local variable named statusCode. If, for example, the value of statusCode were 404, then this action would forward control to the relative URL, message404.html. As mentioned, the <jsp:forward> action can be used to transfer control to any other document within the same web application. For the specific case when control is transferred to another JSP page, the JSP container will automatically assign a new pageContext object to the forwarded page. The request object, the session object, and the application object, though, will be the same for both the original page and the forwarded page. As a result, some but not all of the attribute values accessible from the original page will be accessible on the forwarded page, depending upon their scope: page attributes are not shared, but request, session, and application attributes are. If you need to transfer data as well as control from one page to another, the typical approach is to store this data either in the request, the session, or the application itself, depending upon how much longer the data will be needed, and whether it is user-specific. (Recall, however, that the session object is available only on pages which are marked as participating in session management.)
TIP

All of the objects in which JSP pages can store attribute values, with the exception of the pageContext, are also accessible via the servlet API. As a result, this approach can also be used to transfer data when forwarding from a JSP page to a servlet.

Since the request object is common to both the original page and the forwarded page, any request parameters that were available on the original page will also be accessible from the forwarded page. It is also possible to specify additional request parameters to be sent to the forwarded page through use of the <jsp:param> tag within the body of the <jsp:forward> action. The syntax for this second form of the <jsp:forward> action is as follows:
<jsp:forward page="localURL"> <jsp:param name="parameterName1" value="parameterValue1"/> <jsp:param name="parameterNameN" value="parameterValueN"/> </jsp:forward>

For each <jsp:param> tag, the name attribute identifies the request parameter to be set and the value attribute provides the corresponding value. This value can be

124

CHAPTER 6

Actions and implicit objects

either a static character string or a request-time attribute value (i.e., a JSP expression). There is no limit on the number of request parameters that may be specified in this manner. Note also that the passing of additional request parameters is independent of the type of document to which control is transferred; the <jsp:param> tag can thus be used to set request parameters for both JSP pages and servlets.
NOTE

As you might infer from the inclusion of getParameterValues() among the methods of the request implicit object listed in table 6.4, HTTP request parameters can actually have multiple values. The effect of the <jsp:param> tag when used with the <jsp:forward> and <jsp:include> actions is to add a value to a particular parameter, rather than simply set its value. This means that if a request parameter has already been assigned one or more values by some other mechanism, the <jsp:param> tag will simply add the specified value to those already present. Note, however, that this new value will be added as the first (or primary) value of the request parameter, so subsequent calls to the getParameter() method, which returns only one value, will in fact return the value added by the <jsp:param> tag. If the <jsp:param> tag is applied to a request parameter that does not already have any values, then the value specified in the tag becomes the parameters first and only value. Again, subsequent calls to getParameter() will return the value set by the tag.

Given that the <jsp:forward> action effectively terminates the processing of the current page in favor of the forwarded page, this tag is typically used in conditional code. Although the <jsp:forward> action could be used to create a page which generates no content of its own, but simply uses the <jsp:param> tag to set request parameters for some other page, scenarios such as the following are much more common:
<% if (! database.isAvailable()) { %> <%-- Notify the user about routine maintenance. --%> <jsp:forward page="db-maintenance.html"/> <% } %> <%-- Database is up, proceeed as usual... --%>

Here, a method is called to check whether or not a hypothetical database server is available. If not, control is forwarded to a static HTML page which informs the user that the database is currently down for routine maintenance. If the server is up and running, then processing of the page continues normally, as indicated in the comment following the conditional code.

Actions

125

One factor that you need to keep in mind when using this tag is its interaction with output buffering. When the processing of a page request encounters the <jsp:forward> tag, all of the output generated thus far must be discarded by clearing the output buffer. If the output buffer has been flushed at least once, however, some of the output from the page will already have been sent to the users browser. In this case, it is impossible to discard that output. Therefore, if the output buffer associated with the current page request has ever been flushed prior to the <jsp:forward> action, the action will fail, and an IllegalStateException will be thrown. As a result, any page that employs the <jsp:forward> action should be checked to make sure that its output buffer is large enough to ensure that it will not be flushed prior to any calls to this action. Alternatively, if output buffering is disabled for the page, then any code which might call the <jsp:forward> action must appear on the page before any static or dynamic elements that generate output. The final consideration in the use of this tag is the issue of cleanup code. If a JSP page allocates request-specific resources, corresponding cleanup code may need to be run from the page once those resources are no longer needed. If such a page makes use of the <jsp:forward> tag, then processing of that page will end if and when this tag is reached. Any cleanup code that appears in the JSP file after the <jsp:forward> tag will therefore not be run if processing of the page causes this action to be taken. Dependent upon the logic in the page, then, it may be necessary to include a call to the cleanup code just before the <jsp:forward> tag, in order to make sure that resources are managed properly.

6.2.2 Include
The <jsp:include> action enables page authors to incorporate the content generated by another local document into the output of the current page. The output from the included document is inserted into the original pages output in place of the <jsp:include> tag, after which processing of the original page resumes. In contrast to the <jsp:forward> tag, then, this action is used to temporarily transfer control from a JSP page to another location on the local server. The <jsp:include> action takes the following form:
<jsp:include page="localURL" flush="flushFlag" />

The page attribute of the <jsp:include> action, like that of the <jsp:forward> action, is used to identify the document whose output is to be inserted into the current page, and is specified as a URL within that pages web application (i.e., there is no host or protocol information in the URL, just directories and a file name). The

126

CHAPTER 6

Actions and implicit objects

included page can be a static document, a servlet, or another JSP page. As with the <jsp:forward> action, the page attribute of the <jsp:include> action supports request-time attribute values (i.e., specifying its value via a JSP expression). The flush attribute of the <jsp:include> action controls whether or not the output buffer for the current page (if any) is flushed prior to including the content from the included page. In version 1.1 of the JSP specification, it was required that the flush attribute be set to true, indicating that the buffer is flushed before processing of the included page begins. This was a result of earlier limitations in the underlying servlet API. In JSP 1.2, which is based on version 2.3 of the servlet API, this limitation has been removed. In containers implementing JSP 1.2, then, the flush attribute of the <jsp:include> action can be set to either true or false; the default value is false. When the value of the flush attribute is set to true, the first step of the JSP container in performing the <jsp:include> action is to flush the output buffer. Under these circumstsances, then, the standard restrictions on the behavior of JSP pages after the buffer has been flushed apply. In particular, forwarding to another page including an error pageis not possible. Likewise, setting cookies or other HTTP headers will not succeed if attempted after processing the <jsp:include> tag. For similar reasons, attempting to forward requests or set headers or cookies in the included page will also fail (in fact, an exception will be thrown), although it is perfectly valid for an included page to itself include other pages via the <jsp:include> action. If the flush attribute is set to false, only the restrictions on setting headers and cookies still apply; forwarding, including to error pages, is supported. As with pages accessed via the <jsp:forward> action, JSP pages processed via the <jsp:include> tag will be assigned a new pageContext object, but will share the same request, session, and application objects as the original page. As was also the case with the <jsp:forward> action, then, the best way to transfer information from the original page to an included JSP page (or servlet) is by storing the data as an attribute of either the request object, the session object, or the application object, depending upon its expected longevity. Another element of functionality that the <jsp:include> action has in common with the <jsp:forward> action is the ability to specify additional request parameters for the included document. Again, this is accomplished via use of the <jsp:param> tag within the body of the <jsp:include> action, as follows:
<jsp:include page="localURL" flush="true"> <jsp:param name="parameterName1" value="parameterValue1"/>

Actions

127

<jsp:param name="parameterNameN" value="parameterValueN"/> </jsp:include>

As before, the name attribute of the <jsp:param> tag identifies the request parameter to be set and the value attribute provides the corresponding value (which may be a request-time attribute value), and there is no limit on the number of request parameters that may be specified in this manner, or on the type of document to which the request parameters will be passed. As indicated in figure 6.2, the <jsp:include> action works by passing its request on to the included page, which is then handled by the JSP container as it would handle any other request. The output from the included page is then folded into the output of the original page, which resumes processing. This incorporation of content takes place at the time the request is handled. In addition, because the JSP container automatically generates and compiles new servlets for JSP pages that have changed, if the text in a JSP file included via the <jsp:include> action is changed, the changes will automatically be reflected in the output of the including file. When the request is directed from the original file to the included JSP page, the standard JSP mechanismsthat is, translation into a stand-alone servlet, with automatic recompilation of changed filesare employed to process the included page. In contrast, the JSP include directive, described in the previous chapter, does not automatically update the including page when the included file is modified. This is because the include directive takes effect when the including page is translated into a servlet, effectively merging the base contents of the included page into those of the original. The <jsp:include> action takes effect when processing requests, and merges the output from the included page, rather than its original text. There are a number of tradeoffs, then, that must be considered when deciding whether to use the action or the directive. The <jsp:include> action provides the benefits of automatic recompilation, smaller class sizes (since the code

Request

<jsp:include.../> Request Response

Original page

Included page

Response
Figure 6.2 Effect of the <jsp:include> action on the processing of a request

128

CHAPTER 6

Actions and implicit objects

corresponding to the included file is not repeated in the servlets for every including JSP page), and the option of specifying additional request parameters. The <jsp:include> action also supports the use of request-time attribute values for dynamically specifying the included page, which the directive does not. Furthermore, the include directive can only incorporate content from a static document (e.g., HTML) or another JSP page. The <jsp:include> action, since it includes the output from an included URL rather than the contents of an included source document, can be used to include dynamically generated output, such as from a servlet. On the other hand, the include directive offers the option of sharing local variables, as well as slightly better run-time efficiency, since it avoids the overhead of dispatching the request to the included page and then incorporating the response into the output of the original page. In addition, because the include directive is processed during page translation and compilation, rather than during request handling, it does not impose any restrictions on output buffering. As long as the output buffer is sufficiently large, pages which utilize the include directive are not limited with respect to setting headers and cookies or forwarding requests.

6.2.3 Plug-in
The <jsp:plugin> action is used to generate browser-specific HTML for specifying Java applets which rely on the Sun Microsystems Java plug-in. As the primary focus of this book is the use of JSP for server-side Java applications rather than client-side applications, details on the use of this action may be found in appendix C.

6.2.4 Bean tags


JSP provides three different actions for interacting with server-side JavaBeans: <jsp:useBean>, <jsp:setProperty>, and <jsp:getProperty>. Because compo-

nent-centric design provides key strengths with respect to separation of presentation and application logic, the next two chapters are devoted to the interaction between JSP and JavaBeans.

Using JSP components

This chapter covers


I I I

The JSP component model JavaBean fundamentals Interacting with components through JSP

129

130

CHAPTER 7

Using JSP components

JSP scriptlets and expressions allow developers to add dynamic elements to web pages by interleaving their HTML pages with Java code. While this is a great way for Java

programmers to create web-based applications and expressive sites, in general this approach lacks an elegant separation between presentation and implementation, and requires the content developer to be well versed in the Java programming language. Along with scripting, JSP provides an alternative, component-centric approach to dynamic page design. JSP allows content developers to interact with Java components not only though Java code, but through HTML-like tags as well. This approach allows for a cleaner division of labor between application and content developers.

7.1

The JSP component model


The JSP component model is centered on software components called JavaBeans. Before we can explain the specifics of JavaBeans and how they relate to JSP development we must first understand the role of software components in the development process. Once we have an understanding of component-based design principles we will learn how to apply these techniques to web page design in JSP.

7.1.1 Component architectures


Components are self-conBank tained, reusable software Account Database teller manager access Database user elements that encapsulate module component interface application behavior or data into a discrete packa g e . Yo u c a n th i nk o f Figure 7.1 A component-based application components as black box devices that perform specific operations without revealing the details of what s going on under the hood. Because they abstract their behavior from their implementation, they shield their user from messy detailsproviding added functionality without increased complexity. Components are stand-alone and not bound tightly to any single application or use. This allows them to be used as building blocks for multiple, potentially unrelated projects. These two principles, abstraction and reusability, are the cornerstones of component-centric design. Figure 7.1 illustrates how a collection of independent software components is assembled to form a complete solution. Think of components as reusable software elements that we can glue together to construct our applications. A good component model allows us to eliminate or greatly reduce the amount of glue code necessar y to build our applications. Component architectures work by employing an interface that allows our

The JSP component model

131

components to work together in a more integrated fashion. It is this commonality that binds components together and allows them to be used by development tools that understand the interface to further simplify development.

7.1.2 Benefits of a component architecture


Lets look at an example of component-centric design thats more concrete. When an architect designs a new home he or she relies on components to save time, reduce complexity, and cut costs. Rather than design every wall unit, window frame, and electrical system from scratch he or she uses existing components to simplify the task. Architects dont design a custom air-conditioning system; they select an existing unit that will fit their requirements from the many models available on the market. There s a good chance that the architect doesn t have the skills or resources to design an air-conditioning system anyway. And conversely the designer of the air-conditioning system probably couldnt build a house. Because of this component-based approach the architect and contractor can concentrate on building what they know besthouses, and the air-conditioning company can build airconditioners. Component architectures allow us to hide a components complexity behind an interface that allows it to interact with its environment or other components. It isnt necessary to know the details of how a component works in order to access its functionality. We can use this real world example to illustrate another important feature of component designreusability. The construction company can select an off-theshelf air-conditioner because it supports standard connectors, fastens with standard screws, and runs off a standard electric voltage. Later, if the homeowner decides to replace the unit with a new and improved model, there is no need to rebuild the housesimply swap out the old component for the new. Standardized environments and design specifications have allowed for a flexible system that is easily maintained. Software components are designed to operate in specific environments, and interact in predetermined ways. The fact that components must follow a certain set of rules allows us to design systems that can accept a wide array of components.

Component development While it would be nice if we could design our entire application from pre-existing components, thats an approach thats rarely practical for real application design. Usually an application developed with a component approach involves a combination of general purpose and application specific components. The benefits of component reuse sur face not only by sharing components among dif fering

132

CHAPTER 7

Using JSP components

applications, but through reuse of components across several segments of the same or related applications. A banking application, for example, might have several different customer interfaces, an employee access module, and an administrative screen. Each of these related applications could make use of a common component that contained all of the knowledge necessary to display the specifics of a particular bank account. With luck, and good forethought during component design, this banking component might be useful to anyone developing financial management applications. Once a component has been designed, the components author is relatively free to change its inner-workings without having to track down all of the components users. The key to achieving this high level of abstractness is defining an interface that shields any application relying on the component from the details of its implementation.

7.1.3 Component design for web projects


A component-based approach is ideal for the design of web applications. JSP lets web designers employ the same component design principles that other software developers have been using for years. Rather than having to embed complex logic directly into pages through scripting code, or building page content into the programming logic, they can simply employ HTML layout around components. The component models ability to reuse common components can reduce development time and project complexity. Isolating application logic from presentation layout is a necessity for web development organizations that are built around teams whose members have a diverse set of complementary skill sets. In many enterprises the web team is composed of both application developers and web developers. Java application developers are skilled in tasks such as exchanging information with a database and optimizing back-end server code for performance, while web developers are good with the presentation aspects such as interface design and content layout. In a componentized JSP development project, application developers are free to concentrate on developing components that encapsulate program logic, while web developers build the application around these components, focusing their energies on its presentation. As illustrated in figure 7.2, clearly defined boundaries between an applications core functionality and its presentation to its user allow for a clearer separation of responsibilities between development teams. In some cases a single person may handle both aspects of design, but as project complexity grows, splitting up the tasks of the development process can yield a number of benefits. Even for web projects being handled by a small, unified team of developers, a component-based architecture makes sense. The flexibility offered by

The JSP component model

133

Java developers domain

Data presentation

Application logic

Web designer s domain

Data access

Database

Figure 7.2

Division of labor in a web applications development

components allows a project to handle the sudden changes in requirements that often seem to accompany web projects.

7.1.4 Building applications from components


So how can we use these component design principles in the design of web applications? Lets look at how we might develop a web shopping application with such an approach. As is typical for an enterprise application, this example involves collecting information from a database based on user input, performing some calculations on the data, and displaying the results to the user. In this case we will display a catalog of items, allow the user to select some for purchase, and calculate tax and shipping costs, before sending the total back to the user. What we want to end up with is an online form that allows us to enter the customers purchases, and, upon submitting the form, returns a new page with a nicely formatted invoice that includes shipping fees and tax. Our page designers should have no problem creating an attractive input form and invoice page, and our developers can easily calculate shipping and tax costs. It is only the interaction between the two worlds that gets a little sticky. What technologies are best utilized in the design of such an application? Since our product catalog is stored in a database, that portion of the application has to be tied to the server, but where should the tax and shipping calculations take place? We could use a client-side scripting approach with something like JavaScript. However, JavaScript isnt supported in every browser, and would reveal our calculations in the source of our page. Important calculations such as shipping and tax should be confined to the server for security purposes; we certainly dont want the client browser performing the task.

134

CHAPTER 7

Using JSP components

A server-side approach using JSP scripts would get around this problem. We can access back-end resources with the code running safely on the server. While this approach works well for smaller projects, it creates a number of difficulties for a project such as this one. Directly imbedding JSP scripts into all of our pages introduces a high degree of intermingling between our HTML page design and our business logic. Our web designers and application developers will require a detailed understanding of each others work in order to create the application. We could choose to have the developers create a bare-bones implementation, then let our designers polish it up. Or, we could let the designers develop a nice page layout with no logic in it and then have the application developer punch in the code to calculate tax and shipping. Does that provide the division of labor were looking for? Not quite. A problem with this approach surfaces when we deploy and maintain our application. Consider, for example, what happens when our catalog sales application (originally developed for use by a single location of the company) becomes so wildly successful our bosses decide to deploy it companywide to all twenty-eight branches. Of course the sales tax is different at each branch so we make twenty-eight copies of our page and find an application developer familiar with the code to make the necessary changes to the JSP scripts. Then, we have to get our web developers to change the HTML of each page to correct any branch-specific design or branding issues. Over the course of the applications lifetime we will constantly have to fiddle with calculations, fix bugs, increase shipping rates, update the design, and add new features. All of this work must happen across twenty-eight different versions of the code. Why should we need two groups of people doing the same job twenty-eight times over? A web application developed around components offers a better approach. With the ability to deploy components into our HTML pages we can allow our application developers to design tax and shipping calculating components that can be configured at run time with determining factors like the local tax rate. Our web page developers can then rely on these components without having to involve the application developers each time some HTML needs to be changed or a new version of the page created. On the application development side any bug fixes or updates would be isolated to the components themselves and would not affect our web page developers duties. So how do components fit in with JSP? JSP leverages the JavaBeans component model, which well explore next.

JavaBean fundamentals

135

7.2

JavaBean fundamentals
JavaBeans are software components written in Java. The components themselves are called beans and must adhere to specifications outlined in the JavaBeans API. The JavaBeans API was created by Sun with the cooperation of the industry and dictates the rules that software developers must follow in order to create stand-alone, reusable software components. Like many other software components, beans encapsulate both state and behavior. By using JSPs collection of bean-related tags in their web pages, content developers can leverage the power of Java to add dynamic elements to their pages without writing a single line of Java code. Before delving into the specifics of working with beans in JSP, we need to learn more about the beans themselves.

Bean containers A bean container is an application, environment, or programming language that allows developers to call up beans, configure them, and access their information and behavior. Applications that use beans are composed purely of Java code, but bean containers allow developers to work with it at a higher conceptual level. This is possible because JavaBeans expose their features and behavior to the bean container, allowing the developer to work with the bean in a more intuitive fashion. The bean container defines its own way of presenting and interacting with the bean and writes the resulting Java code itself. If you have used Suns Bean Box, IBMs Visual Age for Java, Visual Caf, or other Java development tools you ve already had some experience with beans. These applications include bean containers that work with beans in a visual format. With these tools you can build an application by simply dragging bean icons into position and defining the specifics of their behavior and their connections to other beans. The application then generates all of the necessary Java code. Like these visual tools, JSP containers allow developers to create web-based Java applications without needing to write Java. In JSP we interact with beans through a collection of tags that we can embed inside our HTML. Bean properties Bean containers allow you to work with beans in terms of properties named attributes of the bean that maintain its state and control its behavior. A bean is defined by its properties, and would be pretty much useless without them. Bean properties can be modified at run time by the bean container to control specifics of the beans behavior. These property values are the sole mechanism the bean container uses to expose beans to the developer.

136

CHAPTER 7

Using JSP components

As an example, lets suppose we have a bean called WeatherBean that knows various things about the current weather conditions and forecasts. The bean could collect current weather information from the National Weather Service computers, or extract it from a databasethe point being that as the beans user we do not need to understand the specifics of how the bean gets its information. All we care about as developers is that the WeatherBean is able to give us information such as the current temperature, the projected high, or the chances for rain. Each of these bits of information is exposed to the bean container as a property of the bean whose value we can access for our web page or application. Each bean will have a different set of properties depending on the type of information it contains. We can customize a bean by setting some of its property values ourselves. The beans creator will impose restrictions on each property of the bean, controlling our access to it. A property can be read-only, write-only, or readable and writable. This concept of accessibility allows the bean designer to impose limits on how the beans can be used. In our WeatherBean, for example, it doesnt make any sense to allow developers to modify the value of the beans property representing today s high temperature. That information is managed by the bean itself and should be left read-only. On the other hand, if the bean had a property controlling the ZIP code of the region in whose weather we are interested, it would certainly make sense to allow developers to specify it. Such a property would be writable, and probably readable as well.
NOTE

As well learn in detail in chapter 8, behind the scenes JavaBeans are merely Java objects. A JavaBeans properties map to the methods of a Java object that manipulates its state. So when you set a property of a bean, its like a shortcut for calling object methods through Java. Likewise, viewing the current value of a beans property is essentially calling a method of an object and getting its results. Well learn how a Java objects methods map into bean properties in the next chapter.

Trigger and linked properties Some properties are used to trigger behavior as well as report information and are thus called trigger properties. Reading from or writing to a trigger property signals the bean to perform an activity on the back end. These triggers, once activated, can either update the values of other properties or cause something to happen on the back end. Changing the value of our ZIP code property for example might cause the bean to run off to the National Weather Service, request weather conditions in the new ZIP code, and update its other weather related properties accordingly. In

JavaBean fundamentals

137

that case the weather properties and the ZIP code property are considered linked properties because changing the value of one updates the values of others.

Indexed properties It is also possible for a single property to store a collection of values. These properties are known as indexed properties because each value stored in the property is accessed through an index number, which specifies which particular value you want. For example you can request the first value in the list, the third, or the twentyseventh. Our WeatherBean could have a property that holds forecasted temperatures for the next five days, for example. Not every bean container provides a simple mechanism for working with these multivalue properties directly, however. The JSP bean tags, for example, do not recognize indexed properties. Instead, you must use JSP scriptlets, JSP expressions, or custom JSP tags (discussed in chapters 18 and 19) to access them. Property data types Bean properties can be used to hold a wide array of information. WeatherBeans properties would need to store everything from temperatures to rainfall odds, forecasts, ZIP codes, and more. Each property of a bean can hold only one specific type of data such as text or a number. bean property values are assigned a Java data type, which is used internally by the bean and in the Java code generated by the bean container. As you might expect, properties can hold any of the Java primitives like int or double, as well as Java objects like Strings and Dates. Properties can also store user-defined objects and even other beans. Indexed properties generally store an array of values, each of the same data type. The bean container determines how we work with the property values of a bean. With JSP scriptlets and expressions we reference property values by their Java data type. If a property stores integer values we get integer values out of it and must put integer values into it. With bean tags, however, we treat every property as if it were stored text, or in Java parlance, a String. When you set the value of a bean property, you pass it text. Likewise, when you read the contents of a property you get back text, regardless of the internal data type used inside the bean. This text-only strategy keeps JSP bean tags simple to work with and fits in nicely with HTML. The JSP container automatically performs all of the necessary type conversions. When you set an integer property, for example, it performs the necessary Java calls to convert the series of numeric characters you gave it into an actual integer value. Of course this conversion process requires you to pass in appropriate text values that Java can correctly convert into the native data type. If a property handles floating

138

CHAPTER 7

Using JSP components

point values, for example, it would throw an error if you attempted to set the value to something like banana bread, one hundred, or (3,9). Clever bean designers can control property values themselves by accepting string values for nonstring properties and performing the conversions themselves. For any value which is neither a string nor a Java primitive type, this technique must be used. Therefore it might be perfectly legal to set an integer property to one hundred, provided the beans designer had prepared it for such input.

Bean property sheets A beans capabilities are documented in a table called a property sheet which lists all of the properties available on the bean, their level of access afforded to the users, and their Java type. Property sheets may also specify example or valid values for each property of the bean. Table 7.1 shows the property sheet for the WeatherBean component that we have been using.
Table 7.1 Property sheet examples

Name
zipCode currentTemp todaysHigh todaysLow rainOdds forecasts iconURL

Access
read/write read-only read-only read-only read-only read-only read-only

Java Type
String int int int float String[] URL

Example Value
77630 87 101 85 0.95 Sunny, Rainy, Cloudy, Sunny, Hot http://imageserver/weather/rainy.gif

Property sheets allow bean designers to describe the features of a bean to its users, such as JSP developers, servlet programmers, and the like. From the property sheet a developer can determine what type of information the bean can contain and what behavior it can provide. Of course, the property sheet alone may not be enough to adequately explain the behavior of a bean to the end user. In this case additional information can be communicated through the beans documentation.

7.2.1 The different types of JavaBeans


For purposes of discussion we can think of beans as falling into three general categories: visual component beans used as elements of graphical user interfaces (GUI), data beans that provide access to a collection of information, and service beans (also

JavaBean fundamentals

139

known as worker beans) that can perform specific tasks or calculations. Of course some beans can be classified in more than one category.

Visual component beans The development of visual components has been one of the most common uses of JavaBeans. Visual components are elements such as text fields, selectors, or other widgets useful for building user interfaces. By packaging GUI components into beans, Java development environments can take advantage of JavaBeans support for visual programming. This allows developers to create their interfaces by simply dragging the desired elements into position. Since visual beans have been designed to run as part of graphical Java applications, they are not compatible with JSP, which is intended for text-based applications such as HTML interface design. Data beans Data beans provide a convenient way to access data that a bean itself does not necessarily have the capability to collect or generate. The calculation or collection of the data stored inside data beans is the responsibility of some other, more complex component or service. Data beans are typically read-only, allowing you to fetch data from them but not allowing you to modify their values on your own. However, some data beans allow you to set some of their properties in order to control how data is formatted or filtered before being returned through other properties. For example, an AccountStatusBean might also have a currencyType property that controls whether the balance property returned data in dollars, pounds, or Swiss francs. Because of their simplicity, data beans are useful to standardize access to information by providing a stable interface. Service beans Service beans, as you might expect, provide access to a behavior or particular service. For this reason they are sometimes referred to as worker beans. They can retrieve information from a database, perform calculations, or format information. Since the only way that we can interact with a bean is through its properties, this is how we will access a beans services. In a typical design, we will set the value of certain properties that control the beans behavior, and then read the results of the request through other properties. A bean designed to access a database of employee phone numbers, for example, might have a property called employee, which we could set to the name we wish to look up. Setting this property triggers the database search and sets the phone and email properties of the bean to reflect the information of the requested employee.

140

CHAPTER 7

Using JSP components

Not all service beans collect data from a back-end source. Some simply encapsulate the logic necessary to perform calculations, conversions, or operations. A StatisticsBean might know how to calculate averages, medians, and standard deviations, for example. A UnitConversionBean might allow the page designer to specify some distance in inches and get it back in feet, yards, miles, or furlongs. Some service beans will not return any information. Their service may be to store information in a database or log file, for example. In this case, you might set a propertys value not to get results of the service, but simply for its side-effect behaviorwhat happens on the back end. Service beans allow for a clear separation of responsibility and for teams to have separate knowledge domains. The web designer doesnt need to understand statistical calculations and the programmer doesnt need to understand subtleties of page layout. A change in either the presentation or the program logic will not affect the others, provided the beans interface does not change.

7.3

JSP bean tags


Now that we have a good understanding of the principles of component architecture and JavaBeans we can get into the nitty-gritty of building web pages around them. JSP has a set of bean tags which can be used to place beans into a page, then access their properties. Unlike JSP scriptlets and expressions we explored in the previous chapter, you do not need to be a Java programmer in order to design pages around beans. In fact, you dont need to be any type of programmer at all because JSP does a pretty good job of eliminating the need for messy glue between our HTML and components.

7.3.1 Tag-based component programming


JSP needs only three simple tags to enable interaction with JavaBeans: <jsp:useBean>, <jsp:setProperty>, and <jsp:getProperty> . These tags allow you to

place beans into the page as well as alter and access their properties. Some people complain about the simplicity of the JSP tag set, preferring an approach that embeds more functionality into the tags themselves similar to PHP or ColdFusion. It is important to understand that the limited set of functionality afforded to JSP bean tags is intentional. They are not meant to provide a full-featured programming language; programmers can use JSP scriptlets for that. Instead, the bean tags enable the use of component design strategies in HTML documents without the need for the page author to learn a programming language or to understand advanced programming concepts.

JSP bean tags

141

As always, there is a fine line in determining the trade-off between the power of a language and its complexity. As a good compromise, the JSP designers elected to keep the core functionality very simple, defining only a few tags for working with beans and establishing a specification that allows for the development of new, custom tags that solve specific problems. The standard tags allow you to create references to beans you need to use, set the values of any configurable properties they might have, and read information from the beans properties. Custom tags with more complex levels of functionality can be developed by individuals and organizations and integrated into any JSP environment through an extension mechanism known as custom tag libraries. Through custom tags the JSP language can be extended to support additional programming constructs, like conditionals and loops, as well as provide additional functionality such as direct access to databases. Well learn about custom tags and tag libraries in chapters 18 and 19.

An illustrative example Lets whet our appetite by looking at JSP code built around components, rather than scriptlets. This example shows some of the things we can accomplish with the component-centric design model, and will serve as a kickoff to our discussion of JSPs component features.
<jsp:useBean id="user" class="RegisteredUser" scope="session"/> <jsp:useBean id="news" class="NewsReports" scope="request"> <jsp:setProperty name="news" property="category" value="financial"/> <jsp:setProperty name="news" property="maxItems" value="5"/> </jsp:useBean> <html> <body> Welcome back <jsp:getProperty name="user" property="fullName"/>, your last visit was on <jsp:getProperty name="user" property="lastVisitDate"/>. Glad to see you again! <P> There are <jsp:getProperty name="news" property="newItems"/> new articles available for your reading pleasure. Please enjoy your stay and come back soon. </body> </html>

Notice how straightforward the page design has become? We have used a few special JSP tags to eliminate all of the Java code from our page. Even though we have not yet discussed the specifics of any of the bean tags, you probably already have a good idea of what the code does just by looking at it. It uses two components, user and news. The first allows us to greet visitors personally, and the second stores news items in which they might be interested. JSP bean tags allow us to more clearly

142

CHAPTER 7

Using JSP components

Figure 7.3

Dynamic content with JSP

understand the pages layout because we are writing HTML, not code. Figure 7.3 shows what the page looks like on the browser.

7.3.2 Accessing JSP components


To interact with a bean we first tell the page where to find the Java class file that defines the bean and assign it a name. We can then use this name to access the values stored in the beans properties. By mastering just three simple JSP tags you can add component-based web page design to your repertoire. We will look at each of these tags in-depth.

The <jsp:useBean> tag The <jsp:useBean> tag tells the page that we want to make a bean available to the page. The tag is used to create a bean or fetch an existing one from the server. Attributes of the tag specify the type of bean you wish to use and assign it a name we can use to refer to it. The <jsp:useBean> tag comes in two forms, a single empty tag and a matching pair of start and end tags that contain the body of the tag which can be used to specify additional configuration information. In its simplest and most straightforward form the <jsp:useBean> tag requires only two attributes, id and class. Like all of the JSP tags, you must enclose each attribute value in quotes. The basic syntax for the tags two forms is:
<jsp:useBean id="bean name" class="class name"/> <jsp:useBean id="bean name" class="class name"> initialization code </jsp:useBean>

JSP bean tags

143

Table 7.2 shows all of the possible attribute values supported by the <jsp:useBean> tag. We will discuss the purpose of each throughout the chapter, but for now we will concentrate on understanding the basic bean tag attributes.
Table 7.2 Attributes of the <jsp:useBean> tag

Attribute
id scope class type beanName

Value
Java identifier

Default
none
myBean session

Example Value

page, request, session, appli- page cation Java class name Java class name Java class or serialized Bean none same as class none

java.util.Date com.manning.jsp.AbstractPerson com.manning.jsp.USCurrency.ser

The ID attribute The id attribute specifies a name for the beana unique value that will refer to this particular bean throughout the page and over the course of its lifetime (well learn how to extend the beans life beyond the current page later). We can use multiple <jsp:useBean> tags to define more than one bean within a page, even multiple instances of the same bean class, as long as there is a unique identifier associated with each individual bean. The name we select for our bean is arbitrary, but it must follow some simple rules:
I

It must be unique to the page It must be case sensitive The first character must be a letter Only letters, numbers, and the underscore character (_) are allowed (no spaces)

The class attribute The value of the class attribute specifies the class name of the JavaBean itself. To help better organize code and avoid conflicts, Java classes are usually organized into packages. Packages are collections of individual Java class files organized inside a single directory. Package names are usually composed of multiple, period-separated names where each name is a directory in the package hierarchy. You must always specify the fully qualified name of the bean class. A fully qualified class name consists of the name of the classs package and the class name itself. By convention, packages begin with the Internet domain name of their creator, and usually include more

144

CHAPTER 7

Using JSP components

levels of hierarchy to help better organize collections of classes into logical collections. The beans developer will determine the actual package and class name of the bean. Some fully qualified bean class names might look something like the following:
com.manning.RegisteredUserBean com.deepmagic.beans.database.logging.LogBean com.blokware.MagicPizzaBean com.taglib.wdjsp.arch.EmployeeBean

The actual bean class is the last part of the fully qualified name, so in the first example we are talking about a RegisteredUserBean inside the com.manning package. Unlike other Java code, which allows you to import packages and refer to the classname alone, JSP requires fully qualified class names inside the <jsp:useBean> tag. For example, the following does not work:
<%@page import="com.manning.*" %> <jsp:useBean id="user" class="RegisteredUserBean" />

The correct way


<jsp:useBean id="user" class="com.manning.RegisteredUserBean" />

Early implementations of the JSP specification sometimes allowed non-fully qualified class names in this tag, but as of version 1.2 these are no longer allowed. Even if your container supports this shortcut, you should always fully qualify your names to keep your code compatible with other containers or updates to yours. Note that for scripting variables, imported packages are supported and fully qualified class names are not required.

The type attribute In practice you wont use this attribute too much. The <jsp:useBean> tags class attribute determines which Java class is used to create our bean, but JSP offers a way of fine-tuning the JSP containers interpretation of the beans type which is sometimes needed when beans exist on the server and are not being instantiated by the current page. By default, the bean is referenced by the class type corresponding directly to the underlying objects class. However, if you need to refer to the bean as another type, for example a base class or an interface that the bean implements, you can use the type attribute of the <jsp:useBean> tag to do so. The class type you specify is used to represent the bean object in the Java resulting from the JSP compilation phase. The beans actual class must, of course, be assignable to the class type specified. If you specify both class and type attributes, the bean will be created using the given class, then cast to the given type. The type attribute can only be used alone (that is without a corresponding class attribute) in cases where the

JSP bean tags

145

bean already exists on the server, a feature known as scope which well cover in the last section of this chapter. Like the class attribute, you must specify the fully qualified name of the class.

The beanName attribute This attribute, which is not used too often, specifies the name of a bean which will be passed to the instantiate() method of the java.beans.Beans class. It will always take the format of x.y.z, but can refer to either a fully qualified classname or a local serialized bean, located in the file path x/y/z.ser. If present, this class or resource will be instantiated and assigned to the reference specified by the id attribute. One unique feature of this attribute of the <jsp:useBean> tag is that it can be assigned through a run-time expression, allowing you to specify the name of the class or resource via a request parameter. The tag body The tags optional body portion can be used to initialize any user configurable properties of the bean. This lets us configure a bean specifically for this page or our particular application. We will discuss bean initialization in detail later. For now, well look at beans that do not require any special initialization at the time they are created. <jsp:useBean> in action Lets get into using the bean tags. Heres an example of the <jsp:useBean> tag in action.
<jsp:useBean id="myclock" class="com.manning.jsp.ClockBean"/> <html> <body> There is a Bean hiding in this page! </body> </html>

Weve told the page that we will be using a bean that is defined in the Java class file ClockBean in the com.manning.jsp package and weve named the bean myclock for use in the page. In practice we like to put all of our <jsp:useBean> tags at the beginning of the HTML document, but syntactically it is valid to use the tag anywhere in the page. However, keep in mind that beans are only available to portions of the page following the <jsp:useBean> tag in which they were defined. Portions of the page before the <jsp:useBean> tag will have no reference to the bean, and attempting to access the bean will cause an error. The <jsp:useBean> tag creates an instance of the bean and assigns its ID as specified by the id attribute. When the new bean is created it performs any tasks or

146

CHAPTER 7

Using JSP components

data processing as designed by the beans author. For example, the ClockBean sets its internal state to reflect the current time and date, while another bean might look up information in a database. This is part of the normal Java instantiation process and happens without any help from you. Once a bean has been given a name and been made available to the page we can begin using its properties. Depending on the bean design, the properties may simply provide information such as the time of day or the name of the current user, or they might also execute complex transactions or look up information in a database. Whichever the case, the results are accessible through the beans properties. It is important to understand the difference between a bean s class and its instance. The beans class controls what type of bean will be created, its properties, and capabilities. It is used like an object template to create a unique instance of the bean with each call of the <jsp:useBean> tag. For example, consider the following tags:
<jsp:useBean id="clock1" class="com.manning.jsp.ClockBean" /> <jsp:useBean id="clock2" class="com.manning.jsp.ClockBean" />

This creates two independent, that is, completely separate, beans with their own names: clock1 and clock2. They are instances of the same class, but any changes made to one bean will have no effect on the other. Later in this chapter we will talk about how other attributes of the <jsp:useBean> tag can allow a bean to be reused between visits to a single page or across multiple pages throughout the site. In the examples above, our beans are there, but we arent actually using them to do anything. The next bean tag, <jsp:getProperty> allows us to retrieve the information stored inside the bean.

Accessing bean properties with <jsp:getProperty> The primary way to access a beans properties in JSP is through the <jsp:getProperty> tag. Unlike the <jsp:useBean> tag which performs some work behind the scenes but doesnt produce any output, the <jsp:getProperty> tag actually produces content that we can see in the HTML generated by the page. The <jsp:getProperty> tag is empty with no body element and expects two attributes, name and property. Its syntax is:
<jsp:getProperty name="bean name" property="property name"/>

The name attribute specifies the bean we are evaluating, and should correspond to the name we selected for the bean in the <jsp:useBean> tags id attribute. Dont forget that the <jsp:useBean> tag refers to the bean with the id attribute, and that other tags refer to the bean through a name attribute. It is a JSP convention that the

JSP bean tags

147

id attribute is used to define a new object, while the name attribute is used to refer-

ence an existing object. Be careful, it can be easy to confuse the two. In the resulting HTML that is displayed at run time, the tag is replaced with the value of the property of the bean you request. Of course, since we are creating an HTML document, the property is first converted into text by the JSP container. This tag is very easy to use. Lets look at the ClockBean example again, but this time well use the <jsp:getProperty> tag to ask the bean to tell us what time it is:
<jsp:useBean id="myclock" class="com.manning.jsp.ClockBean"/> <html> <body> The Bean says that the time is now: <jsp:getProperty name="myclock" property="time"/> </body> </html>

This should display HTML that looks something like:


<html> <body> The Bean says that the time is now: 12:33 pm </body> </html>

Youll use this tag a lot, as its the key to component-based dynamic output with JSP. You can use as many <jsp:getProperty> tags in your page as you need. You can intersperse them with HTML to not only dynamically generate single values and blocks of text, but to control attributes of the HTML as well. It is perfectly legal to nest JSP tags inside HTML attributes. A beans property could be used to control the pages background color, the width of a table, or the source of an image. For example, a bean reflecting a standardized corporate style might have a property that exposes the URL location of the latest version of the corporate logo and the corporate color scheme. We can display this image in our HTML as shown next without hard coding the URL value in each page.
<jsp:useBean id="style" class="beans.CorporateStyleBean"/> <html> <body bgcolor="<jsp:getProperty name="style" property="color"/>"> <center> <img src="<jsp:getProperty name="style" property="logo"/>"> Welcome to Big Corp! </center> </body> </html>

This would generate HTML like this:

148

CHAPTER 7

Using JSP components

<html> <body bgcolor="pink"> <center> <img src="http://imageserver/logo.gif"> Welcome to Big Corp! </center> </body> </html>

If the logo changes next week when the company replaces the corporate branding director, or is acquired, all of your pages will instantly reflect the new value built into the CorporateStyleBean. Another advantage here is that application programmers might be relying on the same bean to brand their interfaces, and the change would be reflected there as well.
TIP

According to the specifications, white space in a document is not significant to the JSP parser, but should be preserved by the JSP processor. In some implementations that we have encountered, however, the parser does not properly preserve white space characters between JSP bean tags when no other (non-white space) characters are present. For example, you would expect the following JSP code to display something like Firstname Lastname, but instead you might get FirstnameLastname:
<jsp:getProperty name="user" property="firstName"/> <jsp:getProperty name="user" property="lastName"/>

This might happen because the JSP parser ignored the newline, which would normally be treated as a white space character. If this happens, adding blank lines probably wont help as the JSP parser would simply ignore them too, assuming that there was nothing relevant between the two bean tags. If your JSP container suffers from this annoyance, you can work around it by placing meaningful, but empty content, such as an HTML comment, which should force it to preserve the newline character in the page output.
<jsp:getProperty name="user" property="firstName"/> <!-- insert a space --> <jsp:getProperty name="user" property="lastName"/>

The <jsp:setProperty> tag We use <jsp:setProperty> to modify the properties of beans. The <jsp:setProperty> tag can be used anywhere within the page to modify a beans properties, provided that the property has been made writable by the bean developer. We modify property values of a bean either to control specifics of the beans operation or

JSP bean tags

149

access its services. The exact behavior of changing a propertys value is bean specific. The beans author might, for example, provide a query property that specifies a database query whose results are reflected in other properties. In that case you might call <jsp:setProperty> several times in the page, reading the results properties again and again, since they would return new values after each change to the query property. Most service beans will require some amount of run-time configuration to be useful, because they depend on user-configurable properties that control some aspect of their behavior. This allows the same bean to be used over and over again to encapsulate different sets of information. For example, if a developer needed a bean to provide information about a registered user it would not be necessary to create a different type of bean for each userBobBean, SueBean, JoeBean, and so forth. The developer would instead design the beans properties to abstractly refer to properties of any user, and then make one of the beans properties control which users information is stored in the bean The <jsp:setProperty> tag is relatively straightforward. It requires three attributes: name, property, and value. Just as in the <jsp:getProperty> tag, the name attribute specifies the bean you are working with; the property attribute specifies which of the beans properties you wish to set; the value attribute is text to which you want to set the property.
<jsp:setProperty name="bean name" property="property name" value="property value"/>

The <jsp:setProperty> tag can be used anywhere inside the JSP document after the bean has been defined with the <jsp:useBean> tag. At run time JSP evaluates the tags in a page in the order they were defined, from top to bottom. Any property values that you set will only affect tags in the page that follow the <jsp:setProperty> tag. The value attribute can be specified as text or calculated at run time with JSP expressions. For example, here are a couple of ways that we can set the days since a users last visit by setting the value of a property. Both examples are functionally equivalent, they set the daysLeft property to a value of 30.
<jsp:setProperty name="user" property="daysLeft" value="30"/> <jsp:setProperty name="user" property="daysLeft" value="<%= 15 * 2 %>"/>

Indexed properties As we mentioned earlier, indexed properties contain a whole collection of values for the property. To access a value, you must pass the bean an index to indicate which value you are interested in. The standard JSP bean tags cannot deal with indexed properties; they can only be accessed through JSP scriptlets, expressions, and

150

CHAPTER 7

Using JSP components

custom tags. For example, lets look at WeatherBeans forecasts property, which holds five String values, a forecast for each of the next five days. To view tomorrows forecast we must specify the first element, which is referenced in array style notation as element 0, the next days is element 1 , and so forth. You access an indexed property through a JSP scriptlet or expression simply by calling the method behind the property and passing it an index value. To read from an indexed property, prefix it with the word get; to write to it use the prefix set. (Well explain how properties are mapped to method names in detail in chapter 8.) To read from the forecasts property we would call the method getForecasts(). For example:
<B>Tomorrows Forecast</B>: <%= weather.getForecasts(0) %> <BR> <B>The Rest of the Week</B> <UL> <% for (int index=1; index < 5; index++) { %> <LI><%= weather.getForecasts(index) %> (maybe) <% } %> </UL>

In the above example we use JSP scriptlets and expressions to access the indexed forecasts property of our WeatherBean, which has been loaded into the page with an id of weather. To display the forecast for tomorrow, we use a JSP expression to get the first element of the forecasts property by calling its access method, getForecasts(), with an argument of 0. We then use a scriptlet to loop through elements 1, 2, 3, and 4 to display a list of the forecasts for the rest of the week. Beans with indexed properties can be designed to work more easily with JSPs so that the JSP developer doesnt have to resort to scriptlets in order to access them. A bean can include a convenience property that allows you to treat an indexed property as a single string value by separating each value with a comma or other delimiter.

7.3.3 Initializing beans


When a bean is first created it can be initialized by setting the value of its configurable properties. This initialization happens only the first time the bean is created. By default, this initialization phase will take place each time the page is accessed, since a bean is being created for each request. As we will see later when we discuss the bean life cycle, beans can also be stored in and retrieved from the environment of the web server, in which case they will not need to be reinitialized. When a bean is first created it may be necessary to initialize it by setting the value of any properties that control its operation before we attempt to read any bean properties. We could simply use the <jsp:setProperty> tag in the page, but as we will learn later on, it is possible for beans to exist beyond the scope of a single

JSP bean tags

151

page request, and thus it becomes important to define a separate block of initialization code for the bean.

Bean configuration The body tag version of the <jsp:useBean> tag allows you to configure the bean before using it by setting any necessary properties with the <jsp:setProperty> tag. This form of the <jsp:useBean> has both start and end tags enclosing a body area as follows:
<jsp:useBean id="myBean" class="com.manning.jsp.MyBean"> <%-- This is the body area --%> </jsp:useBean>

Any commands inside the body are processed immediately after the bean is instantiated and before it is made available to the rest of the page. For example:
<jsp:useBean id="clock" class="com.manning.jsp.ClockBean"> <jsp:setProperty name="clock" property="timezone" value="CST"/> </jsp:useBean>

You can think of the <jsp:useBean> tags body elements as a run-once configuration phase. It is a useful way to configure the bean with page-specific configuration data or to prepare the bean for use later in the page. You can even set properties of other beans, as long as they have been created earlier in the page. The body of the <jsp:useBean> tag can also contain JSP scriptlets and arbitrary HTML markup. This HTML will be displayed as part of the page only if the bean must be instantiated. (Be sure that you place such text after your opening HTML tag!) If the bean already exists in the environment, then subsequent page requests will not display this initialization HTML. For example:
<html> <body> <jsp:useBean id="clock" class="com.manning.jsp.ClockBean"> The <b>ClockBean</b> is initializing... </jsp:useBean> The main page follows </body> </html>

Initializing beans from the request A key feature of the <jsp:setProperty> tag is its ability to set a beans properties dynamically at run time using information retrieved from the page request. This allows us to dynamically configure our beans based on user input or other events by embedding the configuration information into the page request itself. The request

152

CHAPTER 7

Using JSP components

information typically comes from an HTML form, or from request parameters hard coded into the URL. It can also be populated with valuesand even entire beans from a servlet. HTML forms provide a natural way to get input from users, fitting well into the name/value pairs associated with JavaBean properties. Like a CGI program, a JSP page can be used as a form handler by specifying its URL in the form tags action attribute. Any data in the form will be accessible to the JSP page and can be used to provide information to the bean.

Example: a compound interest calculator Listing 7.1 shows how to build a simple application that can calculate the value of compounded interest for an investment. Well first create an HTML page with a form that will collect the necessary information to perform our calculation:
Listing 7.1 CompoundInterest.htm

<html> <body> <form action="CompoundInterestResults.jsp"> Principal: <input type="text" name="principal"> Interest Rate: <input type="text" name="interestRate"> Years: <input type="text" name="years"> <input type="submit" value="Calculate Future Value"> </form> </body> </html>

We can then create a handler for our form called CompoundInterestResults.jsp, which will use the values specified in the form fields to configure a bean that can calculate compounded interest. Well actually create this bean in the next chapter, but for now lets concentrate on using this bean as a service for our page. Lets see the CompoundInterestBeans property sheet, shown in table 7.3.
Table 7.3 CompoundInterestBean property sheet

Name
principal interestRate years futureValue

Access
read/write read/write read/write read-only

Java Type
double double int String

Example
100.50 .10 10 155.21

JSP bean tags

153

The futureValue property is linked to the other properties. Its value is calculated using the values of the principal, interestRate, and years properties. To use this bean we must therefore first set the values of these three properties, then read the results from the futureValue property. Lets look at the JSP that will be the forms handler. First we must create a reference to the CompoundInterestBean.
<jsp:useBean id="calculator" class="com.taglib.wdjsp.components.CompoundInterestBean"/> <jsp:useBean id="calculator" class="com.manning.jsp.CompoundInterestBean"/>

In the body of our <jsp:useBean> tag we need to map each of the beans configuration properties to the appropriate data from the form field. The <jsp:setProperty> tag looks for an incoming request parameter matching the value specified in the param attribute of the tag. If it finds one, it tells the bean to set the corresponding property, specified via the property attribute, to that value, performing any necessary type conversion. Well add the following three lines to the body of our <jsp:useBean> tag:
<jsp:setProperty name="calculator" property="principal" param="principal"/> <jsp:setProperty name="calculator" property="interestRate" param="interestRate"/> <jsp:setProperty name="calculator" property="years" param="years"/>

The param attribute of the <jsp:setProperty> tag is the equivalent of the JSP scriptlet <% request.getParameter(something) %>. So, the above block of code is functionally equivalent to the following, which uses scriptlets instead of the param attribute to initialize the beans values:
<jsp:setProperty name="calculator" property="principal" value='<%= request.getParameter("principal") %>'/> <jsp:setProperty name="calculator" property="interestRate" value='<%= request.getParameter("interestRate") %>'/> <jsp:setProperty name="calculator" property="years" value='<%= request.getParameter("years") %>'/>

When the request comes in from the form, the beans properties will be set to the form values specified by the user. Since this is such a common way of configuring beans in JSP, a shortcut has been provided. If a property name is the same as the name of the parameter passed in through the form, we can omit the param attribute. Therefore the body of our <jsp:useBean> tag could be simplified to:
<jsp:setProperty name="calculator" property="principal"/> <jsp:setProperty name="calculator" property="interestRate"/> <jsp:setProperty name="calculator" property="years"/>

154

CHAPTER 7

Using JSP components

When multiple form field names map directly to bean properties you can also use the special wild card character * in the place of a property name. Using a wild card indicates that you wish to set the value of any bean property whose name corresponds to the name of a request parameter. The names must match exactly as there is no way to map parameters to properties with different names when the wild card is used. For each property of the bean, a matching request parameter is looked for. Extra request parameters are ignored, though they can be accessed through scriptlets and the implicit request object. You can, of course, issue additional <jsp:setProperty> commands to pick up any request parameters whose names do not map directly to bean properties. There is no way to determine or specify the order in which the beans properties are changed. If there are interdependencies, one property depending on another, you will want to explicitly set them by specifying a <jsp:setProperty> tag for each one. If we are careful to match up all of the form field names with our beans property names, we can configure all of the beans properties with a single statement. Using the wild card, our bean could be configured with a single line, like this:
<jsp:setProperty name="calculator" property="*"/>

Now that the bean has been configured, we can read the results of the beans calculation in the futureValue property. We can also verify the input by reading the values of the properties that we just configured.
If you invest $<jsp:getProperty name="calculator" property="principal"/> for <jsp:getProperty name="calculator" property="years"/> years at an interest rate of <jsp:getProperty name="calculator" property="interestRate"/>% compounding monthly, you will have $<jsp:getProperty name="calculator" property="futureValue"/>

The output of our JSP form handler will produce results like this:
If you invest $1000 for 30 years at an interest rate of 15% compounding monthly, you will have $87,541.99

The JSP page is shown in its entirety in listing 7.2.


Listing 7.2 CompoundInterestResults.jsp

<jsp:useBean id="calculator" class="com.taglib.wdjsp.components.CompoundInterestBean"/> <jsp:useBean id="calculator" class="CompoundInterestBean"/> <jsp:setProperty name="calculator" property="principal"/> <jsp:setProperty name="calculator" property="years"/> <jsp:setProperty name="calculator" property="interestRate"/>

JSP bean tags

155

</jsp:useBean> <html> <body> If you invest $<jsp:getProperty name="calculator" property="principal"/> for <jsp:getProperty name="calculator" property="years"/> years at an interest rate of <jsp:getProperty name="calculator" property="interestRate"/>% compounding monthly, you will have $<jsp:getProperty name="calculator" property="futureValue"/> </body> </html>

JSP does not care if you are using GET or POST requests for form submission. If desired, you can also use hidden form elements to add configuration information to a form without requiring the user to enter it. You can also encode directives into the request URL directly by following standard URL encoding conventions. For example the following URL will calculate interest for us, no form needed:
http://host/InterestCalculator.jsp?interestRate=0.10&years=15&principal=1000

The properties in the URL are exactly the same as if they came from a form using the GET method of data delivery. You will need to escape any special characters of course, but you will not need to decode them in the JSP, because the JSP container handles this automatically. A word of warning on form values: do not rely on hidden fields for the storage of sensitive information like database passwords. Any form data fields in your HTML, hidden or otherwise, can be viewed quite easily by anyone viewing the source of the HTML page that contains the form data. It is all right to store sensitive information inside your JSP however, provided it is part of a bean tag or JSP scriptlets, because this data will be processed on the server and will never be seen by the client code.
WARNING You cannot use request parameters that begin with jsp, jsp_, java., javax., sun. and com.sun. They are reserved for the JSP containers own use

and may conflict with request parameters assigned to the request by the container itself. One example of a reserved request parameter is jsp_precompile, used to control compilation in JSP 1.2. You can read about this precompilation feature in chapter 14.

Specifying default initialization values If you are attempting to initialize a bean property from a request parameter that does not exist or is defined as an empty value then the <jsp:setProperty>

156

CHAPTER 7

Using JSP components

command has no effect. The property does not get set to a null value, the <jsp:setProperty> tag is just ignored. You can provide a default value for a property by first setting it explicitly, then attempting to set it from the request as shown:
<jsp:setProperty name="calculator" property="interestRate" value="0.10"/> <jsp:setProperty name="calculator" property="interestRate" param="interestRate"/>

In this example, the interestRate property is set to 10 percent, but can be overwritten by the value of the interestRate request parameter if it exists. This allows you to supply appropriate default values for critical properties and to create flexible pages that might be accessed through several means.

A security consideration The wild card notation introduced earlier, <jsp:setProperty property="*">, is a very powerful shortcut for initializing bean properties from a request. It is particularly convenient for mapping the input values from a form into a set of bean properties that perform some computation. Because it is very easy for a user to construct his or her own requests, you need to be careful about using this shorthand notation when the properties of the bean control sensitive information. For example, consider an online banking application that represents account information via a JavaBean class named AccountBean. The AccountBean class provides properties for accessing information about the account, such as accountNumber and balance, as well as properties corresponding to account transactions, such as withdrawalAmount and transferAmount. Given a form that allows a user to specify a withdrawal amount, this form might then point to a JSP page such as the following that actually performs the transaction (as a side effect of setting the property values) and reports the result:
<jsp:useBean id="myAccount" class="AccountBean"> <jsp:setProperty name="myAccount" property="*"/> </jsp:useBean> <html> <head><title>Cash Withdrawal</title></head> <body> <p> $<jsp:getProperty name="myAccount" property="withdrawalAmount"/> has been withdrawn from Account #<jsp:getProperty name="myAccount" property="accountNumber"/>. Your new balance is $<jsp:getProperty name="myAccount" property="balance"/>. Thank you for patronizing us at the First Bank of Orange.

At first glance, the code seems benign. Assuming, however, that both getters and setters are available for the beans properties, the potential is very real. If the URL for this page were withdraw.jsp, consider the effect of a user submitting a request for:

JSP bean tags

157

http://server/account/withdraw.jsp?accountNumber=PH1L31N&balance=1000000

Normally, this page would be accessed as the target of a form, but there is nothing to prevent a user from manually constructing his or her own request. No withdrawal amount is specified in this URL, which presumably is not a problem, but the presence of a request parameter named balance seems a bit troublesome. When processing the pages <jsp:setProperty> tag, the JSP container will map this parameter to the beans like-named balance property, and attempt to set it to $1,000,000! One must hope the Java developer responsible for the AccountBean implementation will have put safeguards in place to prevent this sort of tampering, but the bottom line is that care must be taken when using the <jsp:setProperty> wild card. If the bean whose properties are to be set contains properties whose access must be carefully controlled (such as a bank account balance), then the bean must enforce that access control itself. Otherwise, the bean will be subject to the sort of request spoofing described here if it is ever used in conjunction with a <jsp:setProperty> tag employing the wildcard shortcut.

7.3.4 Controlling a beans scope


Up to now weve been talking about using beans as ways to encapsulate data or behavior over the life span of a single page. Each time the page is requested, a new instance of a bean is created and possibly modified via <jsp:setProperty> tags. However JSP has a very powerful feature that allows you to specify that a bean should continue to exist beyond the scope of a single page request. Such beans are stored in the server environment and reused on multiple pages, or across multiple requests for the same page. This allows us to create a bean once and then access it throughout a user s visit to our site. Any properties that we set will remain set throughout the lifetime of the bean.

Bean accessibility and life span A beans accessibility and life span are controlled through the scope attribute of the <jsp:useBean> tag. The scope attribute can have a value of page, request, session, or application. The accessibility of a bean determines which pages or parts of a web application can access the bean and its properties. A beans life span determines how long a particular bean exists before it is no longer accessible to any page. A summary of how each scope value affects the accessibility and life span of a bean is shown in table 7.4.

158

CHAPTER 7

Using JSP components

Table 7.4

Possible bean scopes

Scope
page request

Accessibility
current page only current page and any included or forwarded pages the current request and any subsequent request from the same browser the current and any future request that is part of the same web application

Life span
until page is displayed or control is forwarded to a new page until the request has been completely processed and the response has been sent back to the user life of the users session life of the application

session application

When a bean is created on the server for reuse between pages it is identified by the name specified by the id attribute of its <jsp:useBean> tag. Any time you attempt to create a bean with the <jsp:useBean> tag, the server searches for an existing instance of the bean with the same id as specified in the tag, in the scope specified by the tag. If one is found that instance of the bean is used instead of creating one. If any configuration commands have been specified in the body of the <jsp:useBean> tag, they will be ignored because the bean has already been initialized. The syntax of the scope attribute is shown below. A bean can have only one scope value. You cannot combine them in any fashion; they are by definition mutually exclusive.
<jsp:useBean id="beanName" class="class" scope="page|request|session|application"/>

Page beans If you do not specify a scope for a bean at the time it is created through the <jsp:useBean> tag, it is assigned the default scope value of page. A bean with a page-level scope is the least accessible and shortest lived of all JSP beans. Each time the page is requested, either from a new visitor or a return visitor, an instance of the bean is created. If there are any initialization tags or scriptlets in the body of the <jsp:useBean> tag, these will be executed each time. Essentially, beans with a page-level scope are transientthey are not persistent between requests. For that matter, such beans are not accessible outside of the page itself. If you use the <jsp:include> or <jsp:forward> tags, any beans with only page-level scope will not be available within the new or included page. If a page referenced by one of these tags contains <jsp:useBean> tags specifying a bean with the same id as a bean created on the parent page, they will ignore the original bean because it is out of scope, and will be forced to create their own new instance of the

JSP bean tags

159

bean instead. Since the default scope of the <jsp:useBean> tag is page-level, there is no difference between these two tags:
<jsp:useBean id="bean1" class="com.manning.jsp.ClockBean"/> <jsp:useBean id="bean2" class="com.manning.jsp.ClockBean scope="page"/>

If a bean does not need to persist between requests, or its information is of no use after the request has been completed, its probably a good candidate for page-level scope. For example, if our ClockBean is initialized to the current time and date the first time it is created then it probably doesnt do any good to keep it around for very long. If you are using the <jsp:include> or <jsp:forward> tags however, you may need to set the scope of your bean to request-level so it can be accessed from within these supplemental pages.

Request beans If you specify a value of request for the scope attribute of a <jsp:useBean> tag the JSP container will attempt to retrieve the bean from the request itself. Since the HTTP protocol does not provide a mechanism that would allow a web browser to store anything other than simple name value pairs into the request, a bean can only be stored in the request by a servlet or another JSP page on the local server. Beans are stored in the request as request attributes, a feature added to Java Servlets in the 2.2 API which we cover in chapter 8. If the bean is not initially found in the request it will be created and placed there. The life span for a bean with request-level scope is essentially the same as one with page scope except that the beans accessibility will be extended to pages referenced with the <jsp:include> and <jsp:forward> tags. This gives the request scope a dual purpose. First, it allows you to use Java servlets to create a bean and forward it to your JSP page. Second, it gives you a way to extend the reach of bean to pages that are included in or forwarded from the original page. For example, consider the situation where you include a footer at the bottom of each page via the <jsp:include> tag, and want to include page specific data. If you place the data into the page scope however, it will not be accessible by the included footer. The desired effect can be accomplished by storing your information in a bean with request scope, assuring that if present it will be seen by the footer, as well as the current page. In this example, we associate a contact name with each page, which appears in the footer.
<jsp:useBean id="contact" class="jsp.ContactBean" scope="request"> <jsp:setProperty name="contact" property="name" value="Kris DeHart"/> </jsp:useBean> <html>

160

CHAPTER 7

Using JSP components

<body> Welcome to our web site! <jsp:include file="/footers/standardFooter.jsp" flush="true"/> </body> </html>

In this example, contact will be accessible from both the current page and standardFooter.jsp, which is an HTML excerpt which looks like this:
<HR> To request changes to this page contact <jsp:getProperty name="contact" property="name"/>

This example of building up a page by including smaller, component pages to build a larger composite one is a useful technique for designing complex pages. It will be discussed in detail in chapter 8.

Session beans The session scope introduces component persistence to JSP, and is one of its most powerful constructs. Unlike the request and page scopes, a bean with a scope attribute value of session exists beyond the life of a single request because it is placed into the users session object. Recall from our discussion of JSP session management in chapter 4 that the JSP container maintains a unique session object for each user visiting the site. Placing a bean into session scope stores it in this session object, using the value of the id attribute as its identifier. A bean does not have to do anything special to support such persistence; the JSP container itself will handle the necessary state maintenance whenever you place a bean into the session through the scope attribute. Once the bean is stored in a users session it will be available to any other JSP on the server. If you call up a bean with the <jsp:useBean> tag that already exists in the session, the identifier that you specify will refer to the existing instance of the bean, rather then creating a new one. Since it is the JSP container that determines the length of time a session bean exists, its lifetime might be minutes, hours, or days. Some JSP containers, like IBMs WebSphere, can write session data to disk when the server is shut down, and restore the sessions upon restart. A container with such a capability effectively gives the beans an infinite life span. Not all containers exhibit this behavior so its not currently a feature you can rely on. If you need to store information for an indefinite length of time, or the session will be used to store critical data, you should consider storing your information in a database instead. Typically, most containers will let session data expire after it hasnt been accessed for a few hours.

JSP bean tags

161

TIP

If you have used the <%@ page session=false %> to indicate that your page does not require session support you will be unable to add beans to or fetch them from the current session! The default value of the session attribute is true, enabling session support. If you have no need for session support however, you set this attribute to false to prevent the servlet container from creating needless, wasteful session objects in memory. The session implicit object will not be available to pages where the session attribute has been set to false and will result in a run-time exception.

Sessions are useful for storing information collected through a users visit to the site and for caching information that is frequently needed at the page level. Sessions can be used to pass information from page to page without each one needing to include the logic or additional processing time required to access information stored in a database or external resource. A shopping cart is a good example of session-oriented data. A user would like a shopping carts contents to be accessible throughout the JSP application, so we create a ShoppingCartBean and store it in the users session. At each page we can include a reference to the shopping cart, allowing us to display a running total if we wish. There is an example of how to build your own JSP shopping cart in chapter 14. As a simple example, lets look at how we would use a TimerBean to report to us how long a users session has been active. We can use such a bean to log the person out after a period of inactivity or to record time-sensitive visits like completing an online survey or exam. Our TimerBean has one basic function: to report the difference between its creation time and the current time. This bean, which well develop in chapter 8, has the properties shown in its property sheet, table 7.5.
Table 7.5 TimerBean properties

Name
elapsedMillis elapsedSeconds elapsedMinutes startTime

Access
read-only read-only read-only read/write

Java Type
long long long long

Example
180000 180 3 857374234

The startTime property is intended to provide a way to affect the beans start time by either setting it to a particular time (expressed in milliseconds since the epoch), or the current time by passing it a zero or negative value.

162

CHAPTER 7

Using JSP components

Heres a simple use of the bean that on the first load will start the clock, and display the elapsed time every subsequent loadproviding of course that the time between visits does not exceed the JSP containers session timeout value.
<jsp:useBean id="timer" class="com.manning.jsp.TimerBean" scope="session"/> <html> <body> Elapsed Time: <jsp:getProperty name="timer" property="elapsedMinutes"/> minutes </body> </html>

If we wanted to add this functionality to a whole series of pages, we could include the appropriate bean tags in their own file, which we then call with the <jsp:include> tag. This example, taken from a web-based quiz application, uses the TimerBean through an included file to display the elapsed time in the footer of each page:
<html> <body> <form action="/servlet/processQuestions/6"> <b>Question 6</b><br> What is the airspeed velocity of an unlaiden European swallow? <br> <input type="text" name="answer"> <br> <input type="submit" value="Submit Answer"> </form> <jsp:include page="/footers/ElapsedTimeFooter.html" flush="true"/> </body> </html>

Here are the contents of the ElapsedTimedFooter.html file:


<jsp:useBean id="timer" class="com.manning.jsp.TimerBean" scope="session"/> <hr> Remember, speed is a factor in this exam!<BR> Time Used: <jsp:getProperty name="timer" property="elapsedSeconds"/> seconds

We can even have several different instances of TimerBean running at once, as long as they have different identifiers. It is the id attribute of the <jsp:useBean> tag that is important in distinguishing between different instances of a bean, whether referencing it from within the page or searching for it in the session.

JSP bean tags

163

TIP

The default lifetime of a session is determined by the JSP container (or more accurately, the servlet container). Beginning with the Servlet API 2.2, the HttpSession interfacess getMaxInactiveInterval() and setMaxInactiveInterval() methods can be used to view or set the timeout variables. The getLastAccessedTime() method of this interface can tell you how long it has been since the data in the session was last accessed.

Application beans A bean with a scope value of application has an even broader life cycle and further reaching availability than a session bean. Beans with application scope are associated with a given JSP application on the server. A JSP application is a collection of JSP pages, HTML pages, images, applets, and other resources that are bundled together under a particular URL hierarchy. Application beans exist throughout the life of the JSP container itself, meaning that they are not reclaimed until the server is shut downthey do not expire after a few hours or days. Unlike session beans that are available only to subsequent requests from a given user, application beans are shared by all users of the application with which they are associated. Any JSP page that is part of an application can access application beans created by other pages within that application. We will explain how to create the packaged JSP applications themselves in chapter 14. The application scope is used to store information that is useful throughout the application and not specific to the individual page requesting access to the bean. Once a bean is placed into application scope it will be used by pages throughout the site. If the bean requires any configuration information it must be page independent. If you expect configuration information to change between page requests or between users, it is probably not a good candidate for application scope. When a bean is stored in application scope there is only one instance of the bean per server. You should be very cautious about changing an application beans property once it has been stored in the application because any changes you make to the properties will instantly affect all of the JSP pages which reference the bean. Another good use of the application scope is the ability to cache application information that would be too computationally expensive to generate for each individual page request. For example, say that all of the pages of your online catalog needed access to a table of shipping rates. This information can be encapsulated into a bean and placed into the application scope. This would mean that the data would have to be collected from the database only once, conserving not only database access time but server memory as well. In each page you simply reference the

164

CHAPTER 7

Using JSP components

bean as normal, if it has not yet been instantiated and placed into the application, the server will handle it:
<jsp:useBean id="ship" class="com.manning.ShipRateBean" scope="application"/> <html> <body> Current shipping charges are: <jsp:getProperty name="ship" property="baseCharge"/> per shipment plus <jsp:getProperty name="ship" property="perItemCharge"/> per each item shipped. </body> </html>

If the bean requires any configuration you should use the body of the <jsp:useBean> tag to set your initial property values. Since you would have to do this on each and every page users might enter, you will probably want to seek alternatives in this situation. First, you could use application-specific beans which require no special configuration or whose constructors collect configuration information from another source (such as a property file). Second, you could take steps to assure that the necessary bean is placed into the application scope prior to the time any of the dependent pages would need to access the bean. Or, you can serialize your preconfigured beans off to disk, and restore them as needed.

Scope and the type attribute The type attribute of the <jsp:useBean> tag is generally only used when dealing with beans that are expected to be in scope and that are subclasses of some higher base class. If the bean exists in the current scope (say in the request or session), but you have no way of knowing its exact type, you can simply specify its base class through the type attribute. For example, a servlet or other JSP page placed a collection of objects into your session. You know that the objects are in some derivative of Javas Collection interface, but have no way of knowing if the other pages used a List, a Set, a ListArray, or anything else. In this case you simply reference the common Collection interface as the beans type; there is no need to specify a class in this case. For example:
<jsp:useBean id="elements" type="java.util.Collection" scope="session"/>

Developing JSP components

This chapter covers


I I I

The JavaBeans API Developing your own JSP components Mixing scriptlets and beans

165

166

CHAPTER 8

Developing JSP components

This chapter will help developers create their own JavaBeans for use as JSP components, and teach web designers how they are implemented behind the scenes. Fortunately, it is not necessar y to understand all of the details of JavaBeans development to work with JSP. As component architectures go, the interface between JavaServer Pages and JavaBeans is quite simple, as we will see.

8.1

What makes a bean a bean?


So what makes a bean so special? A bean is simply a Java class that follows a set of simple naming and design conventions outlined by the JavaBeans specification. Beans are not required to extend a specific base class or implement a particular interface. If a class follows these bean conventions, and you treat it like a bean then it is a bean. A particularly good thing about the bean conventions is that they are rooted in sound programming practices that you may already be following to some extent.

8.1.1 Bean conventions


The JavaBean conventions are what enable us to develop beans because they allow a bean container to analyze a Java class file and interpret its methods as properties, designating the class as a JavaBean. The conventions dictate rules for defining a beans constructor and the methods that will define its properties.

The JavaBeans API Following the conventions specified by the JavaBeans API allows the JSP container to interact with beans at a programmatic level, even though the containing application has no real understanding of what the bean does or how it works. For JSP we are primarily concerned with the aspects of the API that dictate the method signatures for a beans constructors and property access methods. Beans are just objects Like any other Java class, instances of bean classes are simply Java objects. As a result, you always have the option of referencing beans and their methods directly through Java code in other classes or through JSP scripting elements. Because they follow the JavaBeans conventions, we can work with them a lot easier than by writing Java code. Bean containers, such as a JSP container, can provide easy access to beans and their properties. Following the JavaBeans API coding conventions, as we will see, means creating methods that control access to each property we wish to define for our bean. Beans can also have regular methods like any other Java object. However,

What makes a bean a bean?

167

JSP developers will have to use scriptlets, expressions, or custom tags to access them

since a bean container can manipulate a bean only through its properties.

Class naming conventions You might have noticed that in most of our examples bean classes often include the word bean in their name, such as UserBean, AlarmClockBean, DataAccessBean, and so forth. While this is a common approach that lets other developers immediately understand the intended role of the class, it is not a requirement for a bean to be used inside a JSP page or any other bean container. Beans follow the same classnaming rules as other Java classes: they must start with an alphabetic character, contain only alphanumeric and underscore characters, and be case sensitive. Additionally, like other Java classes it is common, but not required, to start the name of a bean class with a capital letter. The magic of introspection How can the JSP container interact with any bean object without the benefit of a common interface or base class to fall back on? Java manages this little miracle through a process called introspection that allows a class to expose its methods and capabilities on request. The introspection process happens at run time, and is controlled by the bean container. It is introspection that allows us to rely on conventions to establish properties. Introspection occurs through a mechanism known as reflection, which allows the bean container to examine any class at run time to determine its method signatures. The bean container determines what properties a bean supports by analyzing its public methods for the presence of methods that meet criteria defined by the JavaBeans API. For a property to exist, its bean class must define an access method to return the value of the property, change the value of the property, or both. It is the presence of these specially named access methods alone that determine the properties of a bean class, as we will soon see. 8.1.2 The bean constructor
The first rule of JSP bean building is that you must implement a constructor that takes no arguments. It is this constructor that the JSP container will use to instantiate your bean through the <jsp:useBean> tag. Every Java class has a constructor method that is used to create instances of the class. If a class does not explicitly specify any constructors, then a default zero-argument constructor is assumed. Because of this default constructor rule the following Java class is perfectly valid, and technically satisfies the bean conventions:

168

CHAPTER 8

Developing JSP components

public class DoNothingBean { }

This bean has no properties and cant do or report anything useful, but it is a bean nonetheless. We can create new instances of it, reference it from scriptlets, and control its scope. Here is a better example of a class suitable for bean usage, a bean which knows the time. This class has a zero-argument constructor that records the time of its instantiation:
package com.taglib.wdjsp.components; import java.util.*; public class CurrentTimeBean { private int hours; private int minutes; public CurrentTimeBean() { Calendar now = Calendar.getInstance(); this.hours = now.get(Calendar.HOUR_OF_DAY); this.minutes = now.get(Calendar.MINUTE); } }

Weve used the constructor to initialize the beans instance variables hours and minutes to reflect the current time at instantiation. The constructor of a bean is the appropriate place to initialize instance variables and prepare the instance of the class for use. Of course to be useful within a JSP page we will need to define some properties for the bean and create the appropriate access methods to control them.

8.1.3 Defining a beans properties


As weve mentioned, a beans properties are defined simply by creating appropriate access methods for them. Access methods are used either to retrieve a propertys value or make changes to it. A method used to retrieve a propertys value is called a getter method, while a method that modifies its value is called a setter method. Together these methods are generally referred to as access methodsthey provide access to values stored in the beans properties. To define properties for a bean simply create a public method with the name of the property you wish to define, prefixed with the word get or set as appropriate. Getter methods should return the appropriate data type, while the corresponding setter method should be declared void and accept one argument of the appropriate type. It is the get or set prefix that is Javas clue that you are defining a property. The signature for property access methods, then, is:
public void setPropertyName(PropertyType value); public PropertyType getPropertyName();

What makes a bean a bean?

169

For example, to define a property called rank, which can be used to store text, and is both readable and writable, we would need to create methods with these signatures:
public void setRank(String rank); public String getRank();

Likewise, to create a property called age that stores numbers:


public void setAge(int age); public int getAge();

NOTE

Making your property access methods public is more than a good idea, its the law! Exposing your beans access methods by declaring them public is the only way that JSP pages will be able to call them. The JSP container will not recognize properties without public access methods. Conversely, if the actual data being reflected by the components properties is stored in instance variables it should be purposely hidden from other classes. Such instance variables should be declared private or at least protected. This helps ensure that developers restrict their interaction with the class to its access methods and not its internal workings. Otherwise, a change to the implementation might negatively impact code dependent on the older version of the component.

Lets revisit our previous example and make it more useful. We will add a couple of properties to our CurrentTimeBean called hours and minutes, that will allow us to reference the current time in the page. These properties must meet the getter method signatures defined by the JavaBeans design patterns. They therefore should look like this:
public int getHours(); public int getMinutes();

In our constructor we store the current times hours and minutes into instance variables. We can have our properties reference these variables and return their value where appropriate. The source for this bean is shown in listing 8.1.
Listing 8.1 CurrentTimeBean.java

package com.taglib.wdjsp.components; import java.util.*; public class CurrentTimeBean { private int hours;

170

CHAPTER 8

Developing JSP components

private int minutes; public CurrentTimeBean() { Calendar now = Calendar.getInstance(); this.hours = now.get(Calendar.HOUR_OF_DAY); this.minutes = now.get(Calendar.MINUTE); } public int getHours() { return hours; } public int getMinutes() { return minutes; } }

Thats all there is to it. These two methods simply return the appropriate values as stored in the instance variables. Since they meet the JavaBean rules for naming access methods, we have just defined two properties that we can access through JSP Bean tags. For example:
<jsp:useBean id="time" class="CurrentTimeBean"/> <html><body> It is now <jsp:getProperty name="time" property="minutes"/> minutes past the hour. </body></html>

Properties should not be confused with instance variables, even though instance variables are often mapped directly to property names but properties of a bean are not required to correspond directly with instance variables. A beans properties are defined by the method names themselves, not the variables or implementation behind them. This leaves the bean designer free to alter the inner workings of the bean without altering the interface and collection of properties that you expose to users of the bean. As an example of dynamically generating property values, here is a bean that creates random numbers in its property access methods rather than simply returning a copy of an instance variable. Its code is shown in listing 8.2.
Listing 8.2 DiceBean.java

package com.taglib.wdjsp.components; import java.util.*; public class DiceBean { private Random rand; public DiceBean() {

What makes a bean a bean?

171

rand = new Random(); } public int getDieRoll() { // return a number between 1 and 6 return rand.nextInt(6) + 1; } public int getDiceRoll() { // return a number between 2 and 12 return getDieRoll() + getDieRoll(); } }

In this example, our dieRoll and diceRoll properties are not managed by instance variables. Instead, we create a java.util.Random object in the constructor and call its random number generator from our access methods to dynamically generate property values. In fact, nowhere in the bean are any static values stored for these propertiestheir values are recomputed each time the properties are requested. You are not required to create both getter and setter methods for each property you wish to provide for a bean. If you wish to make a property read-only then define a getter method without providing a corresponding setter method. Conversely creating only a setter method specifies a write-only property. The latter might be useful if the bean uses the property value internally to affect other properties but is not a property that you want clients manipulating directly.

Property name conventions A common convention is that property names are mixed case, beginning with a lowercase letter and uppercasing the first letter of each word in the property name. For the properties firstName and lastName for example, the corresponding getter methods would be getFirstName()and getLastName(). Note the case difference between the property names and their access methods. Not to worry, the JSP container is smart enough to convert the first letter to uppercase when constructing the target getter method. If the first two or more letters of a property name are uppercased, for example URL, then the JSP container assumes that you really mean it, so its corresponding access methods would be getURL() and setURL().
TIP

Naming PropertiesOne situation that often leads to confusing property names is acronyms. For example consider a property representing an identification number. It could be getId or getID, making the bean property id or ID. This leads to more confusion (and ugly method names) when you combine acronyms with additional words using capatilization of their own.

172

CHAPTER 8

Developing JSP components

For example something like an accessor for an XML document, is that getXMLDocument or getXmlDocument? Is the property name xmlDocument, XMLDocument, or XmlDocument? To keep down confusion and improve consistency, you should only capitalize the first letter of acronyms. Without this rule teams tend to end up with several variations for the same basic property throughout their code base. It is first and foremost consistent and predictable and also clearly deliniates multiple word property names through capitalization. So a property method representing a Social Security number is immediately understood to be getUserSsn with a property name of userSsn. It may look funny, but youll be amazed how much confusion it avoids.

8.1.4 Indexed properties


Bean properties are not limited to single values. Beans can also contain multivalued properties. For example, you might have a property named contacts that is used to store a list of objects of type Contact, containing phone and address information. Such a property would be used in conjunction with scriptlets or a custom iteration tag to step through the individual values. Each value must be of the same type; a single indexed property cannot contain both string and integer elements, for example. To define an indexed valued property you have two options. The first style is creating an access method that returns the entire set of properties as a single array. In this case, a JSP page author or iterative custom tag can determine the size of the set and iterate through it. For example:
public PropertyType[] getProperty()

In the second option, you can access elements of the set by using an index value. This allows you additional flexibility. For example you might want to access only particular contacts from the collection.
public PropertyType getProperty(int index)

While not specifically required by JavaBean conventions, it is useful to implement both styles for a multivalued property. Its not much more work and it adds a good deal more flexibility in using the bean. To set multivalue properties there are setter method signatures analogous to the getter method naming styles described earlier. The syntax for these methods is:
public void setProperty(int index, PropertyType value) public void setProperty(PropertyType[] values)

What makes a bean a bean?

173

Another type of method commonly implemented and recognized by bean containers is the size() method that can be used to determine the size of an indexed property. A typical implementation would be:
public int getPropertySize()

This is another method that is not required but increases the flexibility of the design to give page developers more options with which to work.

Example: a bean with indexed properties In this example we will build a component that can perform statistical calculations on a series of numbers. The numbers themselves are stored in a single, indexed property. Other properties of the bean hold the value of statistical calculations like the average or the sum. This StatBeans source code is shown in listing 8.3:
Listing 8.3 StatBean.java

package com.taglib.wdjsp.components; import java.util.*; public class StatBean { private double[] numbers; public StatBean() { numbers = new double[2]; numbers[0] = 1; numbers[1] = 2; } public double getAverage() { double sum = 0; for (int i=0; i < numbers.length; i++) sum += numbers[i]; return sum/numbers.length; } public double[] getNumbers() { return numbers; } public double getNumbers(int index) { return numbers[index]; } public void setNumbers(double[] numbers) { this.numbers = numbers; } public void setNumbers(int index, double value) { numbers[index] = value;

174

CHAPTER 8

Developing JSP components

} public int getNumbersSize() { return numbers.length; } }

Since the JSP bean tags deal exclusively with scalar properties, the only way to interact with indexed properties such as these is through JSP scriptlets and expressions. In this JSP page well use a JSP scriptlet in the body of the <jsp:useBean> tag to pass an array of integers to the beans numbers property. Well have to use a scriptlet to display back the numbers themselves, but we can use a <jsp:getProperty> tag to display the average. The page is shown in listing 8.4:
Listing 8.4 stats.jsp

<jsp:useBean id="stat" class="com.taglib.wdjsp.StatBean"> <% double[] mynums = {100, 250, 150, 50, 450}; stat.setNumbers(mynums); %> </jsp:useBean> <html> <body> The average of <% double[] numbers = stat.getNumbers(); for (int i=0; i < numbers.length; i++) { if (i != numbers.length) out.print(numbers[i] + ","); else out.println(" + numbers[i]); } %> is equal to <jsp:getProperty name="stat" property="average"/> </body> </html>

The use of custom tags, a technique that we will discuss in chapters 18 and 19, can greatly aid in working with indexed properties by eliminating the need for inline code by encapsulating common functionality into simple tag elements. With custom tags, we could eliminate the need for Java code in this example. We can also move this code inside the bean, which is what well do for now.

What makes a bean a bean?

175

Accessing indexed values through JSP bean tags We might also want to include a method that will enable us to pass in the array of numbers through a standard bean tag. Since bean tags deal exclusively with single values, we will have to perform the conversion ourselves in the property access methods. Well create another pair of access methods that treat the array as a list of numbers stored in a comma delimited string. To differentiate between these two approaches, we will map the String versions of our new access methods to a new property we will call numbersList. Note that even though we are using a different property name, it is still modifying the same internal data, and will cause changes in the average and numbers properties. (Another example of this technique can be found in the Whois example of chapter 17.)
public void setNumbersList(String values) { Vector n = new Vector(); StringTokenizer tok = new StringTokenizer(values, ,"); while (tok.hasMoreTokens()) n.addElement(tok.nextToken()); numbers = new double[n.size()]; for (int i=0; i < numbers.length; i++) numbers[i] = Double.parseDouble((String) n.elementAt(i)); } public String getNumbersList() { String list = new String(); for (int i=0; i < numbers.length; i++) { if (i != (numbers.length -1)) list += numbers[i] + ,"; else list += " + numbers[i]; } return list; }

Now we can access this bean through JSP tags alone, as shown in listing 8.5.
Listing 8.5 stats2.jsp

<jsp:useBean id="stat" class="com.taglib.wdjsp.components.StatBean"> <jsp:setProperty name="stat" property="numbersList" value="100,250,150,50,450" /> </jsp:useBean> <html> <body> The average of <jsp:getProperty name="stat" property="numbersList" /> is equal to <jsp:getProperty name="stat" property="average" /> </body> </html>

176

CHAPTER 8

Developing JSP components

Figure 8.1

The ShowStats page in action

The resulting display is shown in figure 8.1.

8.1.5 Implementing bean properties as cursors


Another technique for exposing the indexed properties of beans is creating a cursor. If you are familiar with JDBC s ResultSet class, or the CachedRowSet class of JDBC 2.0, then you can probably guess where were headed. The idea here is to move the index inside the bean class as an instance variable, allowing us to access each indexed property though the <jsp:getProperty> tags by simply iterating the index. We provide a next() method which increments the index, returning false when the index counter has gone past the end of the list. This greatly reduces the amount of scriptlet code in the page, without introducing the complexity of custom tags. An example of a page using this technique is shown in listing 8.6. The PlanetBean referenced in the page is shown in listing 8.7 and the resulting display is shown in figure 8.2.
Listing 8.6 planets.jsp

<html> <body bgcolor="white"> <jsp:useBean id="planet" class="wdjsp.PlanetBean"/> <table border="1"> <tr><th>Planet</th> <th>Number of Moons</th></tr> <% while (planet.next()) { %> <tr><td><jsp:getProperty name="planet" property="name"/></td>

What makes a bean a bean?

177

<td align="center"><jsp:getProperty name="planet" property="moons"/></td></tr> <% } %> </table> </body> </html>

Listing 8.7
package wdjsp;

PlanetBean.java

public class PlanetBean { private static final int numPlanets = 9; private static final String[] names = { "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto" }; private static final int[] moons = { 0, 0, 1, 2, 16, 18, 20, 8, 1 }; private int index; public PlanetBean() { index = -1; } public void first() { index = -1; } public boolean next() { index++; if (index >= numPlanets) { index--; return false; } else { return true; } } public String getName() { return names[index]; } public int getMoons() { return moons[index]; } }

The while loop continues calling next(), incrementing the index, until it reaches the end of the list. Each time through, the index is pointing at a different planets

178

CHAPTER 8

Developing JSP components

Figure 8.2

Output of planet.jsp

data. We can then use our JSP bean tags to retrieve the corresponding properties. Although we didnt use it in this example, we provided a first() method to rollback the index to just prior to first element. This lets us rewind if we need to display the list again. As this is a simple example, weve not implemented bounds checking on the properties.

8.1.6 Boolean properties


For boolean properties that hold only true or false values, you can elect to use another bean convention for getter methods. This convention is to prefix the property name with the word is and return a boolean result. For example, consider these method signatures:
public boolean isProperty(); public boolean isEnabled(); public boolean isAuthorized();

The container will automatically look for this form of method if it cannot find a property access method matching the getter syntax discussed earlier. Setting the

What makes a bean a bean?

179

value of a boolean property is no different then the setter methods for other properties.
public void setProperty(boolean b); public void setEnabled(boolean b); public void setAuthorized(boolean b);

8.1.7 JSP type conversion


A JSP components properties are not limited to String values, but it is important to understand that all property values accessed through the <jsp:getProperty> tag will be converted into a String. A getter method need not return a String explicitly, however, as the JSP container will automatically convert the return value into a String. For the Java primitive types, conversion is handled by the methods shown in table 8.1
Table 8.1 Type conversions for <jsp:getProperty>

Property Type
boolean byte char double int float long object

Conversion to String
java.lang.Boolean.toString(boolean) java.lang.Byte.toString(byte) java.lang.Character.toString(char) java.lang.Double.toString(double) java.lang.Integer.toString(int) java.lang.Float.toString(float) java.lang.Long.toString(long)

calls the Objects toString() method

Likewise, all property setter methods accessed with a <jsp:setProperty> tag will be automatically converted from a String to the appropriate native type by the JSP container. This is accomplished via methods of Javas wrapper classes as shown in table 8.2.
Table 8.2 Type conversions for <jsp:setProperty>

Property Type
boolean or Boolean byte or Byte char or Character double or Double

Conversion from String


java.lang.Boolean.valueOf(String) java.lang.Byte.valueOf(String) java.lang.Character.valueOf(String) java.lang.Double.valueOf(String)

180

CHAPTER 8

Developing JSP components

Table 8.2

Type conversions for <jsp:setProperty> (continued)

Property Type
int or Integer float or Float long or Long

Conversion from String


java.lang.Integer.valueOf(String) java.lang.Float.valueOf(String) java.lang.Long.valueOf(String)

object

as if new String(String)

Properties are not restricted to primitive types. For objects, the JSP container will invoke the object's toString() method, which, unless you have overloaded it, will probably not be very representative of the data stored in the object. For properties holding objects rather than a String or native Java type you can set the property indirectly, for example allowing the user to set the hours and minutes separately through a pair of write-only properties and having a single read-only property called time.

Handling properties with null values Property getter methods for Javas primitive types such as int and double cannot return a null value, which is only valid for methods that return objects. Sometimes however, a property really is undefined. For example, if a property represents a users age, and a call to the database reveals that we dont know their age, what do we return? While not that critical in many applications, it may be important to some. In this case, we can simply establish a convention for this property, which says if the age is a negative number then we dont have any idea what the age isit is undefined. It is up to the JSP developer in this case to understand the convention and react to such a situation accordingly. Unfortunately, its not always that easy. How would we handle a temperature reading, where negative numbers are perfectly valid? We could still pick an unreasonable number, like -999, as an indicator that this particular value is unknown. However, such an approach is not only messyrequiring too much in-depth understanding by the JSP designerit is also dangerous. Who knows what will be a reasonable value for this application (or its decedents) ten years from now? A better approach to this problem is to add a boolean property which can verify the legitimacy of the property in question. In that case, it doesnt matter what the property is actually set to. For example we would define both a getTempReading() and isValidTempReading() methods.

What makes a bean a bean?

181

8.1.8 Configuring beans


Many times a bean will require run-time configuration by the page initializing it before it can properly perform its tasks. Since we cant pass information into the beans constructor we have to use the beans properties to hold configuration information. We do this by setting the appropriate property values immediately after the container instantiates the bean in the body of the <jsp:useBean> tag or anywhere in the page before the beans properties are accessed. It can be useful to set a flag in your class to indicate whether or not an instance is in a useful state, toggling the flag when all of the necessary properties have been set. Even though the bean tags do not allow you to pass any arguments into a beans constructor, you can still define constructors that take arguments. You will not however, be able to call them through bean tags. You can only instantiate an object requiring arguments in its constructor through a JSP scriptlet. For example:
<% Thermostat t = new Thermostat(78); %> The thermostat was set at a temperature of <%= t.getTemp() %> degrees.

One technique we have found useful is to provide a single method that handles all configuration steps. This method can be called by your constructors that take arguments, for use outside of bean tags, as well as by your property access methods once all the necessary properties have been configured. In this example well provide two constructors for this Thermostat class, as well as an init() method which would handle any necessary internal configuration. The zero argument constructor is provided for bean compatibility, calling the constructor which takes an initial temperature argument with a default value. Our init() method is then called through this alternate constructor.
public class Thermostat { private int temp; private int maxTemp; private int minTemp; private int fuelType; public Thermostat() { // no argument constructor for Bean use this(75); } public Thermostat(int temp) { this.temp = temp; init(); } public void setTemp(int temp) { this.temp = temp;

182

CHAPTER 8

Developing JSP components

// initialize settings with this temp init(); } public int getTemp() { return temp; } private void init() { maxTemp = this.temp + 10; minTemp = this.temp - 15; if (maxTemp > 150) fuelType = Fuels.DILITHIUM; else fuelType = Fuels.NATURALGAS; } }

8.2

Some examples
In this section we will present a number of more detailed examples of creating JavaBeans for use in JSP. These examples are more in-depth than the ones weve been looking at so far, and they will help give you the feel for developing more complex components. For additional examples, see the beans we develop in chapters 9 and 11.

8.2.1 Example: a TimerBean


In the previous chapter we used a TimerBean to track the amount of time a user has been active in the current browsing session. In the beans constructor we simply need to record the current time, which we will use as our starting time, into an instance variable:
private long start; public TimerBean() { start = System.currentTimeMillis(); }

The elapsedMillis property should return the number of milliseconds that has elapsed since the session began. The first time we place a TimerBean into the session with a <jsp:useBean> tag, the JSP container will create a new instance of the bean, starting our timer. To calculate the elapsed time we simply compute the difference between the current time and our starting time:
public long getElapsedMillis() { long now = System.currentTimeMillis(); return now - start; }

Some examples

183

The other property access methods are simply conversions applied to the elapsed milliseconds. We have chosen to have our minutes and seconds properties return whole numbers rather than floating points to simplify the display of properties within the JSP page and eliminate the issues of formatting and precision. If the application using our bean needs a finer degree of resolution, it can access the milliseconds property and perform the conversions themselves. You are often better off reducing component complexity by limiting the properties (and corresponding methods) you provide with the component. We have found it helpful to focus on the core functionality we are trying to provide, rather than attempt to address every possible use of the component.
public long getElapsedSeconds() { return (long)this.getElapsedMillis() / 1000; } public long getElapsedMinutes() { return (long)this.getElapsedMillis() / 60000; }

For convenience we will add a method to restart the timer by setting our start to the current time. Well then make this method accessible through the JSP bean tags by defining the necessary access methods for a startTime property and interpreting an illegal argument to setStartTime() as a request to reset the timer.
public void reset() { start = System.currentTimeMillis(); } public long getStartTime() { return start; } public void setStartTime(long time) { if (time <= 0) reset(); else start = time; }

The complete source for the bean is shown in listing 8.8.


Listing 8.8 TimerBean

package com.taglib.wdjsp.components; public class TimerBean { private long start; public TimerBean() { start = System.currentTimeMillis();

184

CHAPTER 8

Developing JSP components

} public long getElapsedMillis() { long now = System.currentTimeMillis(); return now - start; } public long getElapsedSeconds() { return (long)this.getElapsedMillis() / 1000; } public long getElapsedMinutes() { return (long)this.getElapsedMillis() / 60000; } public void reset() { start = System.currentTimeMillis(); } public long getStartTime() { return start; } public void setStartTime(long time) { if (time <= 0) reset(); else start = time; } }

Heres an example of a JSP page that pulls a TimerBean from the users session (or instantiates a new Bean, if necessary) and resets the clock, using the approach described in listing 8.8:
<jsp:useBean id="timer" class="TimerBean" scope="session"/> <jsp:setProperty name="timer" property="startTime" value="-1"/> <html><body> Your online timer has been restarted </body></html>

8.2.2 A bean that calculates interest


As a more complex example lets create a JSP component that knows how to calculate the future value of money that is accumulating interest. Such a bean would be useful for an application allowing the user to compare investments. The formula for calculating the future value of money collecting compounding interest is:
FV = principal(1 + rate/compounding periods)^(years * compounding periods)

Some examples

185

This bean will require:


I

The sum of money to be invested (the principal) The interest rate The number of years for the investment How often interest is compounded

This gives us the list of properties that the user must be able to modify. Once all of these properties have been initialized, the bean should be able to calculate the future value of our principal amount. In addition, we will need to have a property to reflect the future value of the money after the calculation has been performed. Table 8.3 defines the beans properties.
Table 8.3 Properties of a bean that calculates interest

Property Name
principal years compounds interestRate futureValue

Mode
read/write read/write read/write read/write read-only

Type
double int int double double

Since users will probably want to display the input values in addition to configuring them, they have been given both read and write access. The futureValue property is designated read-only because it will reflect the results of the calculation. Retrieving the value of the futureValue property uses the other properties to calculate our results. (If you wanted to get fancy, you could write a bean that, given any four of the properties, could calculate the remaining property value.) Well store our initialization properties in instance variables:
public class CompoundInterestBean { private double interestRate; private int years; private double principal; private int compounds;

It is a good practice to make your instance variables private since we plan to define access methods for them. This assures that all interaction with the class is restricted to the access methods allowing us to modify the implementation without affecting code that makes use of our class. Following the bean conventions, we must define a

186

CHAPTER 8

Developing JSP components

constructor that has no arguments. In our constructor we should set our initialization properties to some default values that will leave our bean property initialized. We cannot calculate the future value without our initialization properties being set to appropriate, legal values.
public CompoundInterestBean() { this.compounds = 12; this.interestRate = 8.0; this.years = 1; this.principal = 1000.0; }

Since investments are generally compounded monthly (that is twelve times a year) it might be handy to provide a shortcut that allows the bean user to not specify the compounds property and instead use the default. It would also be nice if we could provide other clients of the bean with a more robust constructor that would allow them to do all their initialization through the constructor. This can be accomplished by creating a constructor that takes a full set of arguments and calling it from the zero-argument constructor with the default values we have selected for our beans properties:
public CompoundInterestBean() { this(12, 8.0, 1, 1000.0); } public CompoundInterestBean(int compounds, double interestRate, int years, double principal) { this.compounds = compounds; this.interestRate = interestRate; this.years = years; this.principal = principal; }

This is a good compromise in the design. The bean is now useful to both traditional Java developers as well as JSP authors. We must now define access methods for our initialization properties. For each one we will verify that they have been passed valid information. For example, money cannot be invested into the past, so the year propertys value must be a positive number. Since the access methods are all similar, well just look at those for the interestRate property.
public void setInterestRate(double rate) { if (rate > 0) this.interestRate = rate; else this.interestRate = 0; }

Some examples

187

public double getInterestRate() { return this.interestRate; }

When we catch illegal arguments, such as negative interest rates, we have to decide the appropriate way of handling it. We can pick a reasonable default value, as we did here for example, or take a stricter approach and throw an exception. We chose to initialize our properties with a set of legitimate, but hard-coded values to keep our bean in a legal state. Of course, this approach might not be appropriate in every situation. Another technique for handling uninitialized data is setting up boolean flags for each property which has no legal value until it is initialized, and tripping them as each setter method is called. Another method could then be used to check the status of the flags to determine if the component had been initialized yet or not. For example, we could have defined our futureValue access method like this:
public double getFutureValue() { if (isInitialized()) return principal * Math.pow(1 + interestRate/compounds, years * compounds); else throw new RuntimeException(Bean requires configuration!"); } private boolean isInitialized() { return (compoundsSet && interestRateSet && yearsSet && principalSet); }

In such a case, the bean is considered initialized if and only if the flags for each property are set to true. We would initialize each flag to false in our constructor and then define our setter methods as:
public void setYears(int years) { yearsSet = true; if (years >=1 ) this.years = years; else this.years = 1; }

The complete code is shown in listing 8.9:


Listing 8.9 CompoundInterestBean.java

package com.taglib.wdjsp.components; public class CompoundInterestBean {

188

CHAPTER 8

Developing JSP components

private private private private

double interestRate; int years; double principal; int compounds;

public CompoundInterestBean() { this(12); } public CompoundInterestBean(int compounds) { this.compounds = compounds; this.interestRate = -1; this.years = -1; this.principal = -1; } public double getFutureValue() { if ((compounds != -1) && (interestRate != -1 ) && (years != -1)) return principal * Math.pow(1+interestRate/compounds, compounds*12); else throw new RuntimeException(Bean requires configuration!"); } public void setInterestRate(double rate) { if (rate > 0) this.interestRate = rate; else this.interestRate = 0; } public double getInterestRate() { return this.interestRate; } public void setYears(int years) { if (years >=1 ) this.years = years; else this.years = 1; } public int getYears() { return this.years; } public void setPrincipal(double principal) { this.principal = principal; } public double getPrincipal() { return this.principal;

Bean interfaces

189

} public static void main(String[] args) { CompoundInterestBean bean = new CompoundInterestBean(); bean.setInterestRate(0.06); bean.setYears(30); bean.setPrincipal(1200.00); System.out.println(FutureValue = + bean.getFutureValue()); } }

8.3

Bean interfaces
While not specifically required, there are a number of interfaces that you may choose to implement with your beans to extend their functionality. Well cover them briefly in this section.

8.3.1 The BeanInfo interface


We learned about reflection earlier, but another way that a bean class can inform the bean container about its properties is by providing an implementation of the BeanInfo interface. The BeanInfo interface allows you to create a companion class for your bean that defines its properties and their corresponding levels of access. It can be used to adapt existing Java classes for bean use without changing their published interface. It can also be used to hide what would normally be accessible properties from your client, since sometimes Javas standard reflection mechanism can reveal more information than we would like. To create a BeanInfo class use your beans class name with the suffix BeanInfo and implement the java.beans.BeanInfo interface. This naming convention is how the bean container locates the appropriate BeanInfo class for your bean. This interface requires you to define methods that inform the container about your beans properties. This explicit mapping eliminates the introspection step entirely. There is also a java.beans.SimpleBeanInfo class that provides default, donothing implementations of all of the required BeanInfo methods. This often provides a good starting point when designing a BeanInfo class for a JSP bean, because many of the bean features designed for working with visual beans are irrelevant in the context of JSP, and are ignored by the JSP container. One area where the BeanInfo approach is particularly useful is in visual, or WYSIWYG, JSP editors. JSP was designed to be machine-readable in order to support visual editors and development tools. By applying the BeanInfo interface to existing Java classes, developers can construct their own JSP components for use in such editors, even if the original component class does not follow the JavaBean

190

CHAPTER 8

Developing JSP components

conventions. Using BeanInfo classes you can designate which methods of an arbitrary class correspond to bean properties, for use with the <jsp:setPropety> and <jsp:getProperty> tags.

8.3.2 The Serializable interface


One of the JavaBean requirements that JSP does not mandate is that beans should implement the Serializable interface. This will allow an instance of the bean to be serialized, turning it into a flat stream of binary data that can be stored to disk for later reuse. When a bean is serialized to disk (or anywhere else for that matter), its state is preserved such that its property values remained untouched. There are several reasons why you might want to freeze-dry a bean for later use. Some servers support indefinite, long-term session persistence by writing any session data (including beans) to disk between server shutdowns. When the server comes back up, the serialized data is restored. This same reasoning applies to servers that support clustering in heavy traffic environments. Many of them use serialization to replicate session data among a group of web servers. If your beans do not implement the Serializable interface, the server will be unable to properly store or transfer your beans (or other classes) in these situations. Using a similar tactic, you might choose to store serialized copies of your beans to disk, an LDAP server, or a database for later use. You could, for example, implement a users shopping cart as a bean, which you store in the database between visits. If a bean requires particularly complicated configuration or setup it may be useful to fully configure the beans properties as required, then serialize the configured bean to disk. This snapshot of a bean can then be used anywhere you would normally be required to create and configure the bean by hand, including the <jsp:useBean> tag via the beanName attribute. The beanName attribute of the <jsp:useBean> tag is used to instantiate serialized beans rather than creating new instances from a class file. If the bean doesn t exist in the scope, then the beanName attribute is passed on to java.beans.Bean.instantiate(), which will instantiate the bean for the class loader. It first assumes that the name corresponds to a serialized bean file (identified by the .ser extension) in which case it will bring it to life, but if it cant find or invoke the serialized bean it will fall back to instantiating a new bean from its class.

8.3.3 The HttpSessionBindingListener interface


Implementing the Java Servlet APIs HttpSessionBindingListener interface in your JavaBean s class will enable its instances to receive notification of session events. The interface is quite simple, defining only two methods.

Bean interfaces

191

public void valueBound(HttpSessionBindingEvent event) public void valueUnbound(HttpSessionBindingEvent event)

The valueBound() method is called when the bean is first bound (stored into) the user s session. In the case of JSP, this will typically happen right after a bean is instantiated by a <jsp:useBean> tag that specifies a session scope, thus assigning the bean to the users session. The valueUnbound() method is called, as you would expect, when the object is being removed from the session. There are several situations that could cause your bean to be removed from the session. When the JSP container plans to expire a users session due to inactivity, it is required to first remove each item from the session, triggering the valueUnbound notification. The JSP container will automatically recognize that the bean is implementing the HttpSessionBindingListener interface, hence there is no need to register the bean with the container as a listener. Alternatively, this event would be triggered if a servlet, scriptlet, or other Java code specifically removed the bean from the session for some reason. Each of these events is associated with an HttpSessionBindingEvent object, which can be used to gain access to the session object. Implementing this interface will allow you to react to session events by, for example, closing connections that are no longer needed, logging transactions, or performing other maintenance activities. If you are implementing your own session persistence, such as saving a shopping cart, this would be where you would move your data off to disk or database.

8.3.4 Other features of the Bean API


In addition to the access methods and constructor conventions that we have examined here, the JavaBeans Specification defines several other features. When writing beans for use with JSP we do not generally need to concern ourselves with these remaining elements of the specification because they are more oriented toward visual beans, such as GUI components. While most of this extra functionality is not reflected into the bean tags, it can be useful working with beans through JSP scriptlets or as part of a larger system. For clarity and for the sake of completeness we will quickly point out these other features. For full details on these aspects of JavaBeans, see the JavaBeans Specification or Mannings The Awesome Power of Java Beans.

JavaBean event model The JavaBeans API supports Java 1.1 style event handling, a feature intended primarily for visual components. Events allow visual beans to communicate with one another in a standard way, without each bean having to be too tightly coupled to

192

CHAPTER 8

Developing JSP components

other beans. However, JSP containers do not support the JavaBeans event model directly. Any bean-to-bean communication is the responsibility of the bean designer.

Bound properties A bean can be designed to generate events any time changes are made to its properties. This allows users of the bean to be notified of the changes and react accordingly. If, for example, a bean contained information about the status of a radio button on a user interface which was modified by one of the beans users, any other users of the bean would be notified and could update their displays accordingly. Constrained properties Constrained properties are properties whose values must fall within specific limits. For example a property representing a percentage value must be greater than or equal to zero, and less than or equal to one hundred. The only difference between the design patterns for setting a constrained versus an unconstrained property is that it must declare that it throws the java.beans.PropertyVetoException . Objects that want to support constrained properties must also implement methods that allow other objects to register with the bean so that they can play a part in the change approval process. Constrained property functionality is not directly implemented through the bean tags, although beans can still take advantage of this functionality internally. If a bean throws an exception in response to an illegal property value, the normal JSP error handling will take place.

8.4

Mixing scriptlets and bean tags


Since JSP bean tags, scriptlets, and expressions eventually are translated into the same single Java servlet class on the server, you can combine any of the elements. This allows you to take advantage of component-centric design while not being bound by the limits of the built-in tag commands. Using the <jsp:useBean> tag to create objects puts them into the scope of the page, making them available to both scriptlets and <jsp:getProperty> and <jsp:setProperty> tags.

8.4.1 Accessing beans through scriptlets


Since the <jsp:useBean> tag creates an object reference behind the scenes, you are free to access that object through scriptlets and expressions, using the beans name as the object identifier. For example, it is perfectly valid to do either of these snippets, both of which produce the same results:

Mixing scriptlets and bean tags

193

<jsp:useBean id="stocks" class="StockMarketBean" scope="page"/> The Dow is at <jsp:getProperty name="stocks" property="dow"/> points

or
<jsp:useBean id="stocks" class="StockMarketBean" scope="page"/> The Dow is at <%= stocks.getDow() %> points

Calling bean properties through an expression rather than the somewhat lengthy <jsp:getProperty> tag can be a handy shortcut if you arent afraid of a little Java code in your page. A word of caution however! You cant always assume that a beans property returns a String or maps directly to the method you expect. It may return a different type of data than you expect (which is all right if you are calling the method in an expression), or a BeanInfo class may be redirecting you to a completely different methodone for which you may not even know the name.

8.4.2 Accessing scriptlet created objects


The reverse of this operation is not true. Objects created through scriptlets are not guaranteed to be accessible through the bean tags, because there is no guarantee that these objects will become part of the page context. Consider the following JSP code for example, which is not valid in most JSP containers.
<html><body> Auto-Shop 2000<br> <% Car car = (Car)request.getAttribute(car"); %> <% car.updateRecords(); %> This car has <jsp:getProperty name="car" property="milage"/> miles on it </body></html>

In this example we have attempted to pull an object reference, car, out of the request and use it in the page. However, the <jsp:getProperty> tag will not have a reference to the object because it was not scoped into the page through a <jsp:useBean> tag. The corrected code is:
<html><body> Auto-Shop 2000<br> <jsp:useBean id="car" class="Car" scope="request"/> <% car.updateRecords(); %> This car has <jsp:getProperty name="car" property="milage"/> miles on it </body></html>

Notice that we can access the object through both scriptlets and JSP tags, allowing us to call the updateRecords() method directly. We can even change the object referenced by the named identifier specified by <jsp:useBean>it is the identifier thats important, not the actual object reference.

194

CHAPTER 8

Developing JSP components

Alternatively, you can scope the bean into the pageContext directly using the code:
pageContext.setAttribute("car", car);

Handling indexed properties This technique is particularly useful in handling indexed properties, which JSP doesnt provide any easier way to deal with (other than custom tags, as well learn in chapters 18 and 19). We apply the same principles as before, creating objects with the <jsp:useBean> tag and referencing them through scriptlets and expressions. For example, to loop through an indexed property we write code similar to that which follows. The exact syntax will depend on your beans properties and associated methods. In this example, MusicCollectionBean contains an array of Album objects, nested in its albums property. Each Album object in turn has a number of bean properties. Note however, that we must declare the Album object reference through a bean tag as a placeholder, or it will not be available to our page context and therefore inaccessible through the bean tags.
<jsp:useBean id="music" class="MusicCollectionBean"/> <jsp:useBean id="album" class="Album"/> <% Album[] albums = music.getAlbums(); for (int j=0; j < albums.length; j++) { album = albums[j]; %> Title: <jsp:getProperty name="album" property="title"/><BR> Artist: <jsp:getProperty name="album" property="artist"/><BR> Year: <jsp:getProperty name="album" property="year"/><BR> <% } %>

This code will loop through each of the albums in the array returned by the getAlbums() method of MusicCollectionBean, assigning each to the variable album in turn. We can then treat album as a bean, accessing it through the <jsp:getProperty> tags. You can use this technique to create tables, lists, and other sequences of indexed properties.

Other bean methods Since beans are just objects, they may also have methods that are accessible through JSP scripting elements. While it is desirable to create beans that can be used entirely through the tags, sometimes it is useful to create beans with two levels of complexity. These extra methods are not bean-related, but allow you to treat the bean as any other Java object for more benefits or advanced functionality.

Mixing scriptlets and bean tags

195

Not all of your methods need to follow the bean conventions, although only those methods that can be found by introspection will be made available through the bean container. It is sometimes useful to provide basic functionality accessible through the bean container, such as JSP tags, and more advanced functionality only accessible through scriptlets or direct programmer intervention.

Removing a bean when done with it At the end of a beans life span, which is determined by its scope, all references to the bean will be removed and it will become eligible for garbage collection. Beans in the page or request scopes are automatically reclaimed at the end of the HTTP request, but session and application beans can live on. The life of a session bean is, as discussed, dependent on the JSP container while the application scope is tied to the life of the server. There are several situations where you might want to prematurely end the life of a bean. The first involves removing it from memory for performance reasons. When you have no more use for the bean, especially one in session or application scope, it s a good idea to get rid of it. Eliminating unused bean objects will improve the performance of your server-side applications by freeing as many of the JVMs resources as soon as possible. Another reason you want to remove a bean is to eliminate it from the users session for security reasons. A good example of this would be removing a users login information from the session when the user has specifically advised that they are logging off. A typical approach to user authentication with JSP is to place the users login credentials into the session following a successful login. The presence of these credentials in the session satisfies the login requirements for future visits to protected pages until the session expires. For security reasons however it is desirable to offer the visitor the ability to eliminate their login information from the session when they have completed their visit. We can accomplish this by simply removing their credentials from the session, returning them to their unauthenticated state. The methods available to you are summarized in table 8.4.
Table 8.4 Discarding a used bean from various scopes

Scope
session request/page application

Scriptlet
session.removeAttribute(name) pageContext.removeAttribute(name) application.removeAttribute(name)

Servlet
HttpSession.removeAttribute(name) ServletRequest.removeAttribute(name) ServletContext.removeAttribute(name)

196

CHAPTER 8

Developing JSP components

The request bean As discussed in previous chapters, JSP defines a number of implicit objects that reflect information about the environment. The request object encapsulates information about the request and has several properties that are accessible through the bean tags. Like other beans, we can access the properties of the request objects through <jsp:getProperty>. The id value assigned to the implicit request object is, as you probably guessed, request. For example, we can display the remote user name as follows:
<jsp:getProperty name="request" property="remoteUser"/>

Table 8.5 summarizes some of the more useful methods of the request object, which can be exposed as properties to the bean tags.
Table 8.5 Properties of the request bean

Name
authType method

Access
read read

Use
Gets the authentication scheme of this request or null if unknown. Same as the CGI variable AUTH_TYPE Gets the HTTP method (for example, GET, POST, PUT) with which this request was made. Same as the CGI variable
REQUEST_METHOD

pathInfo

read

Gets any optional extra path information following the servlet path of this requests URI, but immediately preceding its query string. Same as the CGI variable PATH_INFO Gets any optional extra path information following the servlet path of this requests URI, but immediately preceding its query string, and translates it to a real path. Same as the CGI variable PATH_TRANSLATED Gets any query string that is part of the HTTP request URI Same as the CGI variable QUERY_STRING Gets the name of the user making this request. The user name is set with HTTP authentication. Whether the user name will continue to be sent with each subsequent communication is browser-dependent. Same as the CGI variable REMOTE_USER Gets the URI corresponding to the original request Gets the character set encoding for the input of this request Gets the Internet media type of the request entity data, or null if not known. Same as the CGI variable CONTENT_TYPE Gets the protocol and version of the request as a string of the form <protocol>/<major version>.<minor version>. Same as the CGI variable SERVER_PROTOCOL

pathTranslated

read

queryString remoteUser

read read

requestURI characterEncoding contentType protocol

read read read read

Mixing scriptlets and bean tags

197

Table 8.5

Properties of the request bean (continued)

Name
remoteAddr serverName serverPort scheme remoteHost

Access
read read read read read

Use
Gets the IP address of the agent that sent the request. Same as the CGI variable REMOTE_ADDR Gets the host name of the server that received the request. Same as the CGI variable SERVER_NAME Gets the port number on which this request was received. Same as the CGI variable SERVER_PORT Gets the scheme of the URL used in this request, for example http, https, or ftp Gets the fully qualified host name of the agent that sent the request. Same as the CGI variable REMOTE_HOST

Working with databases

This chapter covers


I I

The link between Javas JDBC API and JSP Storing and retrieving JSP Beans with an RDBMS system Displaying database results with JSP Maintaining persistent connections

I I

198

JSP and JDBC

199

While long a bastion of large, well-funded enterprises, databases have found their way into a much wider range of web sites in recent years. Along with their traditional role as back office data sources, most large-scale web sites employ databases for at least some portion of the content. Ad management, users registration information, community services, and contact lists are just some of the features commonly managed through a database. JSPs and relational databases make a good combination. The relational database gives us the organizational capabilities and the performance necessary to manage large amounts of dynamic data, while JSP gives us a convenient way to present it. By combining the power of a relational database with the flexibility of JSP for content presentation and front-end design you can quickly develop rich, interactive web applications.

9.1

JSP and JDBC


Unlike other web scripting languages such as ColdFusion, Server Side JavaScript, and PHP, JSP does not define its own set of tags for database access. Rather than develop yet another mechanism for database access, the designers of JSP chose to leverage Javas powerful, popular, database APIJDBC. When a JSP application needs to communicate with a database, it does so through a vendor-provided driver class written to the JDBC API. Accessing a database in JSP then is nothing new; it sticks to this tried and true workhorse from Sun. In practice, as well learn in chapter 10, well often isolate database access inside a servlet or a Bean, keeping the details hidden from the presentation aspects of the JSP page. Both of these approaches are illustrated in figure 9.1 Learning JDBC is beyond the scope of this book, and a wealth of valuable information already exists on the topic. If you arent familiar with Javas JDBC API, a number of online tutorials can be found on Sun s JDBC web site, http:// java.sun.com/products/jdbc. Check online or at your favorite bookstore if you need more information. In this chapter we ll focus instead on the relationship between JSP and JDBC.
NOTE

The JDBC classes are part of the java.sql package, which must be imported into any Java class from which you wish to access JDBC, including your JSP pages. Additional, optional extensions for the 2.0 version of the JDBC API can be found in the javax.sql package, if it is installed on your system. If your JDBC driver is not in your JSP containers class path, you will have to either import it into your page or refer to it through its fully qualified class name.

200

CHAPTER 9

Working with databases

Request

Request

JSP

Servlet

JSP

Database access directly from a JSP page

JDBC driver JDBC API

Database access handled by a servlet; results passed to JSP page

Database

Figure 9.1

Database access options in JSP

9.1.1 JNDI and data sources


In ColdFusion and other template/scripting systems you access a database through a single identifier that corresponds to a preconfigured database connection (or connection pool) assigned by the systems administrator. This allows you to eliminate database connection information from your code, referring to your database sources by a logical name such as EmployeeDB or SalesDatabase. The details of connecting to the database are not exposed to your code. If a new driver class becomes available, the database server moves, or the login information changes, only the resource description needs to be reconfigured. Any components or code referencing this named resource will not have to be touched. JSP does not define its own database resource management system; instead you can rely on JDBC 2.0s Datasource interface and Java Naming and Directory Interface (JNDI) technology for naming and location services. JNDI can be used to shield your application code from the database details such as the driver class, the username, password, and connection URI. To create a database connection with JNDI, specify a resource name which corresponds to an entry in a database or naming service, and receive the information necessary to establish a connection with your database. This shields your JSP code and supporting components from changes to the databases configuration. More information on using JNDI is available from Sun, at http:/ /java.sun.com/products/jndi. Heres an example of creating a connection from a data source defined in the JNDI registry:

JSP and JDBC

201

Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("jdbc/SalesDB"); Connection con = ds.getConnection("username", "password");

We can further improve upon this abstraction, and further simplify database access, through custom tags, which use JNDI to allow simple access to named database resources in a manner familiar to ColdFusion and other tag-style languages.

9.1.2 Prepared statements


Prepared statements allow us to develop a Structured Query Language (SQL) query template that we can reuse to handle similar requests with different values between each execution. Essentially we create the query, which can be any sort of SQL statement, leaving any variable values undefined. We can then specify values for our undefined elements before executing the query, and repeat as necessary. Prepared statements are created from a Connection object, just like regular Statement objects. In the SQL, replace any variable values with a question mark.
String query = "SELECT * FROM GAME_RECORDS WHERE SCORE > ? AND TEAM = ?"; PreparedStatement statement = connection.prepareStatement(query);

Before we can execute the statement we must specify a value for all of our missing parameters. The PreparedStatement object supports a number of methods, each tied to setting a value of a specific typeint, long, String, and so forth. Each method takes two arguments, an index value indicating which missing parameter you are specifying, and the value itself. The first parameter has an index value of 1 (not 0) so to specify a query that selects all high scores > 10,000 for the Gold team we use the following statements to set the values and execute the query:
statement.setInt(1, 10000); // Score statement.setString(2, "Gold"); // Team ResultSet results = statement.executeQuery();

Once you have defined a prepared statement you can reuse it simply by changing parameters, as needed. There is no need to create a new prepared statement instance as long as the basic query is unchanged. So, we can execute several queries without having to create a statement object. We can even share a single prepared statement among an applications components or a servlets users. When using prepared statements, the RDBMS engine has to parse the SQL statement only once, rather than again and again with each new request. This results in more efficient database operations. Not only is this more efficient in terms of database access, object creation, and memory allocation but the resulting code is cleaner and more easily understood.

202

CHAPTER 9

Working with databases

Consider this example again, but this time the queries are not hard coded, but come from a bean, userBean, which has been initialized from an input form.
statement.setInt(1, userBean.getScore()); // Score statement.setString(2, userBean.getTeam()); // Team ResultSet results = statement.execute();

The alternative is to build each SQL statement from strings, which can quickly get confusing, especially with complex queries. Consider the following example again, this time without the benefit of a prepared statement:
Statement statement = connection.getStatement(); String query = "SELECT * FROM GAME_RECORDS WHERE SCORE > " + userBean.getScore() + " AND TEAM = " + userBean.getTeam() + ""; ResultSet results = Statement.executeQuery(query);

Another, perhaps even more important, benefit of using prepared statements is evidenced here. When you insert a value into a prepared statement with one of its setter methods you do not have to worry about proper quoting of strings, escaping of special characters, and conversions of dates and other values into the proper format for your particular database. This is particularly important for JSPs that are likely to be collecting search terms input directly from users through form elements and are particularly vulnerable to special characters and unpredictable input. Since each database might have its own formatting peculiarities, especially for dates, using prepared statements can help further distance your code from dealing with any one particular database.

9.2

Database driven JSPs


There are a number of ways to develop database driven applications through JSP. In this chapter, were concentrating on the database interaction itself, and less on program architecture. JSP application design will be covered in chapter 10 and again in chapter 11 which will feature a walk-through example of a database driven JSP project.

9.2.1 Creating JSP components from table data


You may have recognized a similarity between the tables of a relational database and simple JavaBean components. When building your applications think of tables as being analogous to JavaBeans. While JavaBeans have properties, data from a table has columns. A tables schema is like the class that defines a JavaBeandefining the names and types data that instances will hold. Like Java classes, tables are templates

Database driven JSPs

203

for storing a specific set of information like the data from a purchase order or details about inventory items and by themselves are not particularly useful. It is only when we create instances of a JavaBean class or add rows to a table that we have something worthwhile. Each row is an instance of what the table represents, just as a bean is an instance of its class. Both classes and tables then serve as data models, a useful container for managing information about some real world object or event. Keep this relationship in mind as we learn about JSP database development. It will form the basis for many of our applications. One of the most common areas for utilizing databases with JSP applications is to retrieve data stored in a table to create a bean for use within the page. The configuration of JSP components from information in the database is pretty straightforward if your table schema (or the results of a join between tables) closely corresponds to your beans properties. We simply use the row access methods of the ResultSet class to configure the beans properties with the values in the tables corresponding columns. If there is more than a single row in the result set we must create a collection of beans, one for each row of the results.

Database beans from scriptlets You can use JSP scriptlets to configure a beans properties when it is created. After establishing the connection, set its properties as appropriate through the data carried in the ResultSet. Dont forget to import the java.sql package into the page with the <%@ page import=java.sql.* %> directive. In this example we will use an ItemBean class used to represent a particular item from inventory, taking the item number from the request object.
<%@ page import="java.sql.*" %> <jsp:useBean id="item" class="ItemBean"> <% Connection connection = null; Statement statement = null; ResultSet results = null; ItemBean item = new ItemBean(); try { Class.forName("oracle.jdbc.driver.OracleDriver"); String url = "jdbc:oracle:oci8@dbserver"; String id = request.getParameter(id); String query = "SELECT * FROM PRODUCTS_TABLE WHERE ITEM_ID = " + id; connection = DriverManager.getConnection(url, "scott", "tiger"); statement = connection.createStatement(); results = statement.executeQuery(query); if (results.next()) { item.setId(results.getInt("ITEM_ID")); item.setDesc(results.getString("DESCRIPTION"));

204

CHAPTER 9

Working with databases

item.setPrice(results.getDouble("PRICE")); item.setStock(results.getInt("QTY_AVAILABLE")); } connection.close(); } catch (ClassNotFoundException e) { System.err.println("Could not load database driver!"); } catch (SQLException e) { System.err.println("Could not connect to the database!"); } finally { try { if (connection != null) connection.close(); } catch (SQLException e) { } } %> </jsp:useBean> <html> <body> <table> <tr><td>Item Number</td><td> <jsp:getProperty name="item" property="i