[ Team LiB ]
•
Table of Contents
•
Index
Sams Teach Yourself JavaServer Pages™ in 21 Days By Steven Holzner
Publisher: Sams Publishing Date Published
: September 24, 2002
ISBN: 0-672-32449-0 Pages: 720
Sams Teach Yourself JavaServer Pages in 21 Days offers a proven tutorial format to teach JSP in 21 example-driven lessons. While many competing JSP books are aimed at Java professionals, this book addresses the needs of the growing number of Web publishing professionals migrating to JavaServer Pages for its ability to create dynamic, interactive Web sites and separate presentation from Java code running behind the scenes. The book starts by explaining the relationship between JSP and Java Servlets and the basics of JSP functions and features. Readers then learn how JSP handles data, interacts with Java components, tracks users, and more. Later chapters discuss debugging, working with databases, XSLT and XML, using the Struts framework from Apache, handling binary data like graphics, and deploying JSP applications. Each topic is illustrated with many working examples that the reader can understand and put to work immediately. Throughout the book the author provides pointers to upcoming developments in JSP 1.3, due in 2003, to ensure readers are prepared for changes in the new version. [ Team LiB ]
[ Team LiB ]
•
Table of Contents
•
Index
Sams Teach Yourself JavaServer Pages™ in 21 Days By Steven Holzner
Publisher: Sams Publishing Date Published
: September 24, 2002
ISBN: 0-672-32449-0 Pages: 720
Copyright About the Author Acknowledgments We Want to Hear from You! Introduction Who Is This Book For? What's Inside? What Do You Need? Where to Download the Code for This Book Conventions Used in This Book A Note From the Author Week 1. At a Glance Day 1. Getting Started! What Are JavaServer Pages Good For? It All Starts with Java The Tomcat Server Creating Web Documents A Brief History of JSP Dissecting Our First JSP
Overview of JSP Syntax Online JSP Resources Summary Q&A Workshop Day 2. Handling Data and Operators Java in JSP The JSP Programming Environment Handling Data in JSP Creating Variables Initializing Variables Data Types Converting Between Data Types Strings Creating Strings Strings Are Objects Determining String Length Creating and Working with Arrays Working with Operators Assignment Operators Incrementing and Decrementing Operators Multiplication and Division Operators Addition and Subtraction Operators Relational Operators Logical Operators Understanding Operator Precedence Summary Q&A Workshop Day 3. Branching, Looping, and Creating Methods Branching Statements Loops Creating Methods Summary Q&A Workshop Day 4. Reading Data from Web Pages: Buttons and Text Fields HTML Controls HTML Forms Submitting Forms Sending Data to the Server Using
request
Objects
Reading Data on the Server
Using Text Fields Using Text Areas Using Password Controls Using Hidden Controls Using Buttons JSP to JSP—Navigating Directly to JSP Pages Using Multiple Forms Summary Q&A Workshop Day 5. Reading Data from Web Pages: Check Boxes, Radio Buttons, and Select Controls Using Check Boxes Using Radio Buttons Selecting and Deselecting Check Boxes and Radio Buttons in Code Using Select Controls Using Multiple-Selection Select Controls Check Box Groups Uploading Files Image Controls Using
Creating Image Maps Using Named Targets Getting All Parameter Names Getting Request Header Information Reset Buttons Summary Q&A Workshop Day 6. Creating JSP Components: JavaBeans Creating a Java Class Creating a Constructor Creating a Method Compiling a Java Class Installing a Compiled Java Class Using a Compiled Java Class Creating a Package Using a Package Passing Data to a Constructor Using
Creating a Read-Only Property
:
Getting a Property Value
Creating a Read/Write Property
: Setting Property Values Creating Private Methods
Java Utility Classes: Working with Dates Summary Q&A Workshop Day 7. Tracking Users with Sessions and Cookies Using Hidden Controls The Cookie Class The
HttpServletResponse Interface
Creating a Cookie Reading a Cookie Setting and Reading a Cookie in the Same Page Using Sessions Creating a Session Setting Session Timeouts Using Applications Using Sessions, Applications, and JavaBeans Summary Q&A Workshop
Week 2. At a Glance Day 8. Handling Errors Syntax Errors Runtime Errors Exceptions Using
try/catch Blocks
Handling Specific Exception Types Catching Multiple Exceptions Nesting
try/catch
Statements
Throwing Exceptions Yourself Throwing Exceptions from Methods Creating a Custom Exception Object Printing to the Server Console Using Log Files Using JSP Error Pages
exception Object request Object Attributes
Using JSP Error Pages: The Using JSP Error Pages: Summary Q&A Workshop
Day 9. Using Custom JSP Tags Tag Libraries The
Request
Tag Library
Tag Library Descriptor Files Creating a Simple Tag Summary Q&A Workshop Day 10. Creating Custom Tags A Simple Text-Inserting Tag Creating and Supporting Attributes in Custom Tags Iterating Tags Cooperating Tags Using Scripting Variables Summary Q&A Workshop Day 11. Creating More Powerful JavaBeans Why Inheritance? Using Inheritance Using Access Specifiers Calling Superclass Constructors Overloading Methods Overriding Methods Using Superclass Variables with Subclassed Objects Using Runtime Polymorphism Creating Abstract Classes Using Interfaces for Multiple Inheritance Summary Q&A Workshop Day 12. Creating Servlets Using
Creating Java Servlets
response Object the request Object
Using the Using
The Life Cycle of a Servlet Creating Web Applications with Servlets Using Servlet Configurations and Contexts Summary Q&A Workshop Day 13. Creating More Powerful Servlets Sessions and Servlet Contexts Forwarding Requests to Other Web Resources
Including Output from Other Web Resources Handling Forwards and Includes JSP Model 1 Architecture JSP Model 2 Architecture Supporting User Authentication Using Cookies in Servlets Thread Safety Summary Q&A Workshop Day 14. Using Filters Understanding Filters Creating a Simple Filter Filtering JSP Pages Creating Filter Chains Using Initialization Parameters Inserting Text Into the Response Logging Using Filters for User Authentication Restricting Access Summary Q&A Workshop
Week 3. At a Glance Day 15. Handling Files on the Server Using Tomcat Logging Using the
File Class
Streams, Readers, and Writers Working with Text Files Writing Text Files Reading Text Files Working with Binary Files Writing Byte Data to Files Reading Byte Data from Files Writing Objects to Files Reading Objects from Files Summary Q&A Workshop Day 16. Getting Started with Databases What Are Databases? Java Database Connectivity
JDBC Drivers Creating Connections Using Structured Query Language Summary Q&A Workshop Day 17. Working with Databases Data Lookup
ResultSet Methods Navigating in a RecordSet The
Setting Cursor Type Getting Information About a Result Set Joining Tables Creating and Filling Tables Updating Data Summary Q&A Workshop Day 18. Using XML and XSLT in JSP Handling XML with JSP Sending XML Data to the Browser Java and XML DOM XML Parsing SAX XML Parsing Handling XSLT with JSP Summary Q&A Workshop Day 19. Using Struts Putting Struts to Work Getting Struts Creating the View Creating Custom Tags to Supply Data Creating the Controller Adapter Accessing Data in the Results Page Creating the Model Summary Q&A Workshop Day 20. Creating Images on the Fly and Handling Internet Programming Creating an Image on the Fly Drawing in Response to User Actions
Drawing Images Embedding Images in HTML Documents Internet Programming—Interacting Directly with Servers Creating Client/Server Applications Summary Q&A Workshop Day 21. Client-Side Programming and Deploying Your Projects Working with JavaScript Creating a
Element
Creating Variables JavaScript Operators Branching Statements JavaScript Loops JavaScript Functions Handling Events in JavaScript Deploying Your Web Applications Summary Q&A Workshop
Week Appendixes At a Glance Appendix A. Answers to the Quiz Questions Quiz Answers for Day 1 Quiz Answers for Day 2 Quiz Answers for Day 3 Quiz Answers for Day 4 Quiz Answers for Day 5 Quiz Answers for Day 6 Quiz Answers for Day 7 Quiz Answers for Day 8 Quiz Answers for Day 9 Quiz Answers for Day 10 Quiz Answers for Day 11 Quiz Answers for Day 12 Quiz Answers for Day 13 Quiz Answers for Day 14 Quiz Answers for Day 15 Quiz Answers for Day 16 Quiz Answers for Day 17 Quiz Answers for Day 18 Quiz Answers for Day 19 Quiz Answers for Day 20 Quiz Answers for Day 21
Index
[ Team LiB ]
[ Team LiB ]
Copyright Copyright ©2003 by Sams Publishing All rights reserved. No part of this book shall be reproduced, stored in a retrieval system, or transmitted by any means, electronic, mechanical, photo copying, recording, or otherwise, without written permission from the publisher. No patent liability is assumed with respect to the use of the information contained herein. Although every precaution has been taken in the preparation of this book, the publisher and author assume no responsibility for errors or omissions. Neither is any liability assumed for damages resulting from the use of the information contained herein. For information, address Sams Publishing, 201 W. 103rd Street, Indianapolis, IN 46290. Library of Congress Catalog Number: 2002106119 Printed in the United States of America First Printing: September 2002 05 04 03 02 4 3 2 1
Trademarks All terms mentioned in this book that are known to be trademarks or service marks have been appropriately capitalized. Sams Publishing cannot attest to the accuracy of this information. Use of a term in this book should not be regarded as affecting the validity of any trademark or servicemark.
Warning and Disclaimer Every effort has been made to make this book as complete and as accurate as possible, but no warranty or fitness is implied. The information provided is on an "as is" basis. The author and the publisher shall have neither liability nor responsibility to any person or entity with respect to any loss or damages arising from the information contained in this.
Credits Executive Editor Michael Stephens Managing Editor Charlotte Clapp
Acquisitions Editor Todd Green Development Editor Songlin Qiu Project Editor Matthew Purcell Copy Editors Seth Kerney Lindsey Rue Indexer Johnna Dinse Proofreader Bob LaRoche Technical Editors Matthew Wilson Christian Kenyeres Team Coordinator Lynne Williams Interior Designer Gary Adair Cover Designer Aren Howell Page Layout Julie Parks Graphics Tammy Graham Oliver Jackson
Dedication To Nancy, as always and forever (for all the reasons she already knows!). [ Team LiB ]
[ Team LiB ]
About the Author Steven Holzner is the author of more than 70 books on programming, and has been writing on Java topics ever since Java has been around. His books have sold more than 1.5 million copies and have been translated into 16 languages around the world. He has a Ph.D. from Cornell University, has been on the faculty of both Cornell and MIT, and is a former contributing editor to PC Magazine. He's long used JSP in commercial environments, and specializes in Web development. [ Team LiB ]
[ Team LiB ]
Acknowledgments A book like the one you're reading is the product of many people's hard work. I'd especially like to thank Todd Green, the acquisitions editor, Songlin Qiu, the development editor, Matt Purcell, the project editor, Seth Kerney, the copy editor, and Matt and Christian, the tech editors. Special thanks to the whole team for being extra helpful during our interstate move! [ Team LiB ]
[ Team LiB ]
We Want to Hear from You! As the reader of this book, you are our most important critic and commentator. We value your opinion and want to know what we're doing right, what we could do better, what areas you'd like to see us publish in, and any other words of wisdom you're willing to pass our way. As an Executive Editor for Sams Publishing, I welcome your comments. You can email or write me directly to let me know what you did or didn't like about this book—as well as what we can do to make our books better. Please note that I cannot help you with technical problems related to the topic of this book. We do have a User Services group, however, where I will forward specific technical questions related to the book. When you write, please be sure to include this book's title and author as well as your name, email address, and phone number. I will carefully review your comments and share them with the author and editors who worked on the book. Email:
[email protected]
Mail:
Michael Stephens Sams Publishing 201 West 103rd Street Indianapolis, IN 46290 USA
For more information about this book or another Sams title, visit our Web site at www.samspublishing.com. Type the ISBN (excluding hyphens) or the title of a book in the Search field to find the page you're looking for. [ Team LiB ]
[ Team LiB ]
Introduction Welcome to Sams Teach Yourself JavaServer Pages in 21 Days! This book is designed to be as comprehensive—and as accessible—as it is possible for a single book on JavaServer Pages (JSP) to be. It puts JSP to work in depth, pushing the envelope as far as it can go. The best way to learn any topic like JSP is by example, and this is an example-oriented book. You'll find nearly 200 tested examples here, ready to be used. Few topics are gaining popularity as fast as JSP these days. Web page authors are demanding more and more power, and JSP is the perfect answer. Not content to simply handle Web pages in browsers any more, people are turning to the server side to do things you just can't do in a browser. Using JSP, you have total control over your Web applications—and the big bonus of JSP is that that doesn't mean it's any harder to write those applications than it is a typical Web page. You can do a lot with a little. JSP is a dazzling package, and you're getting into it at the right time—when the excitement level is high and new developments appear almost daily. This book tries to be true to that spirit and capture as much of the excitement and power of JSP as possible. And you'll see more JSP here than in any comparable book, doing things you won't see other places, such as drawing JPEG images on the fly in the server and then sending them back to the browser. [ Team LiB ]
[ Team LiB ]
Who Is This Book For? This book is for you if you want to really develop all the power that Web applications are capable of. What you'll see here lets you take control of the server side of things. If you want to start using cookies instead of just having your browser accept them, if you want to handle buttons, text fields, check boxes and more in your Web pages, if you want to track users with sessions, or connect to a database on the server, then this is the book for you. This book is specially written so that you don't need a lot of experience to use it. You don't need to know Java, for example—you'll learn all the Java you need to use JSP in this book, introduced carefully, step by step. The only requirement to read this book is that you're familiar with HTML (and you don't need to be an expert). [ Team LiB ]
[ Team LiB ]
What's Inside? This book is filled with examples—almost 200 of them—because seeing a working example is the best way to learn this material; there's nothing like seeing it work for yourself. You'll see how to put it all to work yourself—here are just a few included topics: Reading data from a Web page's text fields, radio buttons, check boxes, and list boxes on the server Creating and handling image maps Tracking users with sessions and cookies Writing data to files on the server (such as guest books) Recovering from errors without crashing Creating JavaBeans and using them with JSP Connecting to databases on the server Using SQL to work with databases Drawing JPEG images and sending them back to the browser Creating custom JSP tags Using the Struts framework to build applications Writing Java servlets Handling the Model-View-Controller architecture Interacting with XML and XSLT from JSP Writing your own mini-Web server to interact with JSP Intercepting JSP actions with filters Deploying your Web applications using WAR files Creating client/server applications with JavaScript and JSP The complete JSP syntax You'll also see a summary at the end of each day's work, as well as additional questions and answers, a self-guided quiz, and exercises designed to help hone your skills.
[ Team LiB ]
[ Team LiB ]
What Do You Need? All you need to read this book is some knowledge of HTML. You don't need to know Java, or anything about server-side programming. You'll get all the material you need right here. As far as software goes, you'll see where to download the Tomcat server (the most popular JSP host) used to host the examples in this book at no cost. You'll see how to use Tomcat on your own computer—no Internet access is even needed to be able to run the examples in this book. You can develop and test your JSP pages all on the samecomputer. All you need to do is to download and install the Tomcat server (it's an easy installation, and not intrusive like some big software packages). You'll also need Java (version 1.4 is used in this book), and this book shows you where to get Java (also free). Day 19 puts the Struts application framework to work, and you'll see where to download Struts at no cost. There's no special installation involved here except unzipping a few files. Days 16 and 17 show how to connect your JSP code to databases, and the examples use Microsoft's SQL Server, but note that you don't have to have that database system to follow along—the Java Database Connectivity (JDBC) techniques you'll see are applicable to any SQL database system (and you'll see where to get such a database system for free on the Internet). You don't need Internet access to learn JSP from this book. However, if you want to put your JSP code on the Internet, you'll need to use an ISP that supports JSP. Check with your ISP to find if they support JSP—more and more ISPs are doing so every day. [ Team LiB ]
[ Team LiB ]
Where to Download the Code for This Book The code in this book is available for download on the Sams Publishing Web site at http://www.samspublishing.com/. Enter this book's ISBN (without the hyphens) in the Search box and click Search. When the book's title is displayed, click the title to go to a page where you can download the code. All the code examples have been tested both by the author and two tech editors on different machines. Installing the examples so that Tomcat can run them is very easy—take a look at the readme.txt file that comes with the downloadable code. [ Team LiB ]
[ Team LiB ]
Conventions Used in This Book The following conventions are used in this book: Code lines, commands, statements, variables, and any text you type or see onscreen appears in a monospace typeface. Italics highlight technical terms when they're being defined. The book contains Notes, Tips, and Cautions to help you spot important or useful information more quickly. These often include shortcuts to help you work more efficiently. When introducing new syntax, this book uses the same conventions that both JSP and Java documentation use, for consistency with those sources. In particular, | means "or," + means "one or more of," items in bold are default settings, items in italics are placeholders that you fill in later, items in square brackets—[ and ]— are optional, and you must select one item of those that appear in curly braces, { and }. Here's an example:
| > other elements }
Also, when an example is being developed step by step, you'll see the newly added section of code displayed using shaded text to distinguish it from what's already there, like this:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("In ch14_01."); chain.doFilter(request, response); System.out.println("Leaving ch14_01."); . . . }
The three dots arranged vertically indicate that more code is coming. [ Team LiB ]
[ Team LiB ]
A Note From the Author This book is designed to be at the top of its field. If you have comments, please write to me, care of Sams Publishing. This book is designed to be the new standard in JavaServer Pages programming, more complete and more accessible than ever before. Please do keep in touch with ways to improve it and keep it at the forefront. If you think the book lacks anything, let me know—I'll add it in a future printing, because I want to make sure this book stays on top. And that's it, you're ready to go. Happy programming! [ Team LiB ]
[ Team LiB ]
Week 1: At a Glance 1 Getting Started! 2 Handling Data and Operators 3 Branching, Looping, and Creating Methods 4 Reading Data from Web Pages: Buttons and Text Fields 5 Reading Data from Web Pages: Check Boxes, Radio Buttons, and Select Controls 6 Creating JSP Components: JavaBeans 7 Tracking Users With Sessions and Cookies [ Team LiB ]
[ Team LiB ]
Day 1. Getting Started! Welcome to JavaServer Pages (JSP)! Over the next 21 days, you'll get an in-depth guided tour of the ins and outs of JSP. From the most basic aspects to the most advanced, we're going to become masters of JSP in this book. You've come to the right place. If you want to do Web programming on the server, there's just nothing like JSP. It's easy to get started with JSP, and because it has the incredible power of Java behind it, there's no limit to how far you can go. Traditionally, server programming was a task only for experts, but with JSP, that's all in the past—now anyone can make Web pages come alive as never before. Let's dig into JSP immediately. In this, our first day on the job, we're going to take a look at these topics: What JavaServer Pages can help you do Setting up your development environment Running the Tomcat Server How we got here: from HTML to JSP Building and dissecting your first JSPs Understanding JSP syntax JSP resources online We're going to work with JavaServer Pages 1.2 in this book, but as you'll find, JSP itself is only the beginning. Because JSP lets you use Java to create Web pages on the server, much of what we're going to study is Java itself, as we see what we can do with JSP. And you'll find there's practically no limit. [ Team LiB ]
[ Team LiB ]
What Are JavaServer Pages Good For? Take a look at Figure 1.1, which shows the home page of Delta Airlines. Note the URL at the top of the browser: http://www.delta.com/home/index.jsp. The JSP in the index.jsp portion is the JSP in JavaServer Pages.
Figure 1.1. The Delta Airlines home page.
It's easy to find JSP at work everywhere on the Web these days. In fact, JSP is becoming the new standard for easily developed, easily maintained Web applications. As you might expect, there are many, many reasons for JSP's soaring popularity, and more are being invented all the time. Here are a couple of things that JSP can do for your Web pages—this is just a starter list, of course: Making Web pages come alive— There are too many static pages on the Internet already. Why add yours to the list? To get noticed, your page must be live—it must do something, or offer some service. What better way to liven pages up yourself than to use JSP? Now your Web pages can interact with the user in real time. Getting data from the user— All the text fields, radio buttons, check boxes, and so on, you see in Web pages can hold data. JSP makes it easy to read that data back to the server, and to send Web pages that use that data back to the browser, as we'll see in Day 4, "Reading Data from Web Pages: Buttons and Fields," and Day 5, "Reading Data from Web Pages: Check Boxes, Radio Buttons, and Select Controls." Easier to program— There are plenty of server-side programming options out there, but none easier to program than JSP. In fact, JSP is specifically designed to be easy to program, as you'll see today.
More power through Java— JSP lets you run Java code when creating Web pages. That fact alone makes what you can do with JSP practically boundless. Java is an ever-expanding, nearly endless programming package, and JSP puts it at your service. And you don't have to be a Java expert either—you can start small, as we will in this book, building up to whatever level you want. Connecting to databases— One of the most popular things you can do with JSP on the server is connect to databases via Java. It's not as hard as you might think, and we'll see how to connect to databases, add our own data to them, get data out of them, and more in this book. Performance— JSP is built to perform better than other server-side programming packages. JSP is built right into the server software itself, which means that many users can access your Web page without using a lot of extra memory or degrading performance. In some other server-side programming packages, a whole new process has to start for every user that accesses your Web page, and if a lot of users are downloading that page, it can bring the server to a virtual halt. Separating code and data— A very big topic in the programming world these days is the separation of code and data, and JSP fits right into that. The idea is that when your JSP programming code that the server runs is separate from the data that that code works on, it's easier to write and maintain your programs. As we'll see in this book, there are some new ways of working with JSP that let you separate code and data very effectively. Handling cookies— A popular use of JSP is to work with cookies, storing information on the user's machine. Some people love cookies, some hate them, but there's no doubt that JSP allows you to use them. Want to record a user's special settings for your Web page? A JSP cookie will do that. You'll see how to work with cookies in Day 7, "Tracking Users with Sessions and Cookies." In choosing JSP, you've chosen the right package for server-side programming. You can do startlingly powerful things with JSP, because JSP has the full power of Java behind it on the server. For example, take a look at Figure 1.2, which shows an example we'll develop later in the book (in Day 20, "Creating Images on the Server and Handling Internet Programming," where you'll learn how to create and draw images using Java). In this case, the user can "draw" a line in the browser using the mouse, and the software we'll develop for the server will actually create the corresponding image file (a JPEG file) and send that image back to the browser, as you see in the figure. That's a JPEG image file you're looking at in the figure, created interactively with Java on the server thanks to JSP.
Figure 1.2. Creating a JPEG image file.
Let's get down to business by setting up your own development environment in which to create and use JSP ourselves. This development environment will give you a JSP server and allow you to develop your own JSP-enabled Web pages. All the software you'll need is free, and you can download it from various sites on the Web. [ Team LiB ]
[ Team LiB ]
It All Starts with Java The J in JSP is for the Java programming language, and we're going to need Java to run JSP. If you already have access to a Web server that runs Java and JSP, congratulations—you're all set. On the other hand, if you don't yet have access to such a server, or want to develop your JSP code offline on your own computer, we can set up our own development environment. The first thing to install is Java itself, which the Web server will need to access to run your JSP code. Java is a product of Sun Microsystems, and you can download it for free from its Web site. We're going to use Java 2 Standard Edition; the current version is 1.4. (That might be different when you read this, however—you should get the latest version of the Java 2 Standard Edition SDK, the Software Development Kit.) Here are the URLs you'll need: http://java.sun.com/j2se/— The home page for Java 2 Standard Edition. Go here to see your download options for Java. http://java.sun.com/j2se/1.4/download.html— The current download page for Java 1.4. You can also download the Java documentation here, which is a good idea.
Caution Allow some time to download Java—the executable installation file is 20–36MB large, depending on what operating system you're using.
The installation instructions are online (you can view them from the download page). Typically, you run a self-extracting executable file, such as j2sdk-1_4_0-win.exe in Windows, or j2re-1_4_0solx86.sh for the Solaris operating system. After you follow the installation instructions, you'll have Java installed. [ Team LiB ]
[ Team LiB ]
The Tomcat Server Now that you've installed Java, you're halfway there. The next step in creating your JSP development environment is to install a JSP-enabled Web server on your computer. There's nothing complex in this, although the idea of installing a Web server on your computer can sound a little daunting. There are a number of JSP-enabled Web servers, and we'll use the one that's become the JSP standard: the Apache project's Tomcat server. This server is the standard throughout the JSP world, and it's the one Sun uses when creating its JSP implementation. You can download the Tomcat server at http://jakarta.apache.org/tomcat/ ("Jakarta" is the name of the project that Tomcat is a part of). We'll use the most recent Tomcat version available as of this writing, version 4.0.3, which supports JSP version 1.2. Currently, you can download this version from http://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/v4.0.3/bin/. Just pick the appropriate version for your system, such as jakarta-tomcat-4.0.3.zip for Windows, and unzip it in a directory of your choosing.
Note In this book, the Zip file will be copied to the Windows directory C:\tomcat and unzipped there, which creates the directory C:\tomcat\jakarta-tomcat-4.0.3, and plenty of subdirectories underneath it. You might want to use the same directory structure to make it easier to follow the examples we'll develop (substitute / for \ in Unix).
That installs Tomcat—now let's take a look at what we've got.
The Tomcat Directory Structure A great deal of this book has to do with understanding how the standard JSP server, Tomcat, works. For the sake of reference—so you can come back to this information as you progress through the book—here's the directory structure that unzipping Tomcat creates (the "classes" here refer to Java classes; for Java code to be accessible, it must be in a class, and you're going to see more about classes in Day 6, "Creating JSP Components: JavaBeans"): jakarta-tomcat-4.0.3 |__bin |__classes |__common
Binary executable files Classes available to all Web applications Classes available to internal classes and Web applications
| |__classes | |__lib |__conf |__jasper |__lib |__logs |__server |__webapps |__work
Common Java classes Common Java classes in Java Archive (JAR) format Configuration files (such as passwords) JAR files used to process and run JSP pages JAR files available to Web applications The server's log files Internal Tomcat classes Directory for Web applications Scratch directory for holding temporary files
We'll get more familiar with this directory structure when we start using it in depth in the coming days. Note in particular the webapps directory, which is where the Web applications you create go so they're accessible to the browser. For instance, the examples from Day 1 will go into the ch01 directory we'll add to webapps:
webapps |__ch01
Our folder for Day 1 examples
The directory containing Web applications must also contain a directory named WEB-INF, with two subdirectories, classes and lib. WEB-INF, classes, and lib might all be empty, but Tomcat will expect them to be there before running your application:
webapps |__ch01 |__WEB-INF |__classes |__lib
Our folder for Day 1 examples Information about Day 1's Web applications Java classes used by Day 1's Web applications JAR files used by Day 1's Web applications
We'll create the ch01, WEB-INF, classes, and lib directories we need in a moment, but first, let's start Tomcat itself.
Note There will be plenty of path specifications in this book, such as jakarta-tomcat4.0.3\webapps\ch01 in Windows, or jakarta-tomcat-4.0.3/webapps/ch01 in Unix. If you're using Windows and you see forward slashes (/) in a path, it's a Unix path—just substitute backslashes (\) instead, and vice versa if you're a Unix user who sees forward slashes. The Tomcat directory structure is the same on all operating systems, except for operating system-dependent syntax, like using \ instead of /.
Starting Tomcat When you start Tomcat, you must first set a few environment variables. Among other things, these environment variables will let Tomcat find Java so it can run our JSP code.
Tip You can get the details on these environment variables by taking a look at the readme.txt document that comes with Tomcat, which will refer you to the document running.txt. It's also available online at http://jakarta.apache.org/tomcat/tomcat-4.0-doc/RUNNING.txt.
In particular, the environment variables to set are the following: JAVA_HOME points to the installation directory of Java; for example, that might be C:\jdk1.4 in Windows. CATALINA_HOME points to the installation directory of Tomcat; for example, C:\tomcat\jakarta-tomcat-4.0.3 (you get this path when you unzip Tomcat 4.0.3 in C:\tomcat). PATH holds the search path the computer's operating system will search for programs to run. Make sure you add Java's bin directory to your path—for example, you would add C:\jdk1.4\bin to the path if Java was installed to C:\jdk1.4. The way you actually set these variables varies by operating system. For example, to set JAVA_HOME to C:\jdk1.4 in Windows 2000 Professional, you can select Start, Settings, Control Panel to open the control panel, and double-click the System icon in the control panel. Next, click the Advanced tab as you see in Figure 1.3. Doing so opens the Environment Variables dialog box; click the New button in the System Variables part, opening the New System Variable dialog you see in Figure 1.4.
Figure 1.3. The Advanced tab in the System Properties dialog in Windows 2000 Professional.
Figure 1.4. Setting an environment variable in Windows 2000 Professional.
You can enter the new setting for JAVA_HOME as you see in Figure 1.4: C:\jdk1.4. To change the PATH variable, which already exists, you click the Edit button in the System Variables section and edit the PATH variable to add the Java bin directory to it. For example, if your path looks something like this:
C:\WINDOWS;C:\Program Files
you'd add a semicolon and the path of the Java bin directory:
C:\WINDOWS;C:\Program Files;C:\jdk1.4\bin
How you set environment variables depends on the operating system, however; for example, the process is completely different in Windows 95/98, where you must edit the C:\autoexec.bat file instead.
Tip You can find excellent instructions on setting environment variables for all the operating systems that run Java from the Java download page, in the installation notes. Here's the URL with links for various operating systems: http://java.sun.com/j2se/1.4/installoperatingsystemname.html (for example, for Windows, the URL is http://java.sun.com/j2se/1.4/install-windows.html). These notes are all about setting the PATH environment variable, but you can use them to set any environment variable.
You can also set the environment variables when you start Tomcat itself, and you might find that more convenient. You'll find the directions for starting Tomcat in the running.txt document that comes with Tomcat. To start Tomcat, you'll need a command prompt. In Windows, that's the DOS prompt, which you get in a DOS window. You can open a DOS window by selecting Start, Programs, Accessories, Command Prompt in Windows 2000 Professional; Start, Programs, MS-DOS Prompt in Windows 98, and so on. To set the environment variables (if you haven't set them already), you can type the following at the DOS prompt. (Make the version numbers and paths match what you have installed, of course. )
C:\>SET JAVA_HOME=C:\jdk1.4 C:\>SET CATALINA_HOME=C:\tomcat\jakarta-tomcat-4.0.3 C:\>SET PATH=%PATH%;C:\jdk1.4\bin
Note the last statement, SET PATH=%PATH%;C:\jdk1.4\bin, which is an easy way of adding C:\jdk1.4\bin to the end of the path, without making any changes to the rest of the path. In the Unix bash shell, this might look something like this in your .bashrc file (start a new shell to make the changes take effect):
JAVA_HOME=/jdk1.4 export JAVA_HOME SET CATALINA_HOME=/tomcat/jakarta-tomcat-4.0.3 export CATALINA_HOME SET PATH=/usr/local/bin:/jdk1.4/bin export PATH
In the Unix tcsh shell, it might look like this in your .tcshrc file (start a new shell to make the changes take effect):
setenv JAVA_HOME /jdk1.4 setenv CATALINA_HOME /tomcat/jakarta-tomcat-4.0.3 setenv PATH /usr/local/bin:/jdk1.4/bin
After these environment variables are set, we're ready to start Tomcat. Again, this process is operating system-dependent; see the Tomcat document running.txt for more details. In Windows, go to the Tomcat bin directory (the bin directory is right under the directory that Tomcat unzips itself to, such as C:\tomcat\jakarta-tomcat-4.0.3\bin if Tomcat was unzipped in C:\tomcat) and type startup:
C:\tomcat\jakarta-tomcat-4.0.3\bin\>startup
In Unix, that command might look like this:
/tomcat/jakarta-tomcat-4.0.3/bin/startup.sh
That's it—now Tomcat is running. In Windows, you'll see a new DOS window open and a message similar to this appear:
Starting service Tomcat-Apache Apache Tomcat/4.0.3
Don't close this new window—that's where Tomcat is running. So how do we put Tomcat to work? You'll need a browser, such as Microsoft Internet Explorer (which you can pick up free at http://www.microsoft.com/windows/ie/default.asp), or Netscape Navigator (free at http://browsers.netscape.com/browsers/main.tmpl). Run the browser now and enter the URL http://localhost:8080/index.html, which should bring up the page you see in Figure 1.5.
Figure 1.5. Running the Tomcat server.
As the figure says, congratulations—now you're running your own Web server. Note the URL we've used—http://localhost:8080/index.html. The localhost part is the name of the Web server, and localhost is the name reserved for Web servers running on your own machine. 8080 is the port number. Each Web server uses a "port" number to keep it separate from other Web servers. Usually, Web servers use port 80, but Tomcat uses port 8080 so it won't interfere with other Web servers.
Tip If Tomcat doesn't run for you, see the Troubleshooting section in the running.txt document that comes with Tomcat.
To stop Tomcat, you use the shutdown command. It looks something like this in Windows:
C:\tomcat\jakarta-tomcat-4.0.3\bin\>shutdown
and this in Unix:
/tomcat/jakarta-tomcat-4.0.3/bin/shutdown.sh
That's our first step—getting Tomcat itself running. We've already made progress—now let's see whether we can display some of our own pages using this server.
[ Team LiB ]
[ Team LiB ]
Creating Web Documents Throughout this book, we'll be creating our own documents—HTML documents, Java documents, JSP documents, and so on. That means that we'll need an editor that can save plain text files as part of our development environment. You can use any editor or even word processor you like, such as WordPad in Windows, or vi (or even pico) in Unix. The main point here is that you must save the files you create in plain text format (not, for example, rich text format, which is the default for some versions of WordPad). For example, you can see how to use WordPad to create a Web page named ch01_01.html (that is, Example 1 from Day 1) in Figure 1.6. When you save it, use the File, Save As menu item, and select the Text Document item in the Save As Type box of the Save As dialog box that appears. We'll see how to open this new HTML document in Tomcat later in this Day.
Figure 1.6. Creating a Web page.
Tip When we develop JSP-enabled pages, we'll give them the extension .jsp, like index.jsp. When you save a file with the extension .jsp in WordPad, it'll try to add the extension .txt because it doesn't know about the .jsp extension, giving you index.jsp.txt. To avoid this, put quotation marks around the name of the file when you save it—if you save the file as "index.jsp", you'll get the file index.jsp, not index.jsp.txt.
You can find the HTML page created in Figure 1.6 in Listing 1.1.
Listing 1.1 A Simple Web Page (ch01_01.html) A Web Page Hello there!
Where can you save this document so you can view it with Tomcat? In this book, it'll be easiest to store the examples from Day 1 in a directory named ch01, the examples from Day 2 in ch02, and so on. Those directories are subdirectories of the webapps directory in the Tomcat directory structure:
jakarta-tomcat-4.0.3 |__webapps |__ch01 |__ch02 |__ch03 . . .
Create the ch01 directory now—for example, you can use the Windows Explorer in Windows for this purpose. We'll also need a WEB-INF directory under ch01, as well as classes and lib subdirectories (even though they're empty):
jakarta-tomcat-4.0.3 |__webapps |__ch01 |__WEB-INF |__classes |__lib |__ch02 |__WEB-INF |__classes |__lib
Create this directory structure for ch01 now, and save the first example, ch01_01.html, in ch01 (that is, in jakarta-tomcat-4.0.3\webapps\ch01 in Windows, or jakarta-tomcat-4.0.3/webapps/ch01 in Unix). What's the URL of our new document? If we had put it into the webapps directory itself, it would be http://localhost:8080/ch01_01.html, but because we've placed it in the webapps\ch01 directory, its URL is http://localhost:8080/ch01/ch01_01.html. Enter that URL into the browser now, and you should see the result in Figure 1.7.
Figure 1.7. Viewing a new document in Tomcat.
And that's it—now our development environment is complete. We've got Java, we've got a JSP server, we've got a browser, and we've got an editor with which to write our Web documents (alternatively, you could just download the source code for this book and use that). Not bad—we've made a great deal of progress. Now we're ready to start working up to JSP itself. And to do that, it's a good idea to start by taking a look at the history of JSP. [ Team LiB ]
[ Team LiB ]
A Brief History of JSP To understand JSP, you have to understand where JSP came from. The Web started with HTML, and JSP's history starts there, too, so the first step is to take a look at HTML.
HTML The pages into which we embed our JSP are Hypertext Markup Language (HTML) pages. (This book assumes you are already familiar with HTML.) HTML is a specification of the World Wide Web Consortium (W3C), and you can find the official home page for HTML at http://www.w3.org/MarkUp. The current version of HTML is 4.01, and you can find HTML's official specification at http://www.w3.org/TR/html4/.
Tip If you want to brush up on HTML, there are many resources on the Internet. Here's a good one that lists all HTML tags and attributes by browser version and what they do: http://www.willcam.com/cmat/html/tags.html.
We've already seen our first HTML example, ch01_01.html; that example didn't do anything except support a title for the page and display the text Hello there!:
A Web Page Hello there!
That's okay as far as it goes, but it doesn't go very far. This page is very static, and Web developers wanted more as the Web became more and more popular. At first, client-side programming became popular, using script languages like JavaScript.
JavaScript Despite the name, JavaScript is not related to Java. It actually began in 1995, when a Netscape Communications Corporation developer named Brendan Eich was given a new project to work on. The original idea was to give Netscape Navigator something extra; Eich took a look around and decided that what was needed was a scripting language that was fast and easy to use. He called his creation LiveScript, but it was renamed JavaScript (although developed by Netscape, Sun had the trademarks on Java, so, interestingly, the name JavaScript is actually a trademark of Sun Microsystems). The new language was announced in a joint press conference with Netscape and Sun on December 4, 1995. Unlike JSP, which is all about programming on the server, scripting languages like JavaScript are all about programming on the client side, in the browser. You enclose your JavaScript code in a element in an HTML page—for example, you can see how to use JavaScript to write the message Hello there! to a Web page while that page is being loaded in Listing 1.2.
Listing 1.2 Using JavaScript (ch01_02.html) A Web Page
This creates the same results as we saw for our HTML page in Figure 1.7, but now we're using JavaScript to write to the Web page. Client-side programming like this can be useful—you'll see that we can use JavaScript to pass data to JSP documents on the server—but it's extremely limited. As a result of security restrictions, for example, you can't access files from JavaScript. And because JavaScript has to be built into the browser, it has to be relatively small, and can't contain more than a small fraction of the power of a full programming language like Java. In fact, during all the time HTML and scripting languages like JavaScript were developing, so was Java.
Java Java wasn't originally created for the Internet. The first version was actually begun in 1991 and written in 18 months at Sun Microsystems. In fact, it wasn't even called Java in those days; it was
called Oak, and it was used internally at Sun. The original idea for Oak was to create an operating system-independent language. Many programmers were confining themselves to programming for the IBM PC at that time, but the corporate environment can include all kinds of programming platforms, from the PC to huge mainframes, and the inspiration behind Oak was to create something that could be used on all those computers. (Actually, the original inspiration for Oak was not what you'd call especially glamorous—Sun wanted to create a language it could use in consumer electronics. ) Oak was renamed Java in 1995 when it was released for public consumption, and as you probably know, it's become very popular. Even though it's not targeted at the Internet, you can still use it to display the message Hello there!; Listing 1.3 details a small Java application named ch01_03.java that does just that.
Listing 1.3 A Java Application (ch01_03.java) public class ch01_03 { public static void main(String[] args) { System.out.println("Hello there!"); } }
To run this example, you must compile ch01_03.java and create a Java .class file: ch01_03.class. The compilation process creates this .class file, which is what you need to run the program. You compile ch01_03.java with the Java compiler, which is named javac. If you've set up your path to include the Java bin directory as we saw earlier, you can use the javac command at the command prompt; here's how that might look in Windows (make sure you're in the same directory as ch01_03.java):
C:\>javac ch01_03.java
This creates ch01_03.class, which you can run with the Java tool, simply named java. Here's how that would look in Windows:
C:\>java ch01_03
You can see the results in Figure 1.8, where our Java application is displaying the message Hello there!
Figure 1.8. Running a Java application.
JSP is based on Java, and a lot of this book is about learning to use Java. Java's a big part of the Internet now because Sun couldn't ignore the Internet, and Java's first attempt at working with the Internet was to introduce applets.
Java Applets An applet is just a Java .class file that's specially written to display graphics in a Web browser; you embed applets in Web pages using the HTML element. When run in a Web page, Java applets are downloaded automatically and run by the browser, displaying themselves in the space you've allocated for them in the page. They can do anything from working with graphics and displaying animation to handling HTML text fields and buttons. Here's an example called ch01_04.java. The Java applet you see in Listing 1.4 displays our Hello there! message.
Listing 1.4 A Java Applet (ch01_04.java) import java.applet.Applet; import java.awt.*; public class ch01_04 extends Applet { public void paint(Graphics g) { g.drawString("Hello there!", 60, 100); } }
To use this applet, you must first compile it with javac:
C:\>javac ch01_04.java
This creates ch01_04.class, which you can use in the HTML element. Here's a sample Web page that does this by setting aside an area 200x200 pixels in which to display the applet in Listing 1.5.
Listing 1.5 Displaying an Applet (ch01_05.html) A Web Page
If you store the applet, ch01_04.class, and this Web page, ch01_05.html, in the webapps\ch01 directory, you can see the applet at work by navigating to http://localhost:8080/ch01/ch01_05.html, as you see in Figure 1.9.
Figure 1.9. Viewing an applet.
Applets can display text like this, along with buttons, and so on, but like JavaScript, they're very limited. In fact, their time is mostly past as new client-side applications like Flash take over; the standard version of the newest Netscape Navigator no longer even supports applets by default. But the Internet was still there to conquer. With the demise of applets, Java turned to the server side of things, and its first step in the server was to implement servlets.
Java Servlets Java servlets were the first real attempt to get access to the full power of Java in Web applications. Like applets, servlets are written completely in Java; you compile them into .class files, and—using servers like Tomcat that can support servlets—you can navigate directly to those .class files and view the results in a browser. In this way, a servlet can almost be thought of as an applet that runs on the server side (as the name servlet is meant to imply). Listing 1.6 shows a sample servlet, ch01_06.java, written in pure Java that will display our message.
Listing 1.6 A Java Servlet (ch01_06.java) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ch01_06 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println(""); out.println(""); out.println(""); out.println("A Web Page"); out.println(""); out.println(""); out.println("Hello there!"); out.println(""); out.println(""); } }
Compiling ch01_06.java into ch01_06.class takes an additional step we haven't seen before. Much
of the support for servlets is not built into the core of Java, but is stored in a Java Archive (JAR) file named servlet.jar, which stores many specialized .class files internally. Tomcat comes with servlet.jar (located in the jakarta-tomcat-4.0.3\common\lib directory), and to access it, we have to set the CLASSPATH environment variable, which is specific to Java. As you might expect from the name, CLASSPATH indicates where Java can look for the .class files it needs when getting an application ready to run; we're using CLASSPATH because we need a number of servlet .class files stored in servlet.jar. Here's how you can set the CLASSPATH variable to include servlet.jar in Windows (change the path to servlet.jar as needed):
C:\>SET CLASSPATH=C:\tomcat\jakarta-tomcat-4.0.3\common\lib\servlet.jar
Now Java can find what it needs to compile servlets. You might have already set CLASSPATH to other locations, so if you just want to add servlet.jar to the CLASSPATH without affecting the rest of what's already in CLASSPATH, you can do the following in Windows (like other environment variables, you separate the locations and JAR filenames in the CLASSPATH variable with semicolons):
C:>set classpath=%CLASSPATH%;d:\tomcat\jakarta-tomcat-4.0.3\common\lib\servlet.jar
You'll see more on using and setting CLASSPATH in Day 11, "Creating More Powerful JavaBeans." Now that we have access to servlet.jar, navigate to the directory where our sample servlet ch01_06.java is located, and use javac to create ch01_06.class (this assumes javac is in your computer's path) :
C:\>javac ch01_06.java
Now transfer ch01_06.class to jakarta-tomcat-4.0.3\webapps\ch01\classes—note that we have to use the classes directory for Java classes like ch01_06.class. And that's it—all we have to do now is navigate to http://localhost:8080/ch01/servlet/ch01_06. You can see the results in Figure 1.10-note that it looks just like our original HTML document, but this time, we've created this Web page on the server.
Figure 1.10. Using a servlet.
Tip The servlet in http://localhost:8080/ch01/servlet/ch01_06 tells Tomcat that you're navigating to a servlet that it should run. We'll see how we can make some configuration changes that will allow us to omit that term in Day 13, "Creating More Powerful Servlets," making this URL simply http://localhost:8080/ch01/ch01_06.
Servlets are very powerful, but they're not easy to program. As a result, they haven't become very popular. But Java and the Internet was a match meant to be—and the next step is JSP.
JSP JSP is built on top of servlets, but JSP is much easier to program, and that's the whole point—that's why JSP has taken off. JSP, a specification of Sun Microsystems, first appeared in 1998. The official versions, 1.0 and 1.1, both appeared in 1999, and both were very popular. The current version, 1.2, appeared in 2001, and is the most popular implementation yet; this is the version we'll be using in this book. Internally, each JSP page is actually converted into a servlet by the server (we'll see exactly how that works in Day 13). In other words, this is really a book about servlets—but they're acting entirely behind the scenes.
Note We'll also see how to create servlets in this book for some added power—see Days 13 and 14.
From our point of view, JSP pages are simply HTML pages with embedded Java in them. And by using JSP, we avoid all the hassle of creating full-blown Java applications—the server will do all that for us, taking our Java snippets of code and compiling them for us automatically. It's clear that Sun had gotten the message about making things easy for the programmer when it came up with JSP, and we're the winners. Let's use JSP now to create the Web page we've already developed—you can see what it looks like in Listing 1.7, ch01_07.jsp (giving this document the extension .jsp means Tomcat will know that it is a JSP document and treat it accordingly):
Listing 1.7 A JSP Page (ch01_07.jsp) A Web Page
Notice how simple this is—it's just a simple HTML page, with the extra element . This element is called a scriptlet in JSP, and it encloses the Java we use to write the message Hello there! to the Web page. You can see the result by navigating to http://localhost:8080/ch01/ch01_07.jsp, as you see in Figure 1.11.
Figure 1.11. Our first JSP.
Tip As you probably know, a Web server will send the document named index.html to the browser if that document is present in the directory you navigate to on the server, and you don't specify any other document. Similarly, index.jsp is the default for JSP documents—Tomcat will send that to the browser if you don't specify any specific document otherwise. If both index.jsp and index.html are present, the server chooses index.html as the default.
And that's it—now we've created and run our first JSP! Let's see what makes it tick. [ Team LiB ]
[ Team LiB ]
Dissecting Our First JSP The crucial line in our first JSP is this one, where it uses some Java code:
A Web Page
The special JSP tags create a scriptlet, and we can enclose Java code in the scriplet. In this way, we're able to embed Java directly into our page's HTML. The actual Java we're using here is out.println("Hello there!"); (note the semicolon—all Java statements end with a semicolon). Here, we're using the out object to print Hello there! to the Web page before that page is sent back to the browser. A Java object like out contains all kinds of programming power for us. For example, here we're using the out object's println (which stands for "print line") method to write Hello there! to the Web page that is being sent to the browser. The methods of an object let you perform actions, such as writing text in a Web page. Besides methods, objects also support data members. You use data members to configure the object; for example, you can use the out.bufferSize data member of the out object to set the size of the internal buffer used in that object. You'll see more on objects, methods, and data members in Day 2, "Handling Data and Operators," and in detail in Day 6—all that's important right now is to know that in JSP, you can use the out object's println method to write text (including HTML!) to a Web page that is being sent back to the browser. The out object is one of the objects already built into JSP for our use. Note that in our servlet example, we had to create this object ourselves, using techniques we'll look at later in this book:
public class servlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println(""); . . .
In JSP, the out object is already created for us in order to make things easier, and in this example, we're using the println method to write text to the Web page being sent back to the browser. That's all there is to it. [ Team LiB ]
[ Team LiB ]
Overview of JSP Syntax Now that we're actually working with JSP, the next step is to get an overview of JSP itself, which means getting an overview of the JSP syntax. After we've gotten the components of JSP syntax down, everything else will fit into that framework. There are four different types of elements you can use in JSP: Scripting elements— This is where your Java goes, as in the scriptlets we've already seen. Comments— Comments are text you add to annotate a JSP document—they're like notes to yourself or other programmers. They're ignored by the Web server, and are only for programmers to read. Directives— Directives are instructions specific to a particular page that let you set how the page is to be processed. For example, you can use a directive to indicate that you want the output of a page to be XML, not HTML. Actions— Actions let you perform some operation, such as including other pages in the current page, or including Java applets, or working with JavaBean components (which you'll see in Day 6). Unlike directives, actions are re-evaluated each time the page is accessed. Let's take a look at these various types of JSP elements, starting with scripting elements.
Scripting Elements There are three types of scripting elements in JSP: Scriptlets— Scriptlets can contain Java code. This is the most general of all the scripting elements. Declarations— Declares a variable or a method for use in your code. Expressions— Contains a Java expression that the server evaluates. The result of the expression is inserted into the Web page.
Scriptlets The most general place for your Java code is in a scriptlet. Scriplets hold Java code fragments, and are enclosed with the tags . We've already seen an example of a scriptlet in our first JSP, where we used the Java statement out.println("Hello there!"); to display text in a Web page:
A Web Page
A scriptlet can hold any number of Java statements, declarations, or expressions, making scriptlets the most general of all the JSP scripting elements. Note that they must hold valid Java statements, so you can't include direct HTML in a scriptlet. Scriptlets are what many JSP programmers think of when they think of JSP. Scriptlets are used to embed Java code in HTML documents, turning them into JSP documents. But besides scriptlets, you can also use declarations and expressions.
Declarations As you'll see tomorrow, you can store data using variables in Java. For example, here's how you can store our text string Hello there! in a variable of type String: String msg = "Hello there!";
This declares a new variable named msg that holds the text Hello there!. In Java, you must declare variables before you use them, giving them a name. After you've named a variable, you can refer to it in your code using that name. There's a special set of tags, , that you can use to declare variables in JSP (you can also declare variables in scriptlets, which is a more common thing to do). Here's an example: In this case, the code declares the variable msg:
A Web Page
Now you can use this new variable in a scriptlet; for example, here's how you can display the text in msg in the Web page using the out.println method:
A Web Page
That's what the process looks like in overview; you'll get all the details on declaring and using variables in Day 2.
Expressions Expressions are any Java code fragment that can be evaluated to yield a value. For example, the expression 2 + 2 yields a value of 4, the expression 44 - 10 yields 34, and so on. In JSP, you can surround a Java expression in the tags . The expression's value is inserted into the Web page as text by the server. You can even use a variable as an expression—when such an expression is evaluated, it yields the value of the variable. For example, if we had stored our string Hello there! in a variable named msg, we can insert that string into the Web page simply by using the variable as an expression this way:
A Web Page
Expressions like this are similar to scriptlets, because you can place Java code in them, but they have to be able to result in a single value when they're evaluated. Expressions like this are useful for shorter JSP pages, but note that you don't have to use them to insert text into a Web page—you can use methods like out.println in scriptlets instead.
Comments You can use JSP comments to document what's going on in a JSP page; they act like notes to you or
other programmers. Comments are purely for the benefit of the programmers that work on the page, because the server will strip them out before sending the page back to the browser. You enclose the text in a comment between the tags . Here's an example; in this case, the code includes the comment Display the message now. to this JSP example:
A Web Page
This comment lets you and other programmers know what's going on in your JSP. You can add as many comments to a JSP as you like—they're entirely for the benefit of programmers, and will all be stripped out before the page is sent back to the browser.
Directives JSP directives let you give directions to the server on how a page should be processed. There are three directives in JSP; we'll see them throughout the book, but here's an overview: page— This directive lets you configure an entire JSP page, such as whether its output is HTML or XML. You'll see more on this directive in Day 6. include— This directive lets you include another page or resource in a JSP page. taglib— This directive lets you use a set of custom JSP tags as defined in a tag library. More on taglibs is coming up in Day 9, "Using Custom JSP Tags," and Day 10, Creating Custom Tags." The page directive is going to be a useful one for us as we work with Java. You can use this directive to configure the page you're working on. Like other directives, you use the special tags with this directive; to create a page directive, you also include the keyword page like this: .
Here's an example to show what the page directive can do for us. In this case, the code wants to indicate that if there's an error in the current page, the server should send an error page named error.jsp back to the browser; that we're programming in Java; that the output of the current page should be XML (not HTML, which is the default—more on XML in Day 18, "Using XML and XSLT in JSP"); and that we want to import the java.sql package so that our code can work with SQL databases. You'll see more on importing Java packages when we start working with Java in depth—Java is divided into many sections called packages, and to use a particular section's functionality, you must import the corresponding package, which makes it accessible to your code. You can do all that with attributes of a single page directive. In JSP, attributes work just as they do in HTML—they're part of an element's opening tag, and have the form attribute=value. Here's how you can use the errorPage, language, contentType, and import attributes of the page directive to configure the page as you want (note that the page directive comes at the very beginning of the page): . . .
As you can already see, the page directive is going to give us a lot of programming power. The include directive, which looks like , lets you include another page in the current page. When you include a page at a particular point, that page's entire contents are simply inserted at that point. The taglib directive (which looks like this: ) specifies a library of custom JSP tags (see Days 9 and 10) that you want to use in the current page. Tag libraries let you define your own JSP tags. We're going to see how to use this directive later, so we won't go into the details now.
Note There are rumors that scriptlets are going to be phased out in JSP 2.0 and tag libraries will be used instead, so it's a good idea to make sure you know what's going on with tag libraries in Days 9 and 10.
Actions
JSP also includes actions. As their name implies, actions let you perform some action. Unlike directives, actions are re-evaluated each time the page is accessed. There are two types of actions: custom and standard. Custom actions are actions you create yourself, and standard actions come built into JSP. Here are the standard actions in overview: — Forwards the browser request for a new Web page to an HTML file, JSP page, or servlet. In this way, you can delegate how your Web applications respond to the browser. — Includes a file or Web component. Note that is different than the include directive because it re-evaluates the included file every time the page is accessed, whereas the include directive does not. — Lets you execute applets or JavaBeans with a plug-in. If the browser doesn't have the required plug-in module, it will display a dialog box asking you to download it. We'll see this one in Day 13. , , and —, You use these actions with JavaBean components, as you'll see in Day 6. We'll get all the details on these standard actions when we put them to work in the coming days. And that's it—that completes our overview of JSP syntax. Now we've got the foundation we'll need to move on to Day 2. [ Team LiB ]
[ Team LiB ]
Online JSP Resources Our first day of JSP work will end by taking a look at some of the resources available to you online. These resources are available for free, and they're there to augment your JSP arsenal. Let's start with JSP itself: http://java.sun.com/products/jsp— JSP's official home page. http://java.sun.com/products/jsp/product.html— A useful overview of JSP from Sun. http://developer.java.sun.com/developer/technicalArticles/Programming/jsp/— A technical overview of JSP from Sun. http://java.sun.com/products/jsp/faq.html#techfaq— The official JSP Frequently Asked Questions (FAQ) list. http://java.sun.com/products/jsp/tags/12/syntaxref12.html— The JSP syntax guide online. http://archives.java.sun.com/archives/jsp-interest.html— An interactive JSP mailing list. http://java.sun.com/products/jsp/technical.html— Technical pages and documentation on JSP. http://java.sun.com/webservices/docs/ea1/tutorial/doc/JSPTags.html— Creating custom tags in JSP. http://www.jspinsider.com/index.view— You'll find lots of JSP resources here. Here's a starter list of online JSP tutorials: http://java.sun.com/products/jsp/docs.html— Sun's QuickStart guides to JSP; a good tutorial. http://java.sun.com/webservices/docs/ea2/tutorial/doc/JSPIntro.html— A Sun JSP tutorial. http://www.apl.jhu.edu/~hall/java/Servlet-Tutorial/— A tutorial on servlets and JSP. http://www.jsptut.com/— A JSP tutorial site. http://www.jspinsider.com/content/rcarnes/jspb_intro.view— The JSP Insider's tutorial. http://java.sun.com/products/jsp/tutorial/TagLibrariesTOC.html— A tag library tutorial.
And here are some JSP tools available online (note that they're not necessarily free, however) : http://jakarta.apache.org/jmeter/— Apache's online performance meter, which can help test JSP performance. http://www.macromedia.com/software/ultradev/— An authoring environment for JSP applications. http://www-4.ibm.com/software/webservers/studio/— IBM's WebSphere Studio, which lets you create JSP applications. Even though you can also find Java 1.4 documentation online or download it, here are a few good URLs to know: http://java.sun.com/j2se/1.4/— The Java 1.4 home page. http://java.sun.com/j2se/1.4/docs/index.html— The online Java 1.4 documentation. http://java.sun.com/j2se/1.4/download.html— Downloadable Java documentation. http://jakarta.apache.org/tomcat/tomcat-4.0-doc/servletapi/index.html— Servlet and JSP Java object documentation; a good one to have. These are also installed with Tomcat on your hard disk—take a look at jakarta-tomcat-4.0.3\webapps\tomcatdocs\servletapi\index.html. http://java.sun.com/docs/books/tutorial/index.html— A Java tutorial from Sun. There's also some Tomcat documentation available: http://jakarta.apache.org/tomcat/— The Tomcat home page. http://java.sun.com/products/jsp/tomcat/— Sun's page on Tomcat. http://java.sun.com/products/jsp/tomcat/faq.html— The Tomcat FAQ. http://jakarta.apache.org/tomcat/tomcat-4.0-doc/index.html— The Tomcat documentation online. Also installed on your hard disk when you install Tomcat; take a look at jakarta-tomcat-4.0.3\webapps\tomcat-docs\index.html. http://jakarta.apache.org/tomcat/tomcat-4.0-doc/RUNNING.txt— The running.txt document that covers how to run Tomcat. Also included in the Tomcat download. As you can see, there are a great number of online resources available on JSP—take a look!
Note No JSP groups have appeared on Usenet (yet). Even so, the comp.lang.java groups (like comp.lang.java.help, comp.lang.java.databases, and so on) can offer a lot of Java
help.
[ Team LiB ]
[ Team LiB ]
Summary In our first day working with JSP, we've come far. We've gotten an idea of what JSP is good for, and how it's used. We've seen that JSP gives us the power of Java on the Web server, which is an incomparable asset. We've also taken a look at where JSP came from, and how it developed. We've seen that as the Web has evolved, Java has been a part of the picture—first with applets, then servlets, and now JSP. Applets were nice, but limited; servlets are very powerful but complex. JSP gives us the best of both worlds: They're both very powerful (they're converted to servlets before they're run) and easy to write. You've also installed the Tomcat server and gotten it running, and built the development environment (Java, Tomcat, browser, and an editor) you'll be using in the coming days. We've also developed and run our first JSP. Instead of having to write everything in Java, we were able to simply insert the Java we wanted into an HTML page. That's the whole genius of JSP—you use an HTML backbone and just add the Java you need. As we've also seen, JSP offers a whole set of built-in objects, which means we can get away with even less Java because we don't have to create those objects ourselves. We also took a look at the JSP syntax in overview here—some of which might not have made a great deal of sense yet. (But don't worry, that's why this is Day 1—it's all coming up in depth in the next days.) And that's it—we've started our in-depth guided tour of JSP, and built the foundation we'll need in the coming days. Tomorrow, you'll see more details, such as how to work with data and operators in JSP, and you'll start writing some real code. [ Team LiB ]
[ Team LiB ]
Q&A Q1:
Do I have to use the Tomcat server? Aren't there any other JSP-enabled Web servers out there?
A1:
There sure are—take a look at http://klomp.org/gnujsp/ and http://www.caucho.com/ for some other JSP Web servers.
Q2:
How can I find out whether my Internet service provider supports JSP?
A2:
The best way is simply to ask your ISP's tech support. If they don't support JSP, suggest to them that they consider it—tell them that JSP is growing all the time and that other users will soon be asking. Many of the larger commercial Web servers offer some kind of JSP support these days.
[ Team LiB ]
[ Team LiB ]
Workshop This workshop tests whether you understand all the concepts you learned today. It is very helpful to know and understand the answers before starting tomorrow's lesson. You can find the answers to the quiz questions in Appendix A.
Quiz 1:
Can you trace the development of JSP from HTML pages as you saw today? Knowing this history will help explain a great deal when it comes to working with servlets later in the book.
2:
What are the four different types of JSP elements discussed today?
3:
How many different types of scripting elements are there in JSP? What are they?
4:
What are the tags you use for the three different types of JSP scripting elements?
5:
What are the three JSP directive types?
Exercises 1:
Take a look at the JSP resources given in the topic "Online JSP Resources" and either bookmark or download your favorites. Compiling a list of ready resources like that can be a big help in your JSP development. You might even want to try a few of the JSP tutorials.
2:
Use the JSP expression in a welcome message in a new JSP page. This expression will insert the current date and time, permitting you to customize your welcome page.
[ Team LiB ]
[ Team LiB ]
Day 2. Handling Data and Operators Welcome to Day 2! Today, you'll see how to get down to the brass tacks of JSP programming as we see how to work with and handle data in JSP. Working with data is the very heart of programming, and it's our logical first step. In fact, the capability to work with and handle data is what separates JSP from static HTML—and we have the full power of Java behind us when we work with data in JSP. We're also going to see how to use operators to work with data today. Operators enable you to perform simple mathematical operations on your data. For example, to add 2 and 5, you can use the + operator in Java, so the Java expression 2 + 5 results in the value 7. (In this operation, 2 is the first operand, + is the operator, and 5 is the second operand.) You're going to see how to perform all kinds of math with operators today. Here's an overview of today's topics: The JSP programming environment Handling data Creating variables and arrays Working with strings Using operators Understanding operator precedence Now that we're digging into real programming in JavaServer Pages, the first thing to note is that we are indeed dealing with Java. You'll see what that means next. [ Team LiB ]
[ Team LiB ]
Java in JSP Note the word Java in JavaServer Pages. Java itself is a very large programming language, but you don't have to be a Java expert to use this book, or even know it at all—we're going to cover what we need. But you should know that Java programming is a huge topic, and we're not going to have space to cover it all here. There are thick multiple-volume book sets on Java containing thousands of pages that don't cover Java programming completely—and because this is a book about JSP, it's clear we're not going to be able to cover all of Java here, either. If you press on in JSP programming, you might want to pick up a good book on Java programming. You can also find the complete Java documentation online, as well as Java tutorials—see the "Online JSP Resources" topic in Day 1, "Getting Started!". Fortunately, you don't need a great deal of Java prowess to be able to build extremely powerful JSP applications, as you'll see. The basics are very simple—Java code is broken up into statements, each of which must end in a semicolon, like this one: Creating a Greeting Creating a Greeting
A statement, in turn, can be made up of expressions, and we've already seen what an expression is—it's a set of terms (2 + 2, for example) that Java can evaluate to yield some value (such as 4 here). What's important to remember about expressions is that they can be evaluated to yield a value in Java. You can also comment your Java code using the Java // comment marker, which makes Java ignore all the rest of the text on a line. As with JSP comments, Java comments are meant as notes to yourself or other programmers explaining what's going on in the code, as you can see in Listing 2.1.
Listing 2.1 Using Comments (ch02_01.jsp)
Creating a Greeting Creating a Greeting
//Display the greeting
If this were a book on Java programming, we'd have to cover a great many more details before writing any code, such as how to create Java classes, and so on, which you need just to get started. We're lucky in that this is a book on JSP, where those background details are taken care of for us—as we're going to see. We just need to use the Java code that we'll actually want to execute; no extras that Java would normally need to set the stage. That's because JSP already sets the stage for us, as we'll discuss next. [ Team LiB ]
[ Team LiB ]
The JSP Programming Environment When you create a pure-Java Web application, like a servlet, you need to set up a Java class and perform all kinds of other work just to get started. That's not necessary in JSP—you just put the actual Java statements you want to execute into scriptlets, and you're set. The JSP server does the rest, creating a full servlet for you automatically. In fact, JSP even does more for us—we've already seen that JSP comes with a built-in Java object named out, which we can use to send text to a Web page. There are a number of built-in objects like out already set for us to use in JSP pages, and we'll list them here for reference. Each of these objects is created from a Java class (we'll see how to create Java classes ourselves in Day 6, "Creating JSP Components: JavaBeans"). Here, you'll see which Java class each built-in object is created from, so that if you want to find out more about any object, you can check the Java documentation (see http://java.sun.com/j2se/1.4/docs/index.html for the online documentation, or http://java.sun.com/j2se/1.4/download.html to download it). Note that there's no need to read the Java documentation directly—these objects are covered in detail in the coming days. Here's a list of the built-in JSP objects; it'll be hard to appreciate this list right now, but it's good to have for later reference: application— Holds data for the current Web application (see Day 7, "Tracking Users with Sessions and Cookies"). This is an object of the Java javax.servlet.http.HttpSession class. config— Holds configuration data like passwords. This is an object of the Java javax.servlet.ServletConfig class. exception— Lets you handle errors (see Day 8, "Handling Errors"). This is an object of the Java java.lang.Throwable class. out— The object you use to send text to a Web page. This is an object of the Java javax.servlet.jsp.JspWriter class. page— Gives you access to the current JSP page's underlying servlet (see Day 6). This is an object of the Java javax.servlet.jsp.HttpJspPage class. pageContext— Holds data from the JSP page's underlying servlet (see Day 10, "Creating Custom Tags"). This is an object of the Java javax.servlet.jsp.PageContext class. request— Holds data sent to you from the browser (see Day 4, "Reading Data from Web Pages: Buttons and Text Fields"). This is an object of the Java javax.servlet.http.HttpServletRequest class. response— Holds data you are sending back to the browser (see Day 7). This is an object of the Java javax.servlet.http.HttpServletResponse class. session— Holds data about the current session (see Day 7). This is an object of the Java
javax.servlet.http.HttpSession class. We're going to introduce and use these objects as we need them. Today, you're only going to use the out object. We've seen that object has a method named println, which you can use to send text to a Web page. For example, here's how we print "Hello from JSP!" to a Web page:
out.println("Hello from JSP!");
In this case, we're passing the text string "Hello from JSP!" to the println method so it can print that text to the Web page. When you invoke a method like this, you call it, so the appropriate terminology here is what we're calling the println method and passing the text string "Hello from JSP!" to it. Besides println, there are other methods available in the out object, and you can see them all in Table 2.1. You pass different types of data to these various methods, and the type of data you can pass is indicated in that table. We're going to see all these data types today—for example, this entry in Table 2.1
println(char x);
means that you can pass an individual character (such as 'a' or 'x') to the println method. Note that the print and println methods in Table 2.1 have multiple versions with the same name that take different data types. This means you can call the same method with different types of data—for example, you can pass a single character to the println method, or a String object (as we'll see today), or a floating point value, and so on, as indicated in Table 2.1.
Tip Here's something useful to know about the println method—because its name means "print line," you might think it'll write output to a Web page and then skip to the next line. In fact, the output only skips to the next line when you're writing plain-text files. Although that lets you format the text in your HTML files nicely, when the browser displays that HTML, it will ignore the attempt to skip to the next line. If you want to skip to the next line in the browser, make sure you print the HTML to do that, such as using a element (for example, out.println("");). Note that the out object also has a print method, which doesn't skip to the next line after printing its text.
Table 2.1. Methods of the out Object
Method
Does This
clear()
Clears all internal data in the object.
clearBuffer()
Clears the contents of the internal data buffer.
close()
Closes the output "stream," which is the stream of data going to the Web page.
flush()
Flushes the output stream, sending any data in it to the Web page.
getBufferSize()
Gets the size of the internal data buffer.
getRemaining()
Gets the number of unused bytes in the data buffer.
isAutoFlush()
Indicates if out autoflushes, which means it writes its data out fully each time you write.
newLine()
Skips to the next line in plain text files.
print(boolean b)
Prints a Boolean value.
print(char c)
Prints a character.
print(char[] s)
Prints an array of characters.
print(double d)
Prints a double-precision floating-point number.
print(float f)
Prints a floating-point number.
print(int i)
Prints an integer.
print(long l)
Prints a long integer.
print(java.lang.Object obj)
Prints an object.
print(java.lang.String s)
Prints a string.
println()
Skips to the next line in plain text files.
println(boolean x)
Prints a Boolean value and then skips to the next line in plain text files.
println(char x)
Prints a character and then skips to the next line in plain text files.
println(char[] x)
Prints an array of characters and then skips to the next line in plain text files.
println(double x)
Prints a double-precision floating-point number and then skips to the next line in plain text files.
println(float x)
Prints a floating-point number and then skips to the next line in plain text files.
println(int x)
Prints an integer and then skips to the next line in plain text files.
println(long x)
Prints a long integer and then skips to the next line in plain text files.
Method
Does This
println(java.lang.Object x)
Prints an Object and then skips to the next line in plain text files.
println(java.lang.String x)
Prints a String and then skips to the next line in plain text files.
[ Team LiB ]
[ Team LiB ]
Handling Data in JSP When you handle data values directly into your code, they're called literals in Java. For example, in the code in Listing 2.2, a string literal ("Number of days = ") is passed to println first, and an integer literal (365) second.
Listing 2.2 Using Literals (ch02_02.jsp) Using a Literal Using a Literal
This code displays those literals, as you see in Figure 2.1.
Figure 2.1. Using a literal in Java.
You can't work with or change the value of literals in your code, so Java also has variables. [ Team LiB ]
[ Team LiB ]
Creating Variables Variables come in different types and serve as placeholders in memory for data. The different types have to do with the format the data is stored in, and how much memory is set aside to hold that data. For example, an integer variable type, the int type, is made up of four bytes, or 32 bits, and you use it to store integer values. This gives the data in the int type a substantial range of possible values from 2,147,483,648 to 2,147,483,647. There are quite a few different variable types built into Java, such as integers, floating-point numbers, and individual characters, which we'll see today. Before you use a variable in Java, you must declare it, specifying its data type. Here's how you declare variables: type is the type of variable (like int), name is the name of the variable (that must start with a letter and can only contain letters, numbers, and/or underscores), and value is the value you want to store in the variable (remember that term is in square brackets, [] and is optional). type name [= value][, name [= value]...];
Let's see how this works; here's an example showing how to declare a variable of the int type, which means you can store an integer in it. This variable is named days, like the following:
int days;
Now you can assign a value to this variable, which stores the integer 365 in days:
int days; days = 365;
Now days holds 365, as you can see in Listing 2.3. Here, the code is using the + operator to join the value in days to the text "Number of days = "—you'll see more on joining text together like this later today.
Listing 2.3 Creating Variables (ch02_03.jsp) Creating a Variable
Creating a Variable
You can see the results of this code in Figure 2.2.
Figure 2.2. Creating a variable.
As we know, you can also declare variables in declaration scripting elements, enclosed in this way:
Creating a Variable Creating a Variable
[ Team LiB ]
[ Team LiB ]
Initializing Variables You can also store a value in a variable when you declare it, which is called initializing the variable. You can do that by using an = sign, called the assignment operator in Java, like this: Creating a Variable Creating a Variable
In this case, the code is assigning a value of 365 to days at the same time that the variable is declared, which is a handy shortcut. [ Team LiB ]
[ Team LiB ]
Data Types The int type is only one kind of simple variable that you can use. Here are the possibilities in overview: Integers— These types are: byte, short, int, and long, which hold signed, whole-value numbers. Floating-point numbers— These types are: float and double, which hold signed floating-point numbers. Characters— This is the char type, which holds representations of characters such as letters and numbers. Boolean— This type is designed to hold only two types of values: true and false. You can see these types in more depth in Table 2.2.
Table 2.2. Data Types Type
Bytes Used
boolean 2
Range true, false
byte
1
–128–127
char
2
N/A
double
8
–1.79769313486232E308 to –4.94065645841247E-324 for negative values, and from 4.94065645841247E-324 to 1.79769313486232E308 for positive values
float
4
–3.402823E38 to –1.401298E-45 for negative values, and from 1.401298E-45 to 3.402823E38 for positive values
int
4
–2,147,483,648 to 2,147,483,647
long
8
–9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
short
2
–32,768 to 32,767
For example, the double type holds "double-precision" floating-point numbers, which you can use to store floating-point numbers with greater precision than with the ordinary floating-point type, float. Here's how you can declare a double variable named pi to hold the value of pi to 10 decimal places:
Creating a Variable Creating a Variable
[ Team LiB ]
[ Team LiB ]
Converting Between Data Types Java is a strongly typed language, which means you have to be careful when trying to mix data types. For example, say that you have a float variable, float1, and a double variable, double1. Double-precision variables can hold values with greater precision than simple float variables, so if you try to assign the value in double1 to float1, Java realizes there might be a loss in precision, and will cause an error. This means that Java will not run this code: Mixing Data Types Mixing Data Types
In cases like this, you need to convert between data types. There are two ways you can do that—using automatic type conversion, or doing the type conversion yourself.
Automatic Conversions When you're assigning one type of data to a variable of another type, Java will convert the data to the new variable type automatically. For example, you can assign a float value to a double variable, because double variables have a larger range than float values, so no data will be lost in the type conversion. You can see an example in Listing 2.4.
Listing 2.4 Automatic Data Conversions (ch02_04.jsp) An Automatic Data Conversion
An Automatic Data Conversion
Java will have no problem with this code, as you see in Figure 2.3. These types of conversions, where you convert to a data type with a larger range, are called widening conversions.
Figure 2.3. An automatic data conversion.
Performing Type Conversions If you're assigning a data value to a variable of a type that has a larger range than the variable you're assigning it to, which is called a narrowing conversion, the Java compiler will not perform narrowing conversions automatically, because there is the possibility that precision will be lost. If you want to perform a narrowing conversion, you must use an explicit type cast.
A type cast lets you convert between data types. For example, in the code you see in Listing 2.5, the code is converting double1 from type double to type float with the Java type cast (float) and assigning the result to float1.
Listing 2.5 Casting to a New Data Type (ch02_05.jsp) Casting to a New Type Casting to a New Type
Without the explicit type cast, Java would object, but with the type cast, there's no problem. Java decides what you know about the possibility of losing some data when you cram a possibly larger value into a smaller type, and are taking responsibility for the results. You can see the results in Figure 2.4.
Figure 2.4. Using a type cast.
Note For information on converting text strings to numbers and vice versa, see "Using Named Targets" in Day 5, "Reading Data from Web Pages: Check Boxes, Radio Buttons, and Select Controls."
[ Team LiB ]
[ Team LiB ]
Strings Besides numbers, text strings are an important part of programming. In Java, strings are supported by their own class, the String class, and you can think of the String class as defining a new data type. For example, you can create a string named greeting, which holds the text "Hello from JSP!" in Listing 2.6.
Listing 2.6 Creating a String (ch02_06.jsp) Creating a String Creating a String
You can see the results in Figure 2.5.
Figure 2.5. Creating a string.
Although strings are not one of the simple data types in Java, they deserve a place here, because most programmers treat them as they would any other data type. For example, here's how you can create three strings and join them into one string with the + operator:
String String String String
string1 = "Hello "; string2 = "from "; string3 = "JSP!"; greeting = string1 + string2 + string3;
In this case, the resulting string in greeting would be "Hello from JSP!". You can see a selection of the Java String class's methods in Table 2.3. For example, take a look at the entry int indexOf(String str) in that table. This method searches a string for a substring:
index = string1.indexOf("JSP");
Here, the code is searching the text in the String string1 for the text "JSP". Besides passing data to methods, methods can also return data, and the int in this entry in Table 2.3, int indexOf(String str), meaning this method returns an integer value. In this case, the indexOf method returns the character index at which the substring was found in the string you're searching (the first character in the main string has index 0, the next index 1, and so on). In the previous line of code, then, I'm assigning the index at which "JSP" was found in the text in string1 to the variable index. If the substring was not found, indexOf will return a value of –1.
Table 2.3. Selected Methods of the String Object
Method
Does This
boolean equals(Object anObject)
Compares this string to an object. Returns true if the strings are equal.
int indexOf(int ch)
Returns the index within this string of the first occurrence of the given character, or –1 if the search was unsuccessful.
int indexOf(int ch, int fromIndex)
Returns the index within this string of the first occurrence of the given character starting at the given index, or –1 if the search was unsuccessful.
int indexOf(String str)
Returns the index within this string of the first occurrence of the given substring, or –1 if the search was unsuccessful.
int indexOf(String str, int fromIndex)
Returns the index within this string of the first occurrence of the given substring starting at the given index, or –1 if the search was unsuccessful.
int lastIndexOf(String str)
Returns the index within this string of the rightmost occurrence of the given substring, or –1 if the search was unsuccessful.
int lastIndexOf(String str, int fromIndex)
Returns the index within this string of the last occurrence of the given substring, or –1 if the search was unsuccessful.
int length()
Returns the length of this string.
String replace(char oldChar, char newChar)
Returns a new string by replacing all occurrences of oldChar in this string with newChar.
String substring(int beginIndex)
Returns a new string that is a substring of this string.
String substring(int beginIndex, int endIndex)
Returns a new string that is a substring of this string, allowing you to specify the end index.
String toLowerCase()
Converts all the characters in this string to lowercase, returning a new string.
String toUpperCase()
Converts all the characters in this string to uppercase, returning a new string object.
String trim()
Removes white space from both ends of this string.
Now let's get to the details of creating and using strings. [ Team LiB ]
[ Team LiB ]
Creating Strings There are many ways to create strings. Here's a way we've already seen:
String s1 = "Hello from JSP!"; . . .
The code is assigning a string literal to s1. In fact, when you use a string literal like "Hello from JSP!" in your code, Java treats it as a String object, so what's really happening here is that the code is assigning one String object to another.
Tip String literals like "Hello from JSP!" are enclosed in double quotes. Java also supports single character literals, which you can assign to variables of the character type char. To create a character literal in Java, you must enclose the literal in single quotes, not double quotes (which will create a string), like 'a' or 'x'.
You can also, of course, declare a string first and then assign a value to it, like this:
String s1; s1 = "Hello from JSP!"; . . .
There are other ways of creating strings as well—and they rely on the fact that strings are really string objects. To understand these other ways of creating strings, you need to understand the object nature of strings. [ Team LiB ]
[ Team LiB ]
Strings Are Objects Strings aren't exactly like the other kinds of variables we've been seeing, because they're really objects of the String class, not simple variables of types like int or double. As mentioned in Day 1, an object can have built-in methods—such as the println method we've seen in the out object, as well as data members you use to store data in the object. We've already seen a selection of methods built into String objects in Table 2.3. You can think of Java classes, like the String class, as a sort of template or cookie cutter. You use that cookie cutter to create objects. In this way, a class is an object's type, just like int is the type of an integer variable. You can store objects in variables that you declare to be of that object's type (for example, you can store String objects in variables declared to be of type String). So how do you create an object from a class like the String class? You can use the class's constructor. A constructor is a special method that has the same name as the class itself (such as String), which you can use to create objects of that class. For example, to create a String object from the String class, we can pass the text that we want the new String object to contain to the String class's constructor, and it will return the new String object, which we store in a variable named s1: String s1 = new String("Hello from JSP!"); out.println(s1); . . .
This creates the new object s1, which holds the string "Hello from JSP!". We can pass this object to println to display that text in a Web page, as the code is doing here. Note also the use of the new keyword in this code. When you create a new object using a constructor, you need to use the new keyword in this way. We didn't have to do that when initializing a simple variable of the types int and float that you see in Table 2.2, but when you create a new object using a constructor, you have to use the new keyword as we're doing here. Doing so indicates to Java that it must create and initialize a new object, not just a simple variable. [ Team LiB ]
[ Team LiB ]
Determining String Length There are plenty of methods built into String objects available for use, as you can see in Table 2.3. For example, you can find the length of a string (in characters) using the String length method, as shown in Listing 2.7.
Listing 2.7 Getting String Length (ch02_07.jsp) Getting String Length Getting String Length
You can see the results in Figure 2.6.
Figure 2.6. Determining string length.
Note that the text "Hello from JSP!" in the output is quoted in Figure 2.6. But the text we pass to println must also be quoted in code (out.println("Like this");)—so how do we make sure println doesn't get confused with the quotation marks surrounding the text we pass it and the quotation marks we actually want to display? We do that by preceding the quotation marks we want to display with a backslash (\), which will make sure Java treats them as it would any other character, and does not try to interpret them in any special way. This is called escaping a character, and here are the characters you can escape: \'— Single quote \"— Double quote \\— Backslash \b— Backspace \ddd— Octal character, where ddd is the code for the character \f— Form feed \n— Newline (skips to the next line in plain text files) \r— Carriage return \t— Tab \uxxxx— Hexadecimal Unicode character, where xxxx is the code for the character
For example, if you want to display a quotation mark using out.println, you must escape it in the text you pass to that method: "He said, \"hello,\" when he saw me." This way, println will not get confused and think the two quotation marks in the middle of the text are actually beginning or ending the text itself. [ Team LiB ]
[ Team LiB ]
Creating and Working with Arrays Simple types like int are fine for storing single data items, but data is often more complex than that. Suppose that you want to start a new bank, the JSP Bank, and you need to keep track of the amount of money in every account, as indexed by account number. A method of working with more than simple variables is needed here, and that's what arrays provide. Using an array, you can group simple data types into a more compound data structure, and refer to that new data structure by name. More importantly, you can refer to the individual data items stored in the array by numeric index. That's important, because computers excel at performing millions of operations very quickly, so if your data may be referenced with a numeric index, you can work through a whole set of data very quickly simply by incrementing the array index. In this case, you might start JSP Bank with 100 new accounts, and each one will have its own entry in an array named accounts[]. The square braces at the end of accounts[] indicate that it's an array, and you place the index number of the item in the array you want to access in the braces. Here's how you can create the accounts[] array, giving each entry in it the double type for a little extra precision. First, you can declare the array, and then create it with the new operator—arrays are actually objects in Java, which means you need to use the new operator to create them:
Creating an Array Creating an Array
This creates an array of 100 double values. You can refer to the individual elements in the array using an index number in square brackets like this: accounts[0], which refers to the first element in the array (array indices are zero-based in Java, so accounts[0] refers to the first element), accounts[1], which refers to the second element in the array, and so on. For example, you can store $119.63 in accounts[3], and retrieve that value to display it, as shown in Listing 2.8.
Listing 2.8 Creating an Array (ch02_08.jsp)
Creating an Array Creating an Array
You can see this code at work in Figure 2.7.
Figure 2.7. Creating an array.
You can now refer to the items in the array using a numeric index, which organizes them in an easy way. You can also combine the declaration and creation steps into one step:
Creating an Array Creating an Array
In fact, you can also initialize arrays with values when you create the array. To do that, you enclose the list of values you want to store in the array in curly braces ({ and }). For example, this code creates four accounts, and stores $23.66 in accounts[0], $68.09 in accounts[1], $2889.00 in accounts[2], and $119.63 in accounts[3]:
Initializing an Array Initializing an Array
Tip Here's another thing to remember about arrays—you can get the length of an array (that is, the number of elements in an array) with the length data member. For example, the expression accounts.length will hold 4 in the previous example. See "The for Loop" in Day 3, "Branching, Looping, and Creating Methods," for an example.
This is fine as far as it goes, but there's more. For example, what if our customers want a checking account in addition to a savings account? How can we handle that and still keep things indexed by account number?
The accounts[] array we've already created is a one-dimensional array, which means you can think of it as a single list of numbers that you can index with one index number. However, arrays can have multiple dimensions in Java, which means that you can have multiple array indexes. In this next example, you can extend accounts[] into a two-dimensional array, accounts[][], to handle both a savings and checking account. The first index of accounts[][] will be 0 for savings accounts and 1 for checking accounts, and the second index will be the account number as before. You can see how that looks in code in Listing 2.9.
Listing 2.9 Using Multidimensional Arrays (ch02_09.jsp) Using Multidimensional Arrays Using Multidimensional Arrays
Now that accounts[][] is a two-dimensional array, each item in it is referred to using two index values; for example, the savings balance for account 3 is now accounts[0][3], and the checking balance is accounts[1][3]. You can see the results in Figure 2.8.
Figure 2.8. Creating a multidimensional array.
That gives us a solid start with storing data in Java—we've taken a look at working with literals, simple variables, strings, objects, and arrays. We've gotten data storage down, now let's take a look at how to work with and manipulate that data using operators. [ Team LiB ]
[ Team LiB ]
Working with Operators The most basic way to work with the data in a program is with the built-in Java operators. For example, say you have stored a value of 23 in one variable and a value of 4 in another. You can multiply those two values with the Java multiplication operator, *, which you can see in Listing 2.10.
Listing 2.10 Using Operators(ch02_10.jsp) Using Operators Using Operators
You can see the results in Figure 2.9, where we learn that 23 * 4 is 92.
Figure 2.9. Using Java operators.
The following operators are available in Java: Decrement operator (--) Subtraction operator (-) This is also the negation operator if you use it in front of a value; for example, the expression -x evaluates to the value in x with that value's numeric sign flipped—positive values become negative and negative values become positive. Logical unary NOT operator (!) Not equal to operator (!=) Modulus operator (%) Modulus assignment operator (%=) Logical AND operator (&) Short-circuit AND operator (&&) Bitwise AND assignment operator (&=) Multiplication operator (*) Multiplication assignment operator (*=) Division operator (/) Division assignment operator (/=)
if-then-else operator (?:) Logical Xor operator (^) Bitwise Xor assignment operator (^=) Logical OR operator (|) Short-circuit OR operator (||) Bitwise OR assignment operator (|=) Bitwise unary NOT operator (~) Addition operator (+) Increment operator (++) Addition assignment operator (+=) Less than operator (=) Shift right with zero fill operator (>>>) Shift right zero fill assignment operator (>>>=) We'll see these various operators, and how to use them, throughout the book—starting right here, with a look at the common Java operators. [ Team LiB ]
[ Team LiB ]
Assignment Operators The most basic operators are the assignment operators, which we've already seen. You use the = operator to assign a variable a literal value, the value in another variable, and so on, like this, where the code is assigning the variable named var1 a value of 12:
Assignment Operators Assignment Operators
Java also supports combination assignment operators, which combine an operator like +, -, or * with the assignment operator =. Here's an example showing how that works: Say that we have stored 15 in a variable named var1: int var1 = 15;
To add 12 to the value in this variable, we can use this code:
int var1 = 15; var1 = var1 + 12;
On the other hand, we can use the combination operator += to do the same thing; this operator is short for "add the value of the second operand to the value of the first operand and assign the result to the first operand":
int var1 = 15; var1 += 12;
There are quite a few combination assignment operators in Java: Modulus assignment (%=) Bitwise AND assignment (&=) Multiplication assignment (*=) Division assignment (/=) Bitwise Xor assignment (^=) Bitwise OR assignment (|=) Addition assignment (+=) Shift left assignment (>>=)
[ Team LiB ]
[ Team LiB ]
Incrementing and Decrementing Operators The Java ++ operator increments its operand by one, and the -- operator decrements its operand by one. For example, if value holds 0, then after you execute value++, value will hold 1. Here's an important point; ++ and -- can be either postfix operators (value++) or prefix operators (++value). When used as a postfix operator, they are executed after the rest of the statement, and when used as a prefix operator, before the rest of the statement. This is something you have to watch out for, because if you have code like this value2 = value1++;
when the statement is completed, value2 will actually be left with the original value in value1 (not the incremented value), and the value in value1 will have been incremented. You can see an example showing code using ++ as both a prefix and postfix operator in Listing 2.11.
Listing 2.11 Incrementing and Decrementing Using Operators (ch02_11.jsp) Incrementing and Decrementing Incrementing and Decrementing
You can see the results of this code in Figure 2.10, where you can see the ++ operator working as both a prefix and postfix operator.
Figure 2.10. Using ++ as both a prefix and postfix operator.
[ Team LiB ]
[ Team LiB ]
Multiplication and Division Operators You use * to multiply values and / to divide values in Java. You can see an example where the code uses * and / on double values in Listing 2.12.
Listing 2.12 Multiplication and Division (ch02_12.jsp) Multiplication and Division Multiplication ) For example, operand1 > operand2 returns true if operand1 is greater than operand2. Greater than or equal to (>=) Less than (
You'll see more about branching statements like this one today.
Loops let you execute some code over and over on a set of data. Loops are one of the main reasons computers are so powerful, because that's what computers are good at: executing large amounts of code quickly. For example, you might have an array holding student scores from a class you're teaching on JSP, and using a loop, you can add all the scores to find the average score. Each time through the loop, called a loop iteration, you can increment the array index, giving you access to the next array element. As you iterate through the whole array of student scores this way, you can add each score to a running total. When the loop is finished, you can divide the running total by the total number of students to get the average score. You'll see how that works today. We'll also see how to create our own methods today. We've seen methods ever since Day 1, where we used the out object's println method to write text to the Web page being sent back to the browser. Here, we're going to see how to write our own methods. Dividing your code into methods is a good idea when your code gets long; it helps keep things organized. Unless you break your code up into smaller units, you could end up with many pages of tangled Java. If you divide that code into methods, each of which is called to execute a specific, discrete task, things stay manageable. That's it for the introduction—let's get programming, starting with branching statements. [ Team LiB ]
[ Team LiB ]
Branching Statements The next step up from using the simple operators we saw in Day 2 is to use branching statements in your code. You use branching statements to make decisions based on the value of your data, and to make the flow of the program go in different directions accordingly. There are two branching statements in Java—the if statement, and the switch statement.
The if Statement When you want to test conditions and execute code accordingly, it's a good idea to use a statement like the if statement. Here's how you use this statement in general:
if (condition) statement1; [else statement2;]
If condition evaluates to true, statement1 is executed. Otherwise, if there is an else clause to the statement, the code in it (statement2) is executed. In Java, statement1 and statement2 can both be compound statements, which means that they can be made up of a number of statements enclosed in curly braces, like this:
if (condition){ statement; statement; . . . } else { statement; statement; . . . }
Let's take a look at some examples to see how this works. For example, what if you wanted to find the absolute value of a number? One way to get an absolute value is to start by checking whether the value is greater than 0, and if so, just print out the value itself. Listing 3.1 shows how to make that test with an if statement.
Listing 3.1 Using an if Statement (ch03_01.jsp) Using the if Statement Using the if Statement 0) out.println("Absolute value of " + value + " = " + value); %>
Note the if statement's condition here, value > 0, where the code is using the > relational operator (see the section "Relational Operators" in Day 2), which will be true if the value is greater than 0, and false otherwise. You can see the results of this code in Figure 3.1.
Figure 3.1. Using the if statement.
Executing Compound Statements Note that in this case, the statement that's executed if the if statement is true is a single statement, but you can also execute multiple statements if you make them part of a compound statement surrounded by { and }, as you see in Listing 3.2.
Listing 3.2 Using a Compound Statement (ch03_02.jsp) Using Compound Statements Using Compound Statements 0) { out.println("The number was positive."); out.println("Absolute value of " + value + " = " + value); } %>
You can see the results of this code in Figure 3.2.
Figure 3.2. Using compound statements.
The else Statement So far, our if statement only displays an absolute value if the value is greater than 0. You can expand that if statement by adding an else clause, which is executed if the if statement's condition is false. You can see how that looks in Listing 3.3. This enables us to find the absolute value of negative numbers as well as positive ones (note that the code is also using the Java negation operator (-) to change the sign of value if needed; see the topic "Operators" in Day 2 for more on this operator).
Listing 3.3 Using an else Clause (ch03_03.jsp) Using an else Clause Using an else Clause 0) { out.println("Absolute value of " + value + " = " + value); } else {
out.println("Absolute value of " + value + " = " + -value); } %>
You can see the results of this code in Figure 3.3.
Figure 3.3. Using an else clause.
Nested if Statements You can also nest if statements inside each other; here's an example showing how that works. In this case, say that you want to display the reciprocal of a number—but only if that number is positive. Also, you don't want to even try to get the reciprocal if the number is zero, because the reciprocal of zero is not defined. Listing 3.4 shows how you can put all this into code using a nested if statement (note that the code is using the relational operator != here, which means "not equal to," as you saw in Day 2).
Listing 3.4 Nested if Statements (ch03_04.jsp)
Nested if Statements Nested if Statements 0) out.println("The result = " + (1 / value)); else out.println("Sorry, we need a positive number."); } %>
if-else
Ladders
It's possible to create an entire sequence of if-else statements called an if-else ladder. You can see an example showing how this works in Listing 3.5; in this case, the code keeps testing the value in a String variable until it finds a match to the current day of the week.
Listing 3.5 Using an if-else Ladder (ch03_05.jsp) Using an if-else Ladder Using an if-else Ladder
You can see the results of this code in Figure 3.4, where we see that it's Friday.
Figure 3.4. Using an if-else ladder.
Although it's possible to create if-else ladders like this, Java actually includes a statement expressly for situations like this: the switch statement.
The switch Statement The switch statement is Java's multiway branch statement, and it provides the same kind of functionality as an if-else ladder, but in a much easier form. Here's what the switch statement looks like in general:
switch (expression) { case value1: statement1; [break;] case value2: statement2;
[break;] case value3: statement3; [break;] . . . default: default_statement; }
Here, the value of the expression, which must be of type byte, char, short, or int, is compared against the various test values in the case statements: value1, value2, and so on. If the expression matches one of the test values in the case statements, the code associated with that case statement is executed. If execution reaches a break statement, the switch statement ends. Listing 3.6 shows an example in which the code displays the day of the week based on a numeric value using a switch statement.
Listing 3.6 Using the switch Statement (ch03_06.jsp) Using the switch Statement Using the switch Statement
You can see the results of this code in Figure 3.5.
Figure 3.5. Using the switch statement.
Take a look at this switch statement; note that each case statement in the switch statement matches a particular value of the day variable. If the value in day matches that given in a specific case statement, the code in that case statement is executed, up to the break statement, which ends the switch statement:
int day = 3; switch(day) { case 0: out.println("It\'s Sunday."); break; case 1: out.println("It\'s Monday."); break;
case 2: out.println("It\'s Tuesday."); break; case 3: out.println("It\'s Wednesday."); break; case 4: out.println("It\'s Thursday."); break; case 5: out.println("It\'s Friday."); break; default: out.println("It must be Saturday."); }
You can have multiple statements in each case statement if you so desire:
case 1: out.println("It\'s Monday."); out.println("Have you had your coffee yet?"); out.println("Time to go to work..."); break;
Note also the (optional) default statement at the end of the switch statement in the example—if no case statement is executed, the code in the default statement, if there is one, is executed. You can even nest switch statements, just like if statements. If you don't place a break statement at the end of a case statement, execution will continue with the code in the next case statement. Sometimes that's useful, as when you want to execute the same code for multiple case test values, as you see in Listing 3.7.
Listing 3.7 Testing for Multiple Conditions (ch03_07.jsp) Testing for Multiple Conditions Testing for Multiple Conditions
You can see the results of this code in Figure 3.6, where we see that the temperature is pretty cool.
Figure 3.6. Testing for multiple conditions in a switch statement.
That completes our look at branching statements; next, we'll look at loops. [ Team LiB ]
[ Team LiB ]
Loops Loops are basic programming constructs that let you handle tasks by executing specific code over and over. For example, you might want to handle the items in a set of data by working with each item in succession, or keep performing a task until a particular condition becomes true. There are a number of different loop statements in Java, and we'll take a look at them all here, starting with the for loop.
The for Loop In Java, the basic loop statement is the for statement, which is a very general loop statement. It's usually used to let you execute code using a loop index. Each time through the loop, the loop index will have a different value, and you can use the loop index to access a different data item in your data set; such as when you use the loop index as an index into an array. Here's what the for loop looks like in general:
for (initialization_expression; end_condition; iteration_expression) { statement; }
The initialization_expression is executed before the loop is executed the first time; end_condition is checked every time through the loop, and when it becomes false, the loop ends; and iteration_expression is executed after each time through the loop. statement makes up the body of the loop, holding the code you want executed each time through the loop (note that statement can be a compound statement, including several single statements inside curly braces). For example, you can initialize a loop index in the initialization_expression, provide a test for ending the loop when that test becomes false in the end_condition, and provide some way of changing—usually incrementing—the loop index in the iteration_expression. Let's make this concrete with an example. In this case, the code will execute a for loop 10 times. Here, the code assigns a loop index variable named loopIndex the value 1 to start (as you can see in the initialization expression loopIndex = 1) and end the loop when that loop index exceeds 10 (as you can see in the end condition loopIndex
You can see the results of this code in Figure 3.13—note that the display skips over the line where it would try to calculate the reciprocal of 0.
Figure 3.13. Using the continue statement.
And that completes our look at loops in Java. We've taken a look at for loops, while loops, and dowhile loops, and we've seen the break and continue statements to break out of loops and continue on to the next iteration for extra power. Now let's turn to the last topic for today—creating methods. [ Team LiB ]
[ Team LiB ]
Creating Methods We've been using methods ever since printing out our first message with out.println, so we're familiar with the concept—a method contains code that you can execute by calling that method:
In this case, the code is passing the text "Hello there!" to out.println, and that method writes that text to the Web page. Now it's time to get this power for ourselves. Here's how you create a method in Java:
[access] [static] type methodName (argument_list) . . . }
To declare and define a method in Java, you can use an access specifier, which can be public, private, or protected. These access specifiers are used when you're creating Java classes, and we'll see more about them in Day 11, "Creating More Powerful JavaBeans." The keyword static is also all about working with classes, and lets programmers use your method without creating an object from it. We won't need that here, so we'll also defer that to Day 11. Next, you must specify the return type of a method, which is specified by type in the preceding code. The return type indicates what kind of data the method returns when you call it. For example, if you have a method named addem that you pass two integers to, and it adds those integers and returns the sum—of type int—the return type for the method will be int. Return types include any valid type, such as the simple data types int, float, double, and so on. You can also return an array, using return types like int[], double[], and so on. If your method does not return a value, use the return type void. Next, you give the method's name and place the list of the arguments you intend to pass to the method after that name. Note that you must specify the type of each argument, as in this case, in which the code is declaring the addem method (to which you pass two integers), and it's naming those integers op1 and op2 (for "operand 1" and "operand 2"):
int addem(int op1, int op2)
The actual body of the method—the code that will be executed when you call the method—is enclosed in a code block (delimited with curly braces, { and }) following the method's declaration. Note in particular that you must declare methods in JSP declarations (surrounded by ), and not in scriptlets (which are surrounded by ):
Creating a Method Creating a Method
The code has named the two integers passed to this method part of the method declaration, and now you can refer to those integers in the body of the method with those names. To return their sum from this method, you can use the return statement:
Creating a Method Creating a Method
The code in a method like addem isn't run until you call it. On the other hand, the code in a general scriplet, outside any method, is run as soon as the page is loaded. Listing 3.17 shows how to call the new addem method, add 2 + 2, and display the result.
Listing 3.17 Creating a Method (ch03_17.jsp) Creating a Method Creating a Method
You can see the results of this code in Figure 3.14, where we're using the full power of Java to tell us that 2 + 2 = 4.
Figure 3.14. Creating a method.
Here's something to note—because you must declare methods in JSP declarations, not scriplets, the code in your methods does not have access to the built-in JSP objects like out. That might appear to be a serious drawback if you want to send text to a Web page from a method, but you can get around this problem if you pass the out object to a method. We'll see how this works later today.
Declaring Multiple Methods You can declare multiple methods in the same JSP declaration, as seen in Listing 3.18. This example declares a method named subractem that subtracts one integer from another and returns the difference.
Listing 3.18 Declaring Multiple Methods (ch03_18.jsp) Declaring Multiple Methods Declaring Multiple Methods
You can see the results of this code in Figure 3.15.
Figure 3.15. Declaring and using multiple methods.
Using Built-In JSP Methods The Java class that JSP pages are built on, HttpJspBase, has two methods built into it that are automatically called at specific times in the lifecycle of a JSP-enabled page. The first method, jspInit, is automatically called when the page is first created, and the second, jspDestroy, is automatically called when the page is unloaded and destroyed by the server. The purpose of jspInit is to let you run initialization code for the page, and the purpose of jspDestroy is to let you run clean-up code after the page is done, which can involve opening and closing database connections. Here's an example using jspInit to set a variable to 5 when the page loads, and setting that variable to 0 when the page is destroyed. Note that neither jspInit nor jspDestroy take any arguments or return a value. Also, note that in this case we have to use the public keyword, because we're actually overriding (overriding means redefining, as you'll see in Day 11) the jspInit and jspDestroy methods. Because they were declared in HttpJspBase with the public keyword, Java insists that you use that same keyword here when redefining these methods (more on the public keyword in Day 11), as you see in Listing 3.19.
Listing 3.19 Using jspInit and jspDestroy (ch03_19.jsp) Using jspInit and jspDestroy
Using jspInit and jspDestroy
And that's all it takes—now this page has both initialization and clean-up code that the server runs automatically at the right time.
Recursion It's also worth knowing that JSP methods can call themselves, a process called recursion. This isn't necessary knowledge for the work we'll do in this book, so you can skip it if you like. You've already seen how factorials work (for example, the factorial of 6 is 6 x 5 x 4 x 3 x 2 x 1 = 720), and factorials lend themselves to recursion. This example supports a method named factorial that you pass an integer to, and it returns an integer. If the integer we're passed is 1, we're all done, because the factorial of 1 is 1, so we return that value:
int factorial(int n) { if (n == 1) { return n; } . . . }
Otherwise, all we have to do is return the current number—say that's n, multiplied by the factorial of n-1 (which we can find by calling the factorial method again):
int factorial(int n) { if (n == 1) { return n; } else { return n * factorial(n - 1); } }
Here's how this method looks in an example, in which the code is calling it to find the factorial of 6, as you see in Listing 3.20.
Listing 3.20 Using Recursion (ch03_20.jsp) Using Recursion Using Recursion
You can see the results of this code in Figure 3.16, where we see that the factorial of 6 is 720.
Figure 3.16. Using recursion.
Scope When you discuss the creation of methods, the issue of scope becomes important. An item's scope is the area of your program in which you can reference it—that is, it's where an item in visible. For example, in the following code, the variable named number is declared outside any method, so it's accessible inside the body of any method:
However, if you had declared number inside a method, it would be private to that method, and you couldn't access it in the other method:
You can see this page in Figure 4.13.
Figure 4.13. Using standard buttons.
In the JSP code, all you need to do is recover the name of the button that was clicked from the hidden control and display it, as you see in Listing 4.15.
Listing 4.15 Determining Which Button Was Clicked (ch04_15.jsp) Determining Which Button Was Clicked Determining Which Button Was Clicked You clicked
You can see the results in Figure 4.14, where, with a little help from hidden controls and JavaScript, we see that Button 2 was clicked. That's one way of handling multiple buttons—stay tuned for a few more.
Figure 4.14. Determining which button was clicked.
[ Team LiB ]
[ Team LiB ]
JSP to JSP—Navigating Directly to JSP Pages So far today, we've used HTML pages that you navigate to first, and JSP pages to handle input from those HTML pages. In other words, we've used introductory HTML pages to give users access to our JSP pages. However, it's important to realize that you can navigate directly to JSP pages, even when you're sending data to those pages. When you open the JSP page for the first time, you're not sending any data from HTML controls to that page, so request.getParameter("controlName") will return the Java value null, where controlName is a control in your page whose data you want. You can use this fact to determine whether there's any data sent to you from HTML controls, and if not, simply display an introductory Web page the way you want the users to see it before they've entered any data. For instance, you can rewrite the previous example, putting everything into one JSP page—if the user has clicked a button, you can indicate what button was clicked; otherwise, you can just display the buttons, as you see in Listing 4.16.
Listing 4.16 Using Buttons (ch04_16.jsp) Using Buttons You clicked
To see how this works, you can navigate to http://localhost:8080/ch04/ch04_16.jsp, click a button, and you'll see the results in Figure 4.15. Everything is handled by that one JSP page—no introductory HTML page is needed.
Figure 4.15. Using a literal in Java.
Note that there are times when the data in HTML controls might actually return a value of null when you use getParameter, so here's a more general way of testing if data was sent to you—you can use
the request object's getParameterNames method (that we'll see tomorrow), which returns the names of the HTML controls that sent you data. If this method returns null, it's a sure bet that there's no data waiting for you to process:
if(request.getParameterNames() != null) { //Process data from HTML controls } else { //Display introductory Web page }
In this example, we've been handling multiple buttons in a form with the aid of JavaScript. But this isn't a book on JavaScript, it's a book on JSP. Isn't there a way to handle multiple buttons just using JSP? There is—you can use multiple HTML forms. [ Team LiB ]
[ Team LiB ]
Using Multiple Forms A single Web page can support multiple HTML forms, and that's often useful. For example, one way to support multiple buttons in a Web page is to make them all submit buttons and place them each in their own form. When the user clicks a button, that form's data is sent to the server. To distinguish between the various forms, you can give each form a hidden control with identifying text that you can read in your JSP code. For example, you can see how to support three different buttons in three different forms in Listing 4.17, where each form contains hidden text holding the button's name. When the user clicks a button, our code can display the clicked button's name using that hidden text.
Listing 4.17 Using Multiple Forms (ch04_17.jsp) Using Multiple Forms Using Multiple Forms You clicked
You can see the results in Figure 4.16.
Figure 4.16. Supporting multiple forms.
In fact, there's an easier way to do this. Submit buttons are HTML controls like any other, which means you can read the text in their VALUE attributes—that is, their captions—using getParameter. If you give each submit button the same name but different captions, you can read those captions in our JSP code to determine what button was clicked, as you see in Listing 4.18.
Listing 4.18 Using Multiple Forms Using Buttons with Multiple Names (ch04_18.jsp) Using Multiple Forms Using Multiple Forms
You clicked
You see the results in Figure 4.17, where, thanks to multiple HTML forms, we see that Button 3 was clicked.
Figure 4.17. Using multiple HTML forms with buttons with different names.
[ Team LiB ]
[ Team LiB ]
Summary You've seen quite a lot today. You've gotten started using HTML controls in Web pages and reading data from those HTML controls in JSP code. You've learned how to use the various attributes of the element to tailor your HTML forms as you want them, and to send the data in the form's controls back to the server. You use submit buttons to actually send that data to the URL given in the form's ACTION attribute. You can decipher the data sent to you in your JSP code using the request object, and you learned the methods of that object today. The method we focused on today was the getParameter method, which lets you read the data from various controls. The controls you've seen today included submit buttons, text fields, text areas, password controls, hidden controls, standard buttons, and reset buttons. You can handle all these controls with the getParameter method. You also learned how to use multiple forms, and how you can use them to support multiple buttons in the same Web page. And we got a little tricky by storing form data in hidden controls, both with and without the help of JavaScript. Tomorrow, we'll continue our work with HTML controls as we turn to the other controls that are available, from check boxes to select controls. [ Team LiB ]
[ Team LiB ]
Q&A Q1:
What if a control can return multiple values, such as a multivalue select control? I can't use getParameter in such a case.
A1:
There are other methods you use instead—See the topic "Using Multiple-Selection Select Controls" in Day 5.
Q2:
Can I use the request object in secure channels such as HTTPS?
A2:
Yes. One handy method if you're using a secure channel is the request object's isSecure method, which returns true if this request was made using a secure channel, such as HTTPS, and false otherwise.
[ Team LiB ]
[ Team LiB ]
Workshop This workshop tests whether you understand all the concepts you learned today. It's a good idea to master today's concepts by honing your knowledge here before starting tomorrow's material. You can find the answers to the quiz questions in Appendix A.
Quiz 1:
What attribute of the element do you use to specify where to send the form data?
2:
What's the difference between the GET and POST methods?
3:
Name two controls that can submit a form's data back to the server.
4:
What Java class is the request object an object of?
5:
Which method can you use to determine what browser the user has?
Exercises 1:
Give this one a try—just read the text that the user has entered into a password control and return it in a text field. Doing so will give you practice in handling both reading and sending data using HTML controls.
2:
Following the example in the topic "Using Request Objects" today, use the request.getHeader("User-Agent") method to check what browser the user has. If the user is using Internet Explorer, display a greeting using the element; otherwise, use the element.
[ Team LiB ]
[ Team LiB ]
Day 5. Reading Data from Web Pages: Check Boxes, Radio Buttons, and Select Controls Welcome to Day 5! Today, we're going to continue the work we started yesterday—working with HTML controls and HTTP requests. You'll also learn how to deal with check boxes, radio buttons, and select controls, as well as many other topics. These are primary HTML controls that users expect to see in the pages we'll send them. Besides these controls, we'll also take a look at working with image controls, which let you determine where the user has clicked an image. That's great for image maps—those clickable images with "hotspots" that perform various actions—which we'll also see today. To implement image maps, we'll look at the action, which lets you navigate to new URLs in your JSP code. Using , you can navigate to a new URL when the user clicks a hotspot in the image map corresponding to that URL (for example, our image map is going to contain a hotspot marked "Weather," and when the user clicks it, we'll open a page on the weather). Here's an overview of today's topics: Working with check boxes Working with radio buttons Selecting and deselecting check boxes and radio buttons in code Working with select controls (creating drop-down lists) Handling image controls and image maps Forwarding requests to other pages. Let's start with the HTML controls we're going to see today, beginning with HTML check boxes. [ Team LiB ]
[ Team LiB ]
Using Check Boxes You create check boxes with the element, and you can use the NAME attribute of this element to give the check box a name. In your code, you can see whether a check box has been checked by passing its name to request.getParameter. Here's an example; in this case, the code will add three check boxes to a Web page and name them check1, check2, and check3 (note that the first check box, check1, will appear checked when the page first appears, because the code uses the standalone CHECKED attribute for that check box). You can see the code in Listing 5.1.
Listing 5.1 Submitting Check Boxes (ch05_01.html) Submitting Check Boxes Submitting Check Boxes Checkbox 1 Checkbox 2 Checkbox 3
You can see this Web page with the check boxes in Figure 5.1.
Figure 5.1. Using check boxes and responding to check box actions.
In the JSP code, you can examine each check box by passing its name to request.getParameter to see whether it has been checked—if a check box is checked, request.getParameter will return the text in the check box's VALUE attribute (which is check1, check2, or check3 in this example, as you see in the VALUE attributes in Listing 5.1), or null if the check box was not checked, as you see in Listing 5.2.
Listing 5.2 Reading Check Boxes (ch05_02.jsp) Reading Checkboxes Reading Checkboxes
Now you can see the results in Figure 5.2.
Figure 5.2. Examining check boxes in code.
That's all it takes to see whether a check box was checked or not. You'll see more about checking and unchecking check boxes in code in a few pages. [ Team LiB ]
[ Team LiB ]
Using Radio Buttons Radio buttons operate in groups, and only one radio button in a group can be selected at a time. To create a radio button group, you give a set of radio buttons the same name (using the HTML NAME attribute). How do you tell the radio buttons apart? You use the VALUE attribute, giving them different values.
Tip You can have multiple radio groups, which will operate independently, in the same Web page. Just give all the radio buttons in each group the same name, using a different name for each group.
You can see an example in Listing 5.3, in which the code is adding three radio buttons to a Web page and naming them all radios to group them together, and giving them different values (radio1, radio2, and radio3).
Listing 5.3 Submitting Radio Buttons (ch05_03.html) Submitting Radio Buttons Submitting Radio Buttons Radio Button 1 Radio Button 2 Radio Button 3
You can see the results in Figure 5.3, which shows the three radio buttons.
Figure 5.3. Using radio buttons and responding to radio button actions.
You can see whether a radio button has been selected by passing the name radios to request.getParameter. If the request.getParameter returns radio1, the first radio button was selected; if it returns radio2, the second radio button was selected, and so on. You can see how to determine which radio buttons were selected in Listing 5.4.
Listing 5.4 Reading Radio Buttons (ch05_04.jsp) Reading Radio Buttons Reading Radio Buttons
You can see the results in Figure 5.4, where we see that in this case, only the first radio button was selected.
Figure 5.4. Checking radio buttons.
As you can see, it's easy to determine which check box or radio button the user has selected. But what if you want to select or deselect these controls yourself in code? That's coming up next. [ Team LiB ]
[ Team LiB ]
Selecting and Deselecting Check Boxes and Radio Buttons in Code Using the standalone CHECKED attribute, you have control over whether check boxes and radio buttons appear selected when their containing Web page first appears. Using this attribute, you can select and deselect check boxes and radio buttons in code. Here's an example, which you can see in Figure 5.5. This example lets users select which sandwich they want, as you can see in the figure. The user can select a sandwich using the radio buttons on the left, and our program will check the corresponding ingredient check boxes on the right when the user clicks the Submit button. The code also determines which radio button was selected, and makes sure the same radio button is selected when a new page is sent back to the browser.
Figure 5.5. Selecting and deselecting check boxes and radio buttons in code.
Selecting and deselecting check boxes and radio buttons in JSP code is simply a matter of using the CHECKED attribute. In this example, we want to set the check boxes to match which radio button was selected. To do that, you can declare three variables for each of the three check boxes, check1, check2, and check3, setting each to an empty string ("") at first:
String check1 = "", check2 = "", check3 = "";
If a particular radio button is selected, such as the one for turkey sandwiches, we can set the corresponding check boxes' variable to "CHECKED":
if(request.getParameter("radios").equals("turkey")){ check1 = "CHECKED"; check3 = "CHECKED"; }
Then when we display each check box, we can simply indicate whether or not the check box should be checked:
You can see the full code for this example in Listing 5.5.
Listing 5.5 Design Your Sandwich (ch05_05.jsp) Design Your Sandwich!
Design Your Sandwich!
Sandwich |
Cheese Sandwich Turkey Sandwich Ham Sandwich |
Ingredients |
Meat Cheese Lettuce |
We've got a lot of power over check boxes and radio buttons now, and can determine whether the user has selected them, and we can also select and deselect them in code. Next, our discussion will cover the use of select controls. [ Team LiB ]
[ Team LiB ]
Using Select Controls Select controls display scrollable lists and drop-down lists. These kinds of controls come in two varieties—those that let you select one item at a time, and those that let you select multiple items. We'll look at single-selection select controls first. You create a select control with the element, enclosing the items you want to appear in the select control in elements. Here's an example in which the code is creating a select control named select1 with three items in it: Option 1, Option 2, and Option 3:
Option 1 Option 2 Option 3
Listing 5.6 shows how you can use this control in a sample HTML document.
Listing 5.6 Submitting a Select Control (ch05_06.html) Submitting Select Controls Submitting Select Controls Option 1 Option 2 Option 3
You can see what this Web page looks like in Figure 5.6.
Figure 5.6. Using a select control.
You can read the selected option in single-selection select controls in your JSP code by passing the name of the control to request.getParameter. Listing 5.7 shows the code that determines which item the user selected in the select control.
Listing 5.7 Reading Select Controls (ch05_07.jsp) Reading Select Controls Reading Select Controls You selected
You can see the results in Figure 5.7, where we learn that we've selected Option 2.
Figure 5.7. Determining a selection in a select control.
And that's how you use single-selection select controls. Multiple selection select controls are coming up next. [ Team LiB ]
[ Team LiB ]
Using Multiple-Selection Select Controls If you use the MULTIPLE standalone HTML attribute in a select control, that control can accept multiple selections:
Option 1 Option 2 Option 3 Option 4 Option 5
Listing 5.8 shows how you can display a multiple-selection select control.
Listing 5.8 Using Multiple-Selection Select Controls (ch05_08.html) Submitting Multiple Selection Select Controls Submitting Multiple Selection Select Controls Option 1 Option 2 Option 3 Option 4 Option 5
Caution Note that this code is using the SIZE attribute here to display a number of items in the
select control at once. If you don't use the SIZE attribute (as we didn't in the previous single-selection example), you get a drop-down list, but drop-down lists don't support multiple selections.
You can see this Web page in Figure 5.8, in which the user is selecting two items. (How you select multiple items in a select control like this varies by operating system—for example, in Windows, you can use the Ctrl key together with the mouse to select multiple items by clicking them, or the Shift key with the mouse to select a range of items.)
Figure 5.8. Using a multiple-selection select control.
The next step is to determine which items were selected when the Submit button was clicked and the form's data was sent to us on the server. This is the first time a control has sent us multiple values, and the getParameter method isn't going to work here (it would simply return the first selected item). Instead, you use the request object's getParameterValues method in this case. As you can see in Table 4.1, the getParameterValues method returns an array of strings corresponding to all the values associated with a control. That's exactly what you need here to get all the selected items in the select control. You can loop over the items in the returned string array and display them as you see in Listing 5.9.
Listing 5.9 Reading Multiple-Selection Select Controls (ch05_09.jsp) Reading Multiple Selection Select Controls
Reading Multiple Selection Select Controls You selected:
Now you can determine which items the user has selected in a multiple-selection select control, as you see in Figure 5.9.
Figure 5.9. Determining which options were selected.
[ Team LiB ]
[ Team LiB ]
Check Box Groups We've seen that you can create radio button groups by giving radio buttons the same name; in the same way, you can create check box groups. However, check box groups are different from radio button groups, because multiple check boxes can be checked at the same time in the same group. Listing 5.10 illustrates how to create a check box group with three check boxes, all named checks, but with different values.
Listing 5.10 Submitting Check Boxes (ch05_10.html) Submitting Check Boxes Submitting Check Boxes Checkbox 1 Checkbox 2 Checkbox 3
You can see this Web page in Figure 5.10.
Figure 5.10. Creating a check box group.
To determine which check boxes were checked, you can use request.getParameterValues and loop over the array that method returns, as you see in Listing 5.11.
Listing 5.11 Reading Check Boxes (ch05_11.jsp) Reading Checkboxes Reading Checkboxes You checked:
You can see the results in Figure 5.11. Using getParameterValues in this way, you can support check box groups and determine which check boxes in the group were checked.
Figure 5.11. Using a check box group.
[ Team LiB ]
[ Team LiB ]
Uploading Files Another HTML control is the file upload control (), but here the Tomcat server isn't going to help us out much. To upload files you'll use multipart forms, which you create with the element's ENCTYPE attribute:
However, Tomcat doesn't support multipart forms yet, so you have to use a standard form, as you see in Listing 5.12.
Listing 5.12 Uploading Files (ch05_12.html) Uploading Files
Figure 5.12 shows the file control created by this Web page.
Figure 5.12. Using a file upload control.
This file upload control isn't going to do much for us. Listing 5.13 shows you how to recover the information it sends you.
Listing 5.13 Uploading Files (ch05_13.jsp) Uploading Files Uploading Files You selected
You can see the results in Figure 5.13, where we see that the file upload control has given us only the name of the file we had wanted to upload in this case. Presumably, file upload controls will be supported in later versions of the server software.
Figure 5.13. Getting a filename.
[ Team LiB ]
[ Team LiB ]
Image Controls Image controls () act much like submit buttons, except they display images the user can click. The location that the user clicked in the image is also sent to the server with the rest of the data from the form. Here's an example showing how this works. Here, the code will use an image control to display a clickable image, and when the user clicks it, the mouse location is sent to the server automatically, with no submit button needed. In the JSP code, we can determine and display the mouse location. Listing 5.14 details the HTML page that displays the image and the image control—note that this code names the image control images.
Listing 5.14 Using Image Controls (ch05_14.html) Using Image Controls Using Image Controls
You can see this page at work in Figure 5.14, where the user is about to click the image.
Figure 5.14. Using an image control.
The name of our image control is images, which means that the (x, y) mouse location is passed to us as the request parameters images.x and images.y. You can see how to display that mouse location when you get it in Listing 5.15.
Listing 5.15 Reading Image Controls (ch05_15.jsp) Reading Image Controls Reading Image Controls You clicked the image at (, ).
The results appear in Figure 5.15, where we see the location at which the user clicked the image.
Figure 5.15. Reading data from an image control.
Because they can report mouse locations, image controls are often used for image maps, those clickable images with hotspots that will take you to different URLs. In fact, there is a way to send the browser to a new URL—you can use the action. You'll see first, then put it to work in an image map with hotspots that the user can click to navigate to new URLs. [ Team LiB ]
[ Team LiB ]
Using You can use the action to forward an HTTP request to another Web page:
Note the XML-style tag terminator here, />, which you'll see a lot in JSP action elements. This is just a shortcut that lets you omit a closing tag; the previous line of code is the same as this version, which uses the closing tag :
Here, relativeURL is the URL of another page accessible as part of the same Web application. For example, relativeURL can hold the name of another HTML or JSP file in the same server directory as the current document. You can also change or add new parameters to the request being forwarded to the new URL with elements:
. . .
Here, parameterName1 is the name of the first parameter you want to set a value for, and parameterValue1 is the value you want to give that parameter, and so on. We'll see how to pass new parameters on to new URLs this way in Day 9, "Using Custom JSP Tags." To create our image map, all we'll need to do is use to send the browser to a new URL, and that's coming up next.
Tip Here's another way to redirect a browser, this time using JavaScript. You can set the href property of the location object to redirect the browser to a new URL. For example, if you want to send the browser to http://www.sun.com, you could send this HTML back to the
browser: location.href="http://www.sun.com".
[ Team LiB ]
[ Team LiB ]
Creating Image Maps This new image map will be based on an image control named imagemap; the code for the Web page that contains it appears in Listing 5.16.
Listing 5.16 Using an Image Map (ch05_16.html) Using Image Maps Using Image Maps
You can see the image map we'll be using in Figure 5.16 (this image is included in the code you can download for this book). The user is about to click the Weather hotspot in this figure.
Figure 5.16. An image map.
All the user has to do is click one of the hotspots you see in Figure 5.16, and the mouse location will be sent to our JSP page, ch05_17.jsp. There we determine the mouse location with the following code fragment. (Note that the code is using the Integer.parseInt method to convert the string text we get from request.getParameter into an integer; see the next topic "Using Named Targets" for all the details on converting text to numeric format, including the Integer.parseInt method.)
You can determine which hotspot the user clicked by checking the mouse location; here the code is checking whether the Weather hotspot was clicked, and if so, forwarding the browser to the Weather page (ch05_19.html):
98 && x < 209 && y > 104 && y < 126) { %>
Here's what the HTML for ch05_19.html looks like:
Weather Weather During the day, light. During the night, dark.
Figure 5.17 depicts what ch05_19.html looks like in the browser after the user clicks the Weather link in the image map.
Figure 5.17. Forwarding to a new URL.
And that's all it takes—now we're redirecting browsers based on image maps. The full code appears in Listing 5.17.
Note Note that this example also includes ch05_18.html up to ch05_23.html, so the next example in the following topic will be ch05_24.jsp.
Listing 5.17 Reading an Image Map (ch05_17.jsp) Reading Image Controls 16 && x < 127 && y > 39 && y < 61) { %> 98 && x < 209 && y > 104 && y < 126) { %> 62 && x < 173 && y > 71 && y < 93) { %> 411 && x < 522 && y > 35 && y < 57) { %> 360 && x < 471 && y > 67 && y < 89) { %> 328 && x < 439 && y > 98 && y < 120) { %>
[ Team LiB ]
[ Team LiB ]
Using Named Targets Here's another important aspect about HTML forms—you can use the element's TARGET attribute to indicate where to send the output of your JSP code. We saw yesterday that there are various predefined settings for this attribute, such as _blank when you want the page sent back from your JSP code to open a new window. You can also use the TARGET attribute to send output from JSP code to another frame in the same browser window, and that's coming up next. In this example, you can create the JSP Calculator, shown in Figure 5.18. In the top frame, you enter two numbers to add, click the = button, and the server will send the results back to the bottom frame as you see in the figure. (This example is also specifically designed to show how to convert the text you read from HTML controls into numeric data types, such as integers—something that's frustrated a lot of JSP programmers.)
Figure 5.18. Using targeted frames with JSP.
You can see the main Web page that displays the two frames in Figure 5.18 in Listing 5.18—note that the code names the bottom frame frame2.
Listing 5.18 Displaying Frames (ch05_24.html)
You can see the calculator part of the application, which goes in the top frame, in Listing 5.19. Note that the code is using the form's TARGET attribute to indicate that the results of our JSP code should go into frame2, the bottom frame (the code sets the caption of the = button to " = ", where is the HTML code for a nonbreaking space, to widen that button instead of just giving it the narrow caption =).
Listing 5.19 The JSP Calculator (ch05_25.html) The JSP Calculator +
Finally, you can see the JSP code that will add the two numbers and display the result in the bottom frame of the application in Listing 5.20.
Listing 5.20 Displaying Numeric Results (ch05_26.jsp) The sum is:
Note that the values we get from request.getParameter are strings, and in Java, you can't just assign strings to integer variables (and you can't use a type cast here, either). Instead, you must use the Integer class's parseInt method, which reads string text and returns an integer like int integer1 = Integer.parseInt(request.getParameter("op1")). Other methods to convert strings into numbers include Float.parseFloat, Double.parseDouble, and so on. You convert the text you read from HTML controls into numbers by using these methods.
Tip How do you convert a number to a text string? You can use the String class's valueOf method like this: String string1 = String.valueOf(number), where number is a number of data type int, float, double, and so on.
Our calculator is fully functional (as long as the only math operation you want to perform is adding integers, that is). Using named frames like this is a cool technique to know—the HTML in the top frame here doesn't change, but the HTML in the bottom frame can be updated from the server whenever you want. [ Team LiB ]
[ Team LiB ]
Getting All Parameter Names We've seen a lot about request objects yesterday and today. There are two more powerful methods we should take a look at—getParameterNames and getHeaderNames—to add even more power to our JSP arsenal. You'll see getParameterNames here, and getHeaderNames in the next section. The getParameterNames method returns a Java Enumeration object holding the names of the parameters being passed to your JSP code. Enumeration objects are like arrays in that they hold collections of items, but you use two methods to move through an enumeration, rather than using an array index (these are the only two methods that enumerations support): boolean hasMoreElements()— Returns true if this enumeration contains more elements that you haven't accessed yet. Object nextElement()— Returns the next element of this enumeration if this enumeration object has at least one more element you haven't accessed yet. Here's a look at an example to see how to use getParameterNames to determine the names of all the parameters sent to our code. Listing 5.21 shows a sample Web page with a text field named text1 and a select control named select1 that you can use to test getParameterNames.
Listing 5.21 Getting Parameter Names (ch05_27.html) Getting Parameter Names Getting Parameter Names Option 1 Option 2 Option 3 Option 4 Option 5
You can see this page in Figure 5.19.
Figure 5.19. A test page to use with the getParameterNames method.
You can see the JSP page that will accept the request parameters we send it and use the getParameterNames method to display the names of those parameters in Listing 5.22. Note that we're using a Java Enumeration object here, using the hasMoreElements method in a while loop, and the nextElement method to recover successive elements from that Enumeration.
Listing 5.22 Reading Parameter Names (ch05_28.jsp) Reading Parameter Names Reading Parameter Names Parameter Names:
You can see the results in Figure 5.20, where we see that the parameters we've sent to the server are select1 and text1, as they should be.
Figure 5.20. Getting parameter names.
[ Team LiB ]
[ Team LiB ]
Getting Request Header Information Another important request object method is getHeaderNames, which gets the names of request headers. These headers store a great deal of information about the browser and the request itself, including such information as the type of browser the user has (see "Using Request Objects" in Day 4, "Reading Data From Web Pages: Buttons and Text Fields,") and what types of data the browser accepts. You can use these header names with another method, getHeader, to get the header's data. Next, you can take a look at the request headers passed to your code to see what they are and what they can offer you. Listing 5.23 shows a simple Web page with just a form and a submit button that you can use.
Listing 5.23 Getting Header Data (ch05_29.html) Getting Header Data Getting Header Data
You can see the JSP page that will read and display the request headers you send to it from ch05_29.html in Listing 5.24.
Listing 5.24 Reading Header Information (ch05_30.jsp) Reading Header Information Reading Header Information Here are the request headers and their data:
You can see the results in Figure 5.21. As you see in that figure, the accept header informs you what kinds of data the browser can accept, the user-agent header tells you what browser the user has, the referer header tells you that the URL of the Web page that the user was just looking at was http://localhost:8080/ch05/ch05_29.html, and so on—all useful information.
Figure 5.21. Getting request header data.
[ Team LiB ]
[ Team LiB ]
Reset Buttons No discussion on HTML forms would be complete without adding reset buttons, and it's appropriate to end our discussion on forms with this control. The user can click a reset button to clear all the data in the control in the form and reset them to their default values. You usually add a reset button to a form next to the submit button:
Using a Reset Button Using a Reset Button Please enter your name:
You can see the reset button in Figure 5.22.
Figure 5.22. Adding a reset button to a form.
And that's all it takes—now the user can reset all the data in the form just by clicking this button. Although not mandatory, it's a nice convenience to have a reset button available in your forms. [ Team LiB ]
[ Team LiB ]
Summary We've seen a great deal today. We took a look at working with some primary HTML controls here—check boxes, radio buttons, and select controls. Check boxes usually operate independently, and it's easy to recover the data from a named check box with the getParameter method. Radio buttons operate in groups, where you give them the same name, but different values; and it's easy to find which radio button is selected by using that name with getParameter to get the value of the selected radio button. We've also seen how to select and deselect both check boxes and radio buttons in code. Check boxes can work in groups, where you give all check boxes the same name but different values. In that case, you use the getParameterValues method, not getParameter, to determine which check boxes are checked. We took a look at using drop-down select controls, as well as multiple-selection select controls, letting the user select various items in those controls and determining which items are selected in code. We've also seen how to use image controls and create server-side image maps. To create an image map, you use the JSP action , which lets you forward a request to another Web page. Image controls act like submit buttons, except that they also pass the mouse location on to the server, which is what makes it possible to implement image maps. We've seen that you can use the element's TARGET attribute to send the output from your JSP code to another frame in a Web page, and we learned how to convert the text data we got from the getParameter method into numbers. We took a look at dissecting the information in a request by getting all the parameter names sent to our JSP code using the getParameterNames method, as well as deciphering the information in the request headers with the getHeaderNames methods. At this point, you've gained a solid foundation in working with requests and HTML controls. You know how to handle data the user sends, and how to return your own Web pages. Now that your code is actually doing something substantial, it's time to start learning how to organize that code using JavaBeans. [ Team LiB ]
[ Team LiB ]
Q&A Q1:
What if the user only selects one item in a multi-select selection control? Should I use getParameter in that case?
A1:
No, you still use getParameters, but the returned enumeration will only have one item in it—the item the user selected.
Q2:
Do image maps send any other request object parameters besides the x and y mouse location?
A2:
No, those are the only two. However, you can use the presence of those parameters to determine that the image map was clicked, which lets you use it as a graphical submit button if you want to.
[ Team LiB ]
[ Team LiB ]
Workshop This workshop tests whether you understand all the concepts you learned today. It's a good idea to master today's concepts by honing your knowledge here before starting tomorrow's material. You can find the answers to the quiz questions in Appendix A.
Quiz 1:
If a control contains multiple selections, what method do you use to get those selections from the request object?
2:
How do you create a radio button group?
3:
What happens if you don't use the SIZE attribute in a select control?
4:
If an image control is named image1, what are the names of the request object parameters holding the x and y mouse locations?
5:
How can you set request object parameters when forwarding a request to another URL?
Exercises 1:
Put what you've learned to work now by enhancing the create-your-own sandwich example (Listing 5.5) to read what check boxes are checked and display a total price for the sandwich (use $1.00 for each check box checked, for example).
2:
Develop a JSP page that displays seven radio controls that let the user display the day of the week (Monday, Tuesday, and so on)—and make sure that the current day of the week's radio button is already selected when the page first appears. You can do that with the Date and Calendar classes you'll see tomorrow—use this page directive at the top of your code: . Then use this code: GregorianCalendar calendar = new GregorianCalendar(); Date date1 = new Date(); calendar.setTime(date1); int day = calendar.get (Calendar.DAY_OF_WEEK);, which leaves the day of the week (Sunday = 1, Monday = 2, and so on) in the variable named day. (For more details on dates, see Listing 6.15, coming up tomorrow!)
[ Team LiB ]
[ Team LiB ]
Day 6. Creating JSP Components: JavaBeans Today, you will learn how to create your own Java classes, as well as JavaBeans. As you develop your Java code, it'll get longer and longer, and after a while, it's not going to fit easily into scriptlets anymore. As it turns out, JSP servers are specially built to let your JSP pages interact with Java classes that you write yourself. Now that our applications are getting more involved, we're going to see how this works. Here's an overview of today's topics: Creating and compiling Java classes Creating Java methods Using Java classes from JSP Creating Java packages Creating and using JavaBeans Creating Bean properties As we'll see, a JavaBean will give you access to properties and methods that you can use in JSP, called exposing. That is, today we're going to be working on the Java part of JavaServer Pages, and you're going to learn how to create compiled Java classes accessible from JSP. Putting your code in compiled Java .class files is a good idea for several reasons. First, it enables you to organize your code and divide it into manageable components, which is especially important as your applications get more involved. Imagine trying to put twenty pages of Java code into a scriplet, for example—it's much easier to handle that code in its own Java file and interact with it as needed in JSP. The JSP server also has to compile those 20 pages of code each time you open the page, so that it also saves a great deal of time to compile your code first and save it in a Java .class file.
Tip You'll see how to create Java classes directly in your JSP code (instead of Java source code files as we'll do today) in Day 8, "Handling Errors," but note that such classes are intentionally kept short—for longer Java code, you usually use a JavaBean.
Creating components such as this is also how JSP supports code reuse. Whether you have, say, 10
different Web pages that use the same code to access a database, it's far more efficient to put that code into a component such as a JavaBean instead of having to repeat that code in each page. Because any number of Web pages can call the Java code in a JavaBean, JavaBeans provide us with components that allow us to reuse our code as needed. Now that we're taking a closer look at Java programming, you'll also learn how to work with some Java utility classes today—the Date and Calendar classes, which enable you to work with and display dates and times, a very popular part of Web programming. That's the program for today—creating Java components that can store your code and that you can interact with in JSP easily, as well as starting to take a look at some of the power available to us in the utility classes built into Java. Today we're going to write actual Java programs, compile them ourselves, and install them on the server, so that we can reach them in JSP. We'll take it step-bystep, and it all starts by creating a Java class.
Tip For the official documentation on JavaBeans, see http://java.sun.com/products/javabeans/docs/.
[ Team LiB ]
[ Team LiB ]
Creating a Java Class In this first example, you'll create a Java class named ch06_01 that will include a method named msg that will return the string "Hello from JSP!". We'll be able to call this method from JSP. To create a Java class, you use the Java class statement, which looks like this in general:
access class classname [extends ...] [implements ...] { [access] [static] type variable1; . . . [access] [static] type variableN; [access] [static] type method1 (parameter_list) { . . . } . . . [access] [static] type methodN (parameter_list) { . . . } }
We'll get familiar with the parts of this statement in more detail in Day 11, "Creating More Powerful JavaBeans." The access term specifies the accessibility of the class or class members to the rest of the program, and can be public, private, or protected. You use the extends and implements keywords with class inheritance, as we'll see in Day 11. To create ch06_01.class, which is a compiled Java class file, you have to start with the actual Java code for this class, which you must store in a file named ch06_01.java. The class in this file will be named ch06_01, and you create it with the Java class statement:
public class ch06_01 { . .
. }
Enter the preceding text into ch06_01.java now. Java source code files must have the extension .java, and we must name this file ch06_01.java because it contains a public class named ch06_01. A public class is accessible to other Java code outside the current file, and you can only have one public class per source code file. If our public class was named addem, we'd need to store it in a Java source code file named addem.java. You can also have private classes, as we'll discuss later—a private class is only accessible in the same file that it's defined in, and you can have as many private classes in a file as you want. Let's get started on the actual Java code here, starting by adding a constructor to our class. [ Team LiB ]
[ Team LiB ]
Creating a Constructor You use a constructor to create an object from a class. In Java, a constructor is a method with the same name as the class itself, so that you can add a constructor to the ch06_01 class like this:
public class ch06_01 { public ch06_01() { } . . . }
Here, the code adds a method named ch06_01 to the ch06_01 class. This particular constructor doesn't do anything; it's a default constructor. Later today, you'll see how you can pass data to a constructor such as this to configure the object—in particular, you'll see how to use the constructor to set the text that the msg method will return. Now it's time to create the msg method.
[ Team LiB ]
[ Team LiB ]
Creating a Method The msg method is simply supposed to return the text "Hello from JSP!", and you don't pass any data to it. This is a method of the ch06_01 class, so you can make its definition part of that class, as you see in Listing 6.1.
Listing 6.1 Creating a Method (ch06_01.java) public class ch06_01 { public ch06_01() { } public String msg() { return "Hello from JSP!"; } }
Note that this method is declared public. A public method such as this can be called from outside a class and any other classes based on this class. We have to make msg a public method so that it'll be accessible outside the ch06_01 class and we can call it from JSP. That's all you need to start—you've created a public class, given it a default constructor, and added a method, msg, to it. The msg method will return our message when it's called, so let's take a look at calling that method from a JSP page now. [ Team LiB ]
[ Team LiB ]
Compiling a Java Class The first step in making the msg method accessible to our JSP code is to compile the file ch06_01.java, creating the file ch06_01.class. This is a step that the JSP server has been taking care of for us, but now that we want to compile a Java class, we'll handle this task ourselves. In Day 1, "Getting Started!," we set our computer's path to include the Java bin directory (such as C:\jdk1.4\bin), which gives us access to the Java tools that we'll use here—in this case, we'll use the Java compiler, javac. Make sure that you're in the same directory as ch06_01.java, and enter javac ch06_01.java at the command prompt to compile ch06_01.java. For example, in Windows, that might look like
C:\ch06>javac ch06_01.java
Tip If you haven't set your path as we discussed in Day 1, you can still use javac to compile Java files if you give the full path of that compiler, which might look like this in Windows: C:\ch06>C:\jdk1.4\binjavac ch06_01.java.
This will compile ch06_01.java and create ch06_01.class in the same directory. This new file, ch06_01.class, is the file we're going to need so that our JSP code can call the msg method.
[ Team LiB ]
[ Team LiB ]
Installing a Compiled Java Class So where can we put ch06_01.class, so that we'll have access to it in a Web page? The examples for today go into the webapps\ch06 directory in the Tomcat directories. As we saw in Day 1, directories like the ch06 directory need a subdirectory named WEB-INF, which itself has two subdirectories, classes and lib:
webapps |____ch06 |____WEB-INF |____classes |____lib
To give the JSP pages in the ch06 directory access to Java .class files, those .class files must go into the ch06\WEB-INF\classes directory. That's all it takes to give your JSP code access to ch06_01.class—just put that file into the ch06\WEB-INF\classes directory. Now we're ready to put this new Java class to work for us, and that's coming up next. [ Team LiB ]
[ Team LiB ]
Using a Compiled Java Class Our new Java class, ch06_01, is now installed—how do you use it in a Web page? You can start off by importing that class into our JSP page with the page directive (that you first saw in Day 1). The page directive's import attribute enables you to import a Java class to make it available to your JSP code. Here's how you can import the ch06_01 class:
Using a JavaBean . . .
Now you can create a new object of this class. This time the code will call this new object messager. This object will enable us to call the msg method to get the "Hello from JSP!" message:
Using a JavaBean Using a JavaBean . . .
Now you have an object of the ch06_01 class, so you can call the msg method to get the message and display it, as you see in Listing 6.2.
Listing 6.2 Calling a Method (ch06_02.jsp)
Using a JavaBean Using a JavaBean The message is:
You can see the results in Figure 6.1, where our call to the msg method was successful.
Figure 6.1. Calling a compiled Java method.
At this point, we've been able to create and compile a Java class, install it where the JSP server can find it, and call a method in that class. Note that we had to specifically import the class. Actually, we can make things a little easier on ourselves if we put our class into a Java package, and that's coming up next. [ Team LiB ]
[ Team LiB ]
Creating a Package Java provides an easy way of organizing your classes using Java packages. And if you use a Java package, you won't have to use the page directive to import your classes in JSP. For example, you can put the Java code just developed into a new class that's part of a Java package. In this case, the package will be named beans. You can create this package in a .java file with the package statement, as you see in Listing 6.3.
Listing 6.3 Creating a Package (ch06_03.java) package beans; public class ch06_03 { public String msg() { return "Hello from JSP!"; } public ch06_03() { } }
Now when you compile this new file, ch06_03.java, you'll get ch06_03.class—but the public class in this .class file is no longer ch06_03. Instead, it's beans.ch06_03, because it's in the beans package. That's how you must refer to it now—as beans.ch06_03. And you can't put it into the classes directory anymore; you must put it into a directory named classes\beans:
webapps |____ch06 |____WEB-INF |____classes | |____beans |____lib
In this way, the disk organization of your Java classes reflects the package you've put your classes in. You separate package names with a dot (.). For example, if we created a package named these.are.my.beans like this
package these.are.my.beans;
public class ch06_03 { public String msg() { . . .
then we'd store our ch06_03.class file in the directory classes\these\are\my\beans:
webapps |____ch06 |____WEB-INF |____classes | |____these | |____are | |____my | |____beans |____lib
Now that we've placed our new class in a package named beans, how do we access that class? That's coming up next. [ Team LiB ]
[ Team LiB ]
Using a Package As far as our JSP page goes, all that's changed is the name of our class; instead of ch06_03, it's now beans.ch06_03. That means all you have to do is use that as the class name, as you see in Listing 6.4.
Listing 6.4 Using a Package (ch06_04.jsp) Using a Java Package Using a Java Package The message is:
Notice that the page directive we used in our earlier non-package example ch06_02.jsp is gone. Now that we've put our Java class into a package, the new directory structure (specifically, the beans subdirectory of the classes directory) tells Tomcat where to find ch06_03.class. We don't need to import any class at all; Tomcat will do that for us automatically. You can see the results in Figure 6.2—now we're organizing our Java classes into packages.
Figure 6.2. Using a class from a Java package.
[ Team LiB ]
[ Team LiB ]
Passing Data to a Constructor So far, our constructor hasn't done anything, but it's time to change that. Usually you use a Java class's constructor to configure an object when you create it, and we'll do that here. For example, we can pass the string we want the msg method to return to the constructor, storing that string internally. Here's how it might look—in this case, the constructor for this class takes a String argument and stores it in an internal variable named msg. The msg method reads the text and returns it when you call this method; you can see how it all looks in Listing 6.5.
Listing 6.5 Returning Text from a Method (ch06_05.java) package beans; public class ch06_05 { String msg; public ch06_05(String message) { msg = message; } public String msg() { return msg; } }
Now you can pass data to this new constructor when you create a new object of this Java class, as you can see in Listing 6.6.
Listing 6.6 Using a Constructor (ch06_06.jsp) Using a Constructor Using a Constructor
The message is:
And that's all there is to it—now you're able to configure the objects you create from Java classes with a constructor. You can see the results in Figure 6.3.
Figure 6.3. Using a constructor.
Actually, the Java classes we've been developing so far are not technically JavaBeans, they're just classes. A JavaBean must also expose properties. JSP makes it easy to interact with Java classes and JavaBeans using the element. You can use this element to create objects from JavaBeans (and then set and get property values using that object), and an in-depth look at this element is coming up next. [ Team LiB ]
[ Team LiB ]
Using You've seen that you can create objects from Java classes without any special effort. But you can also use the element to do the same thing. The element is a convenience element in JSP that enables you to create an object of a Java class and give it an ID. You can then use that ID with two other elements, and , to get and set property values. Let's take a look at the syntax of the element. As discussed in the Introduction, this book uses the conventions of Java documentation for syntax such as this—here, | means "or," items in bold are default settings, items in square brackets ([ and ]) are optional, and you must select one item of those that appear in curly braces ({ and } ):
| > other elements }
Let's take a look at the attributes of this element: id="ID"— A variable that identifies the bean. You can use the variable name in expressions or scriptlets in the JSP page. If the bean has already been created by another element, the value of id must match the value of id used when the bean was created. scope="page|request|session|application"— The scope in which the bean exists. The default value is page. We'll see more on scope tomorrow. The page scope means you can use the bean within the JSP page. The request scope means you can use the bean from any JSP page processing the same request. The session scope means you can use the bean from any JSP page in the same session as the JSP page that created the bean, as you'll see tomorrow. The application scope means you can use the bean from any JSP page in the same application as the JSP page that created the bean, as you'll see tomorrow. class="package.class"— Creates a bean from a class. The class must have a public noargument constructor. type="package.class"— If the bean already exists, this gives the bean a data type other than the class it was created from. The type must be a class or interface that the bean is already based on. beanName="{package.class | }" type="package.class"— Creates a
bean from a class. When you use beanName, the bean is created by the java.beans.Beans.instantiate method, which we're not going to cover here. other elements— You can include other elements inside the body of , such as the and elements. Here's an example that puts to work. We've already seen this code, which creates an object from ch06_03.class and calls that object's msg method:
The message is:
Here's how to do the same thing with . In this case, you can create a new bean with the ID bean1 from the same class, ch06_03.class (internally, Java actually uses the new operator to create this new object). Then you can refer to that bean with that ID—for example, you can call the bean's msg method as bean1.msg, as you see in Listing 6.7.
Listing 6.7 Using a Bean (ch06_07.jsp) Using <jsp:useBean> Using <jsp:useBean> The message is:
You can see this Web page in Figure 6.4, where we've used to create a new Java object.
Figure 6.4. Using the element.
The element is designed to be used with two other elements—the and elements, which enable you to work with bean properties. We'll look at how to create a property in a JavaBean next. [ Team LiB ]
[ Team LiB ]
Creating a Read-Only Property A property is a data item that you store in a JavaBean. For example, suppose you have a property named color. You can store various strings, such as red, blue, and so on in the color property, and the bean can use that property's value to configure the HTML it returns from other methods. To support a JavaBean property, you use get and set methods. For example, for the color property, you'd add getColor and setColor methods to the bean. Note that you capitalize "color" in getColor and setColor, even though the actual property name is color—Java will expect these methods to exist, so it can work with the color property. If your property was named myFavoriteProperty, you would use the get and set methods getMyFavoriteProperty and setMyFavoriteProperty. In this case, you can add a property named message that returns our message from the bean. You can start by only adding a get method, which means this property will be read-only (there's no set method to set its value). In particular, this code will enable Java to read the value of this property with a method named getMessage, as you see in Listing 6.8.
Listing 6.8 Reading a Property Value (ch06_08.java) package beans; public class ch06_08 { private String message = "Hello from JSP!"; public String getMessage() { return message; } public ch06_08() { } }
Note that in addition to the getMessage method, the code has also declared a variable with the same name as the property, message. Java will expect to find a variable with the same name as the property this way, because that tells Java what the data type of the property is. You might also note that the code has declared the string variable message to be private here. That means it's not accessible outside objects of this class—instead, you must access its value with the getMessage method. If you made this variable public instead (such as this: public String message = "Hello from JSP!";), you can access it in JSP code directly as object.message, as in
this code:
The message is:
However, this gives the JSP code direct access to the message variable, which means it can change that variable's value. To avoid such tampering, it has become standard in JavaBeans to use get and set methods to create a well-defined way of accessing property values—for example, if some JSP code tried to set a property named height to a negative value, the property's set method can detect that and not store that value in the property. That's all we need to let Java read the value of this property. How do you read that value in JSP? You use the element. [ Team LiB ]
[ Team LiB ]
: Getting a Property Value
You use the element to return the value of a property. Here's the syntax for this element:
Here are the attributes of this element: name="ID"— This refers to the name of the bean as declared in a element. property="propertyName"— The name of the bean property whose value you want. The property is declared as a variable in a bean and must have a corresponding get method. Here's how you can use to get the value of the message property—all you have to do is use to create an object named, say, bean1, and then get the value of the message property, as you see in Listing 6.9.
Listing 6.9 Getting a Property Value (ch06_09.jsp) Getting a Property Value element> element> element> Getting a Property Value The message is:
You can see the results in Figure 6.5.
Figure 6.5. Getting a property's value.
Now we can get the value of a property in a JavaBean. It's worth noting that you can also use inside a element:
The message is:
Note, however, that this will only work if the enclosing element creates the object you're accessing with ; if the object already exists (that is, was created by another element), the elements in the element are not executed. That's how to get the value of a property—now what about setting a property's value? [ Team LiB ]
[ Team LiB ]
Creating a Read/Write Property To let Java set the value of a property, you can use a set method. For example, to let our JSP code set the message our bean will return, we can add a method named setMessage to set the value of the message property. You can see what that might look like in Listing 6.10.
Listing 6.10 Creating a Property (ch06_10.java) package beans; public class ch06_10 { private String message = "Hello from JSP!"; public void setMessage(String msg) { this.message = msg; } public String getMessage() { return this.message; } public ch06_10() { } }
Note the keyword this here. In Java, this keyword always refers to the current object. In other words, this.message refers to the private variable message created and stored in this object:
private String message = "Hello from JSP!"; public void setMessage(String msg) { this.message = msg; }
The this keyword is a handy one to know now that you're creating Java objects—you can always use it in code to refer to the current object. As you've seen, it's not technically necessary to use the this keyword when you're referring to an object's data from code in that object (in fact, Java will use it
automatically if you omit it), but you'll sometimes see it done for clarity. It can also prevent ambiguity when a function argument has the same name as a variable. To actually set the value of the message property in JSP code, you can use the element. [ Team LiB ]
[ Team LiB ]
: Setting Property Values
You use to set property values in JSP. You can pass your own values, or automatically pass values from the request object. Here's the syntax of this element:
Here are the attributes of this element: name="ID"— The name of a bean that has already been created or located with a element. property="*"— Stores all of the values of request object parameters in bean properties. The names of the bean properties must match the names of the request parameters. Note that the request parameters are always strings, so Java converts them to the type of your property with methods such as Double.valueOf(String) automatically. property="propertyName" [ param="parameterName" ]— Sets one bean property to the value of one request parameter. If the bean property and the request parameter have different names, you must specify both property and param. If they have the same name, you can specify property and omit param. property="propertyName" value="{string | }"— Sets one bean property to a specific value. The value can be a String or an expression that is evaluated at runtime. If the value is a String, it is converted to the bean property's data type automatically. Here's an example that puts to work using the set method setMessage that we've added to our example. In this case, we'll first display the default message that this property holds, and then use to set it to a new message, as you see in Listing 6.11.
Listing 6.11 Setting a Property Value (ch06_11.jsp) Setting a Property Value
Setting a Property Value The message is: Now the message is:
And that's all it takes—you can see the results in Figure 6.6, where we see that we were indeed able to set a bean's property.
Figure 6.6. Setting a property value.
[ Team LiB ]
[ Team LiB ]
Creating Private Methods Here's one more thing we should note in passing. We've stored our property using a private variable in our Java code—doing so helps hide that data from external tampering. You can also create private methods that are purely internal to the current object, and cannot be called from outside the object. This is a good idea if you're using methods that you only want to call from inside the object. Such methods might help in performing internal calculations, for example. Using private methods can help organize your objects, wrapping up all their functionality into a self-contained entity. Here's an example that shows how this works—in this case, you can just add a private method named privateMessage that will return the object's message, and call the method in the message property's get method, as you see in Listing 6.12.
Listing 6.12 Using a Private Method (ch06_12.java) package beans; public class ch06_12 { private String message = "Hello from JSP!"; public void setMessage(String msg) { this.message = msg; } public String getMessage() { return privateMessage(); } private String privateMessage() { return this.message; } public ch06_12() { } }
You can see a JSP page that uses this new class in Listing 6.13.
Listing 6.13 Calling a Private Method (ch06_13.jsp) Calling a Private Method Calling a Private Method The message is: Now the message is:
You can see the results in Figure 6.7—now we've created private methods purely internal to a Java object.
Figure 6.7. Using private methods.
Now that you're digging into the depths of Java, it's a good idea to take a look at the first of several Java utility classes that you'll see throughout the book. These utility classes are an important part of Java programming. Here you'll see the Date class, which is in the package named java.util.
[ Team LiB ]
[ Team LiB ]
Java Utility Classes: Working with Dates The Date class enables you to create objects that represent a specific instant in time. This class is a popular one in Java programming among JSP programmers, because it enables you to keep track of dates and times. For example, you can see a JSP page that displays the date and time in Listing 6.14 .
Listing 6.14 Using the Date Class (ch06_14.jsp ) Using the Date Class Using the Date Class The date is: .
You can see the results in Figure 6.8 .
Figure 6.8. Getting the date.
Before Java version 1.1, you could also use the Date class to get the day of the month, year, hour, and so on separately, but that's gotten more complex. Now, the Calendar class should be used to get that kind of information. The original methods in the Date class are deprecated, as you'll see. You should know that there are certain conventions used to represent months, days of the month, and so on, in the Date class: A month is represented by an integer from 0 to 11; 0 is January, 1 is February, and so on, up to 11, which is December. A date (day of month) is represented by an integer from 1 to 31. An hour is represented by an integer from 0 to 23. The hour from midnight to 1 a.m. is hour 0, and the hour from noon to 1 p.m. is hour 12 , and so on. A minute is represented by an integer from 0 to 59. A second is represented by an integer from 0 to 61 (the values 60 and 61 do occur! But only for leap seconds). You can see the Date class's methods in Table 6.1 .
Date() Creates a Date object and initializes it to the time it was created. Date(int year, int month, int date) Deprecated. Replaced by Calendar.set( year + 1900 , month , date ) or GregorianCalendar( year + 1900 , month , date ) .
Date(int year, int month, int date, hrs, int min) Deprecated. Replaced by Calendar.set(year + int 1900, month, date, hrs, min) or GregorianCalendar(year + 1900, month, date, hrs, min) . Date(int year, int month, int date, hrs, int min, int sec) Deprecated. Replaced by Calendar.set( year + int 1900, month , date , hrs , min , sec ) or GregorianCalendar(year + 1900, month, date , hrs, min, sec) . Date(long date) Creates a Date object and initializes it to the given number of milliseconds since January 1, 1970, 00:00:00 GMT. Date(String s) Deprecated. Replaced by DateFormat.parse( String ) . boolean after(Date when) Tests if this date is after the specified date. boolean before(Date when) Tests if this date is before the specified date. Object clone() Returns a copy of this object. int compareTo(Date anotherDate) Compares two Date s for ordering. int compareTo(Object o) Compares this Date to another object. boolean equals(Object obj) Compares two dates for equality. int getDate() Deprecated. Replaced by Calendar.get(Calendar.DAY_OF_MONTH) . int getDay() Deprecated. Replaced by Calendar.get(Calendar.DAY_OF_WEEK) . int getHours() Deprecated. Replaced by Calendar.get(Calendar.HOUR_OF_DAY) .
int getMinutes() Deprecated. Replaced by Calendar.get(Calendar.MINUTE) . int getMonth() Deprecated. Replaced by Calendar.get(Calendar.MONTH) . int getSeconds() Deprecated. Replaced by Calendar.get(Calendar.SECOND) . long getTime() Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object. int getTimezoneOffset() Deprecated. Replaced by Calendar.get(Calendar.ZONE_OFFSET) and Calendar.get(Calendar.DST_OFFSET) . int getYear() Deprecated. Replaced by Calendar.get(Calendar.YEAR) - 1900 . void setDate(int date) Deprecated. Replaced by Calendar.set(Calendar.DAY_OF_MONTH, int date) . void setHours(int hours) Deprecated. Replaced by Calendar.set(Calendar.HOUR_OF_DAY, int hours) . void setMinutes(int minutes) Deprecated. Replaced by Calendar.set(Calendar.MINUTE, int minutes) . void setMonth(int month) Deprecated. Replaced by Calendar.set(Calendar.MONTH, int month) . void setSeconds(int seconds) Deprecated. Replaced by Calendar.set(Calendar.SECOND, int seconds) . void setTime(long time) Sets this Date object to represent time milliseconds after January 1, 1970 00:00:00 GMT. void setYear(int year) Deprecated. Replaced by Calendar.set(Calendar.YEAR, year + 1900) . String toGMTString()
Deprecated. Replaced by DateFormat.format(Date date) , using a GMT time zone. String toLocaleString() Deprecated. Replaced by DateFormat.format(Date date) . String toString() Converts this Date object to a String . long UTC(int year, int month, date, int hrs, int min, int sec) Deprecated. Replaced by Calendar.set(year + int 1900, month, date, hrs, min, sec) or GregorianCalendar(year + 1900, month, date, hrs, min, sec) , using a UTC time zone, followed by Calendar.getTime().getTime() .
Table 6.1. Date Class Methods Method
Does This
As you can see in Table 6.1 , many of the Date class's methods that let you get the hour, day, minute, and so on are now deprecated in favor of the Calendar class. The reason is that the Date class wasn't prepared for internationalization. Using the Date class together with various Calendar classes, on the other hand, enables you to work with times in any international locale.
You don't actually use the Calendar class directly, you use a class derived from it for specific locales. Currently, there's only one such class, GregorianCalendar . Say, for example, that you want to get the current year. You can do that by creating a GregorianCalendar object and passing its setTime method a Date object. Then to get the year in that Date object, you can use the GregorianCalendar object's get method, passing it the Calendar.YEAR field like this:
GregorianCalendar calendar = new GregorianCalendar(); Date date1 = new Date(); calendar.setTime(date1); out.println("Calendar.YEAR is " + calendar.get(Calendar.YEAR) + "");
The fields of a class are its data members—that is, variables available publicly or to classes based on the current class. When a field name is in capital letters (like YEAR ), that's a Java convention—it means the field is a constant, and its value can't be changed (these are static data members, and you declare them in Java with the static keyword). You can see the fields of the Calendar class in Table 6.2 . You can also set the time in a GregorianCalendar object using the set method such as in the following, where the code is setting the time to 23:59 (one minute before midnight) on 11/31/2005:
calendar.set(2005, 11, 31, 23, 59);
int AM Value of the AM_PM field for the period of the day from midnight to just before noon. int AM_PM Indicates whether the HOUR is before or after noon. int APRIL Value of the MONTH field for April. int AUGUST Value of the MONTH field for August. int DATE Use in get and set for the day of the month. int DAY_OF_MONTH Use in get and set for the day of the month. int DAY_OF_WEEK Use in get and set for the day of the week. int DAY_OF_WEEK_IN_MONTH Use in get and set for the number of the day of the week within the current month. int DAY_OF_YEAR Use in get and set for the day number within the current year. int DECEMBER Value of the MONTH field for December. int DST_OFFSET Use in get and set for the daylight savings offset in milliseconds. int ERA Use in get and set for the era (such as A.D. or B.C. in the Julian calendar). int FEBRUARY Value of the MONTH field for the second month of the year. int FIELD_COUNT
The number of distinct fields recognized by get and set . protected int[] fields The field values for the currently set time for this calendar. int FRIDAY Value of the DAY_OF_WEEK field for Friday. int HOUR Use in get and set for the hour of the morning or afternoon. int HOUR_OF_DAY Use in get and set for the hour of the day. protected boolean[] isSet The flags that tell whether a specified time field for the calendar is set. protected boolean isTimeSet True if the value of time is valid. int JANUARY Value of the MONTH field for January. int JULY Value of the MONTH field for July. int JUNE Value of the MONTH field for June. int MARCH Value of the MONTH field for March. int MAY Value of the MONTH field for May. int MILLISECOND Use in get and set for the millisecond within the second. int MINUTE Use in get and set for the minute within the hour.
int MONDAY Value of the DAY_OF_WEEK field for Monday. int MONTH Use in get and set for the month. int NOVEMBER Value of the MONTH field for November. int OCTOBER Value of the MONTH field for October. int PM Value of the AM_PM field for the period of the day from noon to just before midnight. int SATURDAY Value of the DAY_OF_WEEK field for Saturday. int SECOND Use in get and set for the second within the minute. int SEPTEMBER Value of the MONTH field for September. int SUNDAY Value of the DAY_OF_WEEK field for Sunday. int THURSDAY Value of the DAY_OF_WEEK field for Thursday. long time The currently set time for this calendar, expressed in milliseconds after January 1, 1970, 0:00:00 GMT. int TUESDAY Value of the DAY_OF_WEEK field for Tuesday. int UNDECEMBER Value of the MONTH field for the thirteenth month of the year. int WEDNESDAY
Value of the DAY_OF_WEEK field for Wednesday. int WEEK_OF_MONTH Use in get and set for the week number within the current month. int WEEK_OF_YEAR Use in get and set for the week number within the current year. int YEAR Use in get and set for the year. int ZONE_OFFSET Use in get and set for the offset from GMT in milliseconds.
Table 6.2. Calendar Class Fields Field
Meaning
Here's an example putting these fields to work—you can find the current year, month, and so on and then reset the Calendar object to 23:59 on 11/31/2005 and display the various Calendar fields again, as you see in Listing 6.15 .
Listing 6.15 Using the Calendar Class (ch06_15.jsp ) [View full width]
Fields of the Calendar Class Fields of the Calendar Class
You can see the results in Figure 6.9 , where you see the year, month, day, and so on.
Figure 6.9. Fields of the Calendar class.
[ Team LiB ]
+ ""; + "";
[ Team LiB ]
Summary Today you learned how to create Java classes, and JavaBeans that support properties. In particular, you learned how to use the Java class statement to create Java classes. You also saw that you can place a constructor into a class, and that you can pass data to that constructor. The element enables you to create an object from a Java class or JavaBean. We've seen that you can use this element to name an object when it's created, so that it's accessible elsewhere in your code. The element enables you to get the value of the property of a bean. The element enables you to set the value of a bean's properties, including letting you set properties of the same name as request parameters automatically. Finally, the Date class enables you to store dates and times. To access the individual day, month, year, and other fields in a Date object, you use a class based on the Calendar class, such as the GregorianCalendar class.
[ Team LiB ]
[ Team LiB ]
Q&A Q1:
As a JSP programmer, do I need to use JavaBeans?
A1:
No. You can get along fine without them, but when your code gets past a certain size, it's awkward to store in a Web page. JavaBeans help you organize your code, and gives you easier access to Java directly.
Q2:
Can I use the request object in a JavaBean?
A2:
No, that object is not accessible in a JavaBean by default. However, you can pass the request object to a JavaBean if you set up a method in the bean to accept that object—see the Exercises for today.
[ Team LiB ]
[ Team LiB ]
Workshop This workshop tests whether you understand all the concepts you learned today. It's a good idea to master today's concepts by honing your knowledge here before starting tomorrow's material. You can find the answers to the quiz questions in Appendix A.
Quiz 1:
What are two access specifiers you can use in Java classes?
2:
How do you invoke the Java compiler?
3:
What is the name of the directory in which you place .class files so that they're accessible from JSP?
4:
You can include and elements inside a element. Under what circumstances are those elements not executed?
5:
Why was the Date class deprecated?
Exercises 1:
Create a new JavaBean and pass the request object to a method of that bean (this object is an object of the Java javax.servlet.http.HttpServletRequest class). Using the request.getParameter method, recover some text from a text field and pass it back to a JSP page using another method, and display that text.
2:
Using Date and Calendar objects, put together a JSP page that displays the number of days remaining until your next birthday. (Hint: the DAY_OF_YEAR field will be useful here.)
[ Team LiB ]
[ Team LiB ]
Day 7. Tracking Users with Sessions and Cookies Today you'll learn about one of the most popular uses of JSP—tracking users with sessions and cookies. Tracking users is a perennial problem; when a user looks at your Web page, has that user been there before? Will you be remembering something about her? Will you remember her present purchases and be checking them out, displaying their total cost? Will you be customizing her Web page in ways that she's specified in the past? Today you'll see several ways of tracking users, including the following: Hidden text— Using hidden controls in a Web page is the easiest way of associating some information with the user that's not directly accessible to him. However, the hidden text can be seen if the user looks at the HTML for the Web page directly. Cookies— This is probably the most common way of tracking users on the Internet. You can store information in a user's computer using cookies, and retrieve it when you need it. You can also specify how long the cookie should exist before being deleted by the browser. Sessions— Sessions are something the server offers us to support user tracking, and they're great, although they can take up a lot of resources on the server. Sessions let you preserve data between accesses to a Web page by the same user. Applications— Applications are much like sessions, as you'll see, but they're more general—you can share data between all the JSP pages in a site using applications. In other words, unlike sessions, applications can be used to track multiple users at the same time. Sessions, applications, and JavaBeans— You can also set JavaBeans so they'll be included in a session or application. Normally, the data in a JavaBean is reset each time the user accesses a page and creates an object from that bean, but you can include the bean in a session or application so its data is preserved between accesses by the same user. The first step is to use HTML hidden controls. [ Team LiB ]
[ Team LiB ]
Using Hidden Controls Using HTML hidden controls is an easy way to store data in a Web page. For example, in this JSP page, the code will let the user set the text to store in a hidden control in a text field:
Reading Hidden Controls Reading Hidden Controls . . .
The code stores the text the user types in the hidden control, as you can see in Listing 7.1.
Listing 7.1 Reading Hidden Controls (ch07_01.jsp) Reading Hidden Controls Reading Hidden Controls
You can see this page in Figure 7.1, where the user has entered some text and is about to click the Set Hidden Text button.
Figure 7.1. Setting hidden text.
When the user clicks the button, the JSP code stores the text she's entered in a hidden control and displays that text, as you see in Figure 7.2.
Figure 7.2. Getting hidden text.
The user can also take a look at the data in the hidden field directly—all she has to do is to view the HTML source of the page you see in Figure 7.2 (using the View, Source menu item in Internet Explorer, or the View, Page Source menu item in Netscape Navigator). Here's what that HTML source looks like—note the hidden control's text:
Reading Hidden Controls Reading Hidden Controls The hidden text is:Hello there!
Hidden controls are fine as far as they go, but there are a number of obvious problems here—you can't store data in a secure way, and you can't store data between sessions. However, you can get around those problems with cookies. You might not be surprised to learn that there's a class you use to work with cookies in JSP—the
cookie class. [ Team LiB ]
[ Team LiB ]
The Cookie Class Cookies— you either love them or hate them. They're small text strings you store on a user's computer. In the early days of cookies, people were very suspicious of them, but the truth is that they're simply text and can't cause problems (unless there are security problems in the user's browser that have not yet been exploited by hackers).
Tip Although cookies are widely regarded as safe, many users are still wary of them, and have instructed their browsers not to accept them. If you can't set a cookie in the client browser you're working with, you might try another method of storing data, such as hidden controls. Technically, a browser is expected to support 20 cookies for each Web server; about 300 cookies total—and might limit the size of each cookie to 4KB of text.
A cookie's value can identify a user, so they are commonly used for session management. Cookies have a name and a value, and you can use methods of the Cookie class (the full name, including the Java package, is javax.servlet.http.Cookie) to get access to that data. You can also include comments in cookies and set their maximum possible ages. Your JSP code sends cookies to the browser by using the HttpServletResponse.addCookie method. This method stores data in the HTTP response headers it sends to the browser, including the cookies you're creating. The browser returns cookies to you by storing data in HTTP request headers. You can get cookie data using the HttpServletRequest.getCookies method, as you'll see in the upcoming examples. You'll see how this all works in detail in today's work. You can see the methods of Cookie objects (that is, the javax.servlet.http.Cookie class) in Table 7.1.
Table 7.1. javax.servlet.http.Cookie Methods Method
Does This
Cookie(java.lang.String name, java.lang.String value)
Creates a cookie with a given name and value.
java.lang.Object clone()
Returns a copy of the cookie.
java.lang.String getComment()
Returns the cookie's comment, or null if the cookie has no comment.
Method
Does This
java.lang.String getDomain()
Returns the domain name for the cookie.
int getMaxAge()
Returns the maximum age of the cookie, in seconds. A value of -1 indicates the cookie will exist until browser shutdown.
java.lang.String getName()
Returns the name of the cookie.
java.lang.String getPath()
Returns the path on the server so that the browser returns the cookie.
boolean getSecure()
Returns true if the browser is sending cookies only over a secure protocol.
java.lang.String getValue()
Returns the value of the cookie.
int getVersion()
Returns the version of the protocol for the cookie.
void setComment(java.lang.String comment)
Sets a comment that describes a cookie's purpose.
void setDomain(java.lang.String domain)
Specifies the domain for the cookie.
void setMaxAge(int expiry)
Sets the maximum age of the cookie in seconds.
void setPath(java.lang.String uri)
Sets the path for the cookie (that is, the path by which the browser will send the cookie).
void setSecure(boolean flag)
Indicates to the browser if cookies should only be sent using a secure protocol (such as HTTPS).
void setValue(java.lang.String value) Assigns a new value to a cookie after the cookie is created. void setVersion(int version)
Sets the version of the cookie protocol for the cookie.
So how do you create a cookie? You use the addCookie method of the HttpServletResponse class, and that class is coming up next. [ Team LiB ]
[ Team LiB ]
The HttpServletResponse Interface To create cookies, you need to use the addCookie method of javax.servlet.http.HttpServletResponse interface. What's a Java interface? You can think of an interface as a class that defines method names, but not their code. You can't create objects directly using an interface. Instead, you must base a class on that interface—the interface only defines what data members and methods that class will have. As we'll see in Day 11, "Creating More Powerful JavaBeans," using interfaces is as close as you can come in Java to basing a class on more than one other class (in object-oriented programming terms, interfaces represent Java's support for multiple inheritance, as we'll see in Day 13, "Creating More Powerful Servlets"). So where does that leave you? Fortunately, the server has done all the work you'll need here—one of the built-in objects available to you in your JSP code is the response object (see "The JSP Programming Environment" in Day 2, "Handling Data and Operators"), and this is a pre-built object based on the javax.servlet.http.HttpServletResponse interface. Just as you use the request object to see what data the user has sent to you, you can use the response object to send data back to the user. In this case, you'll use this object to send cookies back to the browser, which will store them. You can see the fields of the javax.servlet.http.HttpServletResponse interface in Table 7.2, and the methods of this interface in Table 7.3. Because the response object is built on this interface, it shares all the methods of the interface, and you'll see how to put them to work in the next topic, creating your own cookies with the addCookie method. You use the various field values in Table 7.2 if you want to send a status report back to the browser, as with the sendError or setStatus methods (which we won't do here).
Note The convention for fields is that if its name is in capital letters, it's a read-only constant whose value doesn't change.
Table 7.2. HttpServletResponse Fields Method
Does This
int SC_ACCEPTED
Indicates that a request was accepted for processing, but was not completed.
Method
Does This
int SC_BAD_GATEWAY
Indicates that the HTTP server received an invalid response from a server it consulted when acting as a proxy or gateway.
int SC_BAD_REQUEST
Indicates the request sent by the client was incorrect.
int SC_CONFLICT
Indicates that the request cannot be completed because of a conflict with the current state of the resource.
int SC_CONTINUE
Indicates the client can continue.
int SC_CREATED
Indicates the request succeeded and created a new resource on the server.
int SC_EXPECTATION_FAILED
Indicates that the server cannot meet the request in the Expect request header.
int SC_FORBIDDEN
Indicates the server cannot complete the request.
int SC_GATEWAY_TIMEOUT
Indicates that the server did not receive a response from a gateway or proxy server in time.
int SC_GONE
Indicates that the resource is no longer available.
int SC_HTTP_VERSION_NOT_SUPPORTED
Indicates that the server does not support the HTTP protocol version used in the request.
int SC_INTERNAL_SERVER_ERROR
Indicates an error inside the HTTP server.
int SC_LENGTH_REQUIRED
Indicates that the request cannot be handled without a specified content length.
int SC_METHOD_NOT_ALLOWED
Indicates that the method specified in the Request-Line is not allowed.
int SC_MOVED_PERMANENTLY
Indicates that the resource has moved to a new location.
int SC_MOVED_TEMPORARILY
Indicates that the resource has temporarily moved to another location.
int SC_MULTIPLE_CHOICES
Indicates that the resource corresponds to any one of a set.
int SC_NO_CONTENT
Indicates that the request was successful but there was no new content to return.
int SC_NON_AUTHORITATIVE_INFORMATION
Indicates that the meta information sent by the browser did not come from the server.
int SC_NOT_ACCEPTABLE
Indicates that the resource identified by the request was not acceptable.
int SC_NOT_FOUND
Indicates that the requested resource was not available.
Method
Does This
int SC_NOT_IMPLEMENTED
Indicates the HTTP server does not support the request.
int SC_NOT_MODIFIED
Indicates that a GET operation found that the resource was available and not modified.
int SC_OK
Indicates the request succeeded.
int SC_PARTIAL_CONTENT
Indicates that the server has fulfilled the partial GET request.
int SC_PAYMENT_REQUIRED
Reserved for future use.
int SC_PRECONDITION_FAILED
Indicates that the precondition given in a request header field failed.
int SC_PROXY_AUTHENTICATION_REQUIRED
Indicates that the client must authenticate itself with the proxy.
int SC_REQUEST_ENTITY_TOO_LARGE
Indicates that the request entity is larger than the server can process.
int SC_REQUEST_TIMEOUT
Indicates that the request timed out.
int SC_REQUEST_URI_TOO_LONG
Indicates that the Request-URI field is too long.
int SC_REQUESTED_RANGE_NOT_SATISFIABLE
Indicates that the server cannot serve the requested data range.
int SC_RESET_CONTENT
Indicates that the agent will reset the display of the document.
int SC_SEE_OTHER
Indicates that the response to the request can be found under a different URI.
int SC_SERVICE_UNAVAILABLE
Indicates that the HTTP server is overloaded.
int SC_SWITCHING_PROTOCOLS
Indicates the server is switching protocols.
int SC_TEMPORARY_REDIRECT
Indicates that the requested resource is temporarily at a different URI.
int SC_UNAUTHORIZED
Indicates that the request needs HTTP authentication.
int SC_UNSUPPORTED_MEDIA_TYPE
Indicates that the request is in a format not supported by the requested resource.
int SC_USE_PROXY
Indicates that the requested resource must be accessed through the proxy.
Table 7.3. HttpServletResponse Methods Method
Does This
Method
Does This
void addCookie(Cookie cookie)
Adds the given cookie to the response.
void addDateHeader(java.lang.String name, long date)
Adds a response header with the given name and date.
void addHeader(java.lang.String name, java.lang.String value)
Adds a response header with the given name and value.
void addIntHeader(java.lang.String name, int value)
Adds a response header with the given name and integer value.
boolean containsHeader (java.lang.String Returns a Boolean value indicating if a response name) header has been set. java.lang.String encodeRedirectUrl (java.lang.String url)
Deprecated. As of servlet specification version 2.1, use encodeRedirectURL (String url) instead.
java.lang.String encodeRedirectURL (java.lang.String url)
Encodes the specified URL for use in the sendRedirect method.
java.lang.String encodeUrl (java.lang.String url)
Deprecated. As of servlet specification version 2.1, use encodeURL(String url) instead.
java.lang.String encodeURL (java.lang.String url)
Encodes the specified URL by including the session ID in it.
void sendError(int sc)
Sends an error response to the client using the given status field value.
void sendError(int sc, java.lang.String msg)
Sends an error response to the client using the given field value and text.
void sendRedirect (java.lang.String location)
Sends a temporary redirect response to the browser using the given URL.
void setDateHeader(java.lang.String name, long date)
Sets a response header with the given name and date.
void setHeader(java.lang.String name, java.lang.String value)
Sets a response header with the given name and value.
void setIntHeader(java.lang.String name, Sets a response header with the given nameand int value) integer value. void setStatus(int sc)
Sets the status code for this response.
void setStatus (int sc, java.lang.String Deprecated. As of servlet specification version sm) 2.1, use setStatus(int) to send an error with a description. [ Team LiB ]
[ Team LiB ]
Creating a Cookie This next example will put all this new technology to work. Here, the code will create a cookie and place some text in it, and another page will read the cookie and display that text. To create the cookie, you use the Cookie class's constructor, passing it the name of the cookie (which will be message here) and the text in the cookie (which will just be "Hello!" in this case). You can also set the length of time the cookie will exist on the user's computer with the setMaxAge method, which you pass a value in seconds to—to make the cookie last for a day, you can pass a value of 24 * 60 * 60 this way:
Setting a Cookie Setting a Cookie . . .
That creates the cookie, but doesn't install it in the browser—to do that, you use the response object's addCookie method this way:
Setting a Cookie Setting a Cookie . .
.
That installs the cookie in the browser. You can also include a link to the page that will read the cookie, as you see in Listing 7.2.
Listing 7.2 Setting a Cookie (ch07_02.jsp) Setting a Cookie Setting a Cookie Read the cookie
You can see this page in Figure 7.3, where it's already set its cookie in the browser. The next step is to read that cookie's information back in.
Figure 7.3. Setting a cookie.
[ Team LiB ]
[ Team LiB ]
Reading a Cookie To store a cookie in the user's computer, you use the request object's getCookies method. This method returns an array of Cookie objects (or null if there are no cookies) So how do you read the cookie named message? You start with the getCookies method, creating an array of Cookie objects:
Reading a Cookie Reading a Cookie -->
[ Team LiB ]
Using Applications A session enables you to track one user at a time—an application enables you to track all JSPs in the same site, no matter how many users are using them. To access the current application, you can use the built-in JSP application object. Like the session object, the application object is based on the javax.servlet.http.HttpSession interface. In the previous example, you saw how to create a session attribute named counter , which stores the number of times the user has visited the page in the current session. In the same way, you can create an application attribute named applicationCounter that holds the total number of times anyone in the same application has viewed a JSP page:
Integer applicationCounter = (Integer)application.getAttribute("applicationCounter"); if (applicationCounter == null) { applicationCounter = new Integer(1); } else { applicationCounter = new Integer(applicationCounter.intValue() + 1); } application.setAttribute("applicationCounter", applicationCounter);
You can see this at work in Listing 7.6 , where the code supports a counter for the number of visits in the current session, and in the current application.
Listing 7.6 Using the Application Object (ch07_06.jsp ) [View full width]
Using the Application Object Using the Application Object You have visited this page times. This page has been visited by all users times.
In this example, the session counter keeps track of the number of times a user has visited the page, and the application counter keeps track of the number of times all users have accessed the page. This isn't particularly easy to see on the same computer, because Tomcat will count you as the same user. However, you can get around that if you happen to have different browsers. For example, you can open it in Internet Explorer and reload a few times, as you see in Figure 7.7 . If you then open it in another browser, such as Netscape Navigator, you'll see that the application counter is indeed keeping track of users across sessions, as shown in Figure 7.8 .
Figure 7.7. Using the application object.
Figure 7.8. Another user using the application object.
[ Team LiB ]
[ Team LiB ]
Using Sessions, Applications, and JavaBeans It turns out that you can instruct Tomcat to save JavaBeans in a session object as well as in attributes. In fact, you can store JavaBeans in applications as well. You do this with the element's scope attribute, which you can set to one of these values: scope="page|request|session|application". The term scope indicates where a data item is "visible" (meaning it may be referred to by name) in your code. The default scope for a bean is page scope, which means the bean exists only for the page scope. However, if you set the scope of a bean to session, it is stored with the rest of the session's data. The bean you see in Listing 7.7 maintains a property named counter that JSP code can increment—we'll see that using page scope, counter is reset to 1 each time the page loads, but using session scope, counter will increment to 2, 3, 4, and so on as you reload the page, because the bean is stored in the session's data.
Listing 7.7 A Bean That Maintains a Usage Counter ( ch07_07.jsp) package beans; public class ch07_07 { private int counter = 0; public void setCounter(int value) { this.counter = value; } public int getCounter() { return this.counter; } public ch07_07() { } }
You can see a JSP page that uses this bean with page scope in Listing 7.8.
Listing 7.8 Using Page Scope for Beans (ch07_08.jsp)
Using Beans and Page Scope Using Beans and Page Scope The counter value is:
And you can see that Web page at work in Figure 7.9—no matter how many times you reload this page, the counter will remain set to 1, because the bean has page scope, so it's created anew each time you load the page.
Figure 7.9. Using a bean with page scope.
However, if you give the bean session scope, as in Listing 7.9, it's stored with the rest of the session, which means the counter value will be preserved between page accesses.
Listing 7.9 Using Session Scope for Beans (ch07_09.jsp)
Using Beans and Session Scope Using Beans and Session Scope The counter value is:
You can see the results of giving the bean session scope in Figure 7.10.
Figure 7.10. Using a bean with session scope.
[ Team LiB ]
[ Team LiB ]
Summary Today you learned how to track users with cookies and sessions in JSP. Everything started by using HTML hidden controls to store data in the Web page sent to the browser and then sent back to the server. Although storing data in hidden controls works, it's not very secure, and the data stored in those controls is visible if the user views the page's HTML source. You learned that you can use cookies to store text data on a person's computer, using Cookie objects and the response object's addCookie method. You can retrieve those objects with the request object's getCookies method. To support a session, you use the session object. As you've seen, you can get the session's ID, creation time, last accessed time, and more using session methods. Sessions let you establish a workable connection with the user's browser, letting you store data between page accesses. You can also use application objects to store data; an application is broader than a session, because sessions deal with a single user, but an application includes all the users using JSP pages on your site. Finally, you learned that you can store beans in sessions and applications if you set the scope attribute to the appropriate values. [ Team LiB ]
[ Team LiB ]
Q&A Q1:
Are there any drawbacks to using sessions?
A1:
Yes, they put a considerable strain on the resources of the server if there are many sessions running at the same time. They can also be broken unexpectedly if the user's connection fails. All in all, in professional JSP applications, you must be prepared for cases when using a session with the user doesn't work.
Q2:
Can I store other data in cookies besides the cookie's name, maximum age, and value?
A2:
Yes, you can also use the Cookie object's setComment and getComment methods to store a comment—a String object—in the cookie. This comment can explain the purpose of the cookie, for example.
[ Team LiB ]
[ Team LiB ]
Workshop This workshop tests whether you understand all the concepts you learned today. It's a good idea to master today's concepts by honing your knowledge here before starting tomorrow's material. You can find the answers to the quiz questions in Appendix A.
Quiz 1:
What are the names of the Cookie object methods you use to find a cookie's name and value?
2:
What is the default timeout for a session in the Tomcat server?
3:
How do you know if Tomcat can't establish a session with the user's browser?
4:
What possible scopes can you use with JavaBeans in JSP?
5:
What is the default setting for the page directive's session attribute?
Exercises 1:
Create a sample home page that accepts a person's name and birthday using text fields (use text fields for the name, birth month, and birth day) and stores that information using a cookie that lasts a year. Then use the Date and Calendar classes you saw in Day 6, "Creating JSP Components: JavaBeans," to display a greeting to the person on his birthday.
2:
Try repeating the JavaBean example in the topic "Using Sessions, Applications, and JavaBeans," but this time, give the bean application scope to create a Web page counter that uses the counter in the bean to indicate the total number of times the page has been accessed by anyone, and then test it out. Also, use the application object's setMaxInactiveInterval method to set the application timeout to a second or two and watch what happens to the counter as the application times run out over repeated page reloads.
[ Team LiB ]
[ Team LiB ]
Week 2: At a Glance 8 Handling Errors 9 Using Custom JSP Tags 10 Creating Custom Tags 11 Creating More Powerful JavaBeans 12 Creating Servlets 13 Creating More Powerful Servlets 14 Using Filters [ Team LiB ]
[ Team LiB ]
Day 8. Handling Errors Today you'll see how to handle the case when things don't go as planned. Errors are a fact of life for most programmers (perhaps not for you if you write perfect code, but for most programmers!) and both Java and JSP offer you a number of ways of dealing with them. There are two main kinds of errors—syntax and runtime, and you'll see how to handle both of them today: Syntax errors are just what they sound like—errors in Java and JSP syntax. These are handled before your application is even released. Runtime errors are harder to deal with. Here, your application is fine as far as syntax goes, but there is some problem with the code's logic, and an error occurs as the user is running your application. Because you handle syntax errors before your code is even released, today's work is going to concentrate on runtime errors. Here are the topics you'll see: Understanding runtime error messages from Tomcat Understanding Java exceptions Getting exception messages from exception objects Handling exceptions with try/catch blocks Handling specific exception types Printing error messages on the server console Throwing exceptions from methods Nesting try/catch statements Creating custom exception objects Setting request object attributes Error handling isn't the most glamorous topic, but it's an essential one to master—if your application crashes right before the user's eyes, that doesn't seem very professional. Handling errors is one of the aspects of real-world JSP programming that you need to have in your programming arsenal. So that's the program—today's discussion starts with syntax errors and then moves on to runtime errors. It all starts with syntax errors. [ Team LiB ]
[ Team LiB ]
Syntax Errors Syntax errors are those errors that will stop Java or JSP from even running your code. Some of these are obvious (such as misspellings like out.prinbln("Hello!") ), and some are not so obvious. For an example of the not-so-obvious kind, take a look at Listing 8.1 . It's Listing 3.21 (ch03_21.jsp ) from Day 3 , "Branching, Looping, and Creating Methods," with a subtle error introduced into the code. Can you find the error?
Listing 8.1 Reading a Cookie (ch08_01.jsp ) Passing Arrays to Methods Passing Arrays to Methods
Even if you don't see the error in Listing 8.1 , Java will. You can see what happens when you try to take a look at this page in Tomcat in Figure 8.1 .
Figure 8.1. A Tomcat error page.
As you can see by the bold message Apache Tomcat/4.0.3 - HTTP Status 500 - Internal Server Error in Figure 8.1 , Tomcat is unhappy with the code in this example (this error message is a familiar one to nearly all JSP programmers). Tomcat gives us a great deal of information about what the syntax error was, if you scroll down the error page. Here's an excerpt:
[View full width] org.apache.jasper.JasperException: Unable to compile class for JSP An error occurred between lines: 8 and 16 in the jsp file: /ch08_01.jsp Generated servlet error: D:\tomcat\jakarta-tomcat-4.0.3\work\localhost\ch08\ch08_0005f01$jsp.java:15: Attempt to reference field length in a int. for (int loopIndex = 0; loopIndex < a.length; ^
An error occurred between lines: 8 and 16 in the jsp file: /ch08_01.jsp Generated servlet error: D:\tomcat\jakarta-tomcat-4.0.3\work\localhost\ch08\ch08_0005f01$jsp.java:17: [] can only be applied to arrays. It can't be applied to int. a[loopIndex] *= 2; ^
An error occurred between lines: 18 and 36 in the jsp file: /ch08_01.jsp Generated servlet error: D:\tomcat\jakarta-tomcat-4.0.3\work\localhost\ch08\ch08_0005f01$jsp.java:83: Incompatible type for method. Can't convert int[] to int. doubler(array); ^ 3 errors at org.apache.jasper.compiler.Compiler.compile(Compiler.java:285) at org.apache.jasper.servlet.JspServlet.loadJSP(JspServlet.java:552) at org.apache.jasper.servlet.JspServlet$JspServletWrapper.loadIfNecessary (JspServlet. java:177) at org.apache.jasper.servlet.JspServlet$JspServletWrapper.service (JspServlet.java: 189) at org.apache.jasper.servlet.JspServlet.serviceJspFile (JspServlet.java:382) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:474) at javax.servlet.http.HttpServlet.service(HttpServlet.java:853) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter ( ApplicationFilterChain.java:247) at org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain. java:193) at org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java: 243) at org.apache.catalina.core.StandardPipeline.invokeNext (StandardPipeline.java:566) . . .
At the top of this error report, you see the message org.apache.jasper.JasperException: Unable to compile class for JSP . Jasper is Tomcat's internal class for turning your JSP pages into servlets, so we know that there was a problem compiling the code into Java for use as a servlet. Looking underneath this message, you see three error messages, which are shaded. The third error message says Incompatible type for method. Can't convert int[] to int ., and refers you to this line of code:
doubler(array);
This line occurs in Listing 8.1 where the code has created an array, and is passing that array to the
doubler method, which is supposed to double each element in the array:
int array[] = {1, 2, 3, 4, 5}; . . . doubler(array);
What could be the problem with that? A quick look at the doubler method lets you know what the problem is—the argument passed to that method is mistakenly declared to be a simple integer, not an integer array:
void doubler(int a) { for (int loopIndex = 0; loopIndex < a.length; loopIndex++) { a[loopIndex] *= 2; } }
When you fix this problem by changing this line to void doubler(int[] a) , all works as it should. In this way, Tomcat pointed out the syntax error and made it relatively easy to fix. You can also run into syntax errors when writing JavaBeans, of course. There, you'd see error messages from the Java compiler javac that would let you know what's going on. In this way, you'll get feedback on syntax errors. However, the next kind of error, runtime errors, are harder to handle because they only occur when your application is running.
[ Team LiB ]
[ Team LiB ]
Runtime Errors Take a look at the JSP page in Listing 8.2. This code calmly divides a number by zero, which is going to cause a numeric problem.
Listing 8.2 Causing a Runtime Error (ch08_02.jsp) Causing a Runtime Error Causing a Runtime Error
You can see the results of this page in Figure 8.2, where Tomcat is indeed reporting a runtime error.
Figure 8.2. A runtime error.
The crucial line in Figure 8.2 is java.lang.ArithmeticException: / by zero. The message / by zero is Java's terse way of saying that you tried to divide by zero. This causes a runtime error, called an exception. If the user is confronted by the error page you see in Figure 8.2, she's probably not going to know what to do (especially with a message like / by zero). Fortunately, you can set up your code to handle exceptions—by displaying your own error-handling messages or executing recovery code—and that's what most of the rest of today's discussion is about. [ Team LiB ]
[ Team LiB ]
Exceptions Knowing Java, you might guess that exceptions are handled with a new class, and you'd be right. The class that handles exceptions is the Java Exception class (including its package name, it's the java.lang.Exception class), and it's based on the Throwable class (java.lang.Throwable). We'll get familiar with both classes today. The Throwable class holds a sort of snapshot of what was going on in the code when the exception occurred. It can also contain a message string that gives more information about the error. You can see its methods in Table 8.1. Note especially the getMessage method, which returns a String object holding an error message that you can display to the user.
Table 8.1. The Methods of the java.lang.Throwable Class Method
Does This
Throwable()
Constructs a new Throwable object.
Throwable(String message)
Constructs a new Throwable object with the given error message.
String getLocalizedMessage()
Creates a localized description of this object.
String getMessage()
Returns the error message string of this Throwable object.
void printStackTrace()
Prints this Throwable object and its stack trace to the server console.
void printStackTrace(PrintStream s)
Prints this object and its stack trace to the server console.
void printStackTrace(PrintWriter s)
Prints this object and its stack trace to the given print writer object.
String toString()
Returns a description of this Throwable object.
The Exception class is based on the Throwable class, and it's the one you normally use to work with exceptions. Because it's based on the Throwable class, it also includes all the methods of the Throwable class. You can see the methods of the Exception class in Table 8.2.
Table 8.2. The Methods of the java.lang.Exception Class
Method
Does This
Exception()
Constructs an Exception object.
Exception(String s)
Constructs an Exception object with the given error message.
So how do you use Exception objects? You use Java try/catch blocks, and that's the next topic.
[ Team LiB ]
[ Team LiB ]
Using try/catch Blocks Java supports both a try statement and a catch statement to handle exceptions. Here's how you use a try/catch block in general:
try { // Sensitive code } catch (Exception1Type e1) { // Handle exception1 type } catch (Exception1Type e1) { // Handle exception1 type } . . . [finally { // Code to be executed before try block ends }]
When some sensitive code inside a try block throws an exception, you can catch it with a catch block. You can also use a finally block to execute code after the try/catch block is complete, and the code in the finally block will be executed whether or not an exception occurred. You can use a finally block to handle exceptions not explicitly caught in a catch block. The finally block is optional, as is the catch block—but note that one or the other must be specified. Here's an example to make this clearer. This code will surround the earlier code that divided by zero in a try/catch block. If an exception occurs, it is passed to the catch block just like passing an argument to a method, and here the exception object will be named e. This page displays a message in the catch block, using the exception object's getMessage method, as you can see in Listing 8.3.
Listing 8.3 Using a try/catch Block (ch08_03.jsp) Using a try/catch Block Using a try/catch Block
You can see this page at work in Figure 8.3, where again you see the terse message / by zero (you'll see how to make this message more readable in a few pages).
Figure 8.3. Catching an exception.
Now you've been able to handle an exception. Even though the message displayed is very terse, it's better than the Tomcat error page you saw in Figure 8.2. Besides the getMessage method of an Exception object, you can also simply call out.println with the Exception object itself, as you see in Listing 8.4. As with all Java objects, doing so calls the object's toString method, which results in a slightly different exception message as you see in Figure 8.4.
Figure 8.4. Using an Exception object's toString method.
Listing 8.4 Using the Exception Object (ch08_04.jsp) Using a try/catch Block Using a try/catch Block
Note in Figure 8.4 that this error message specifies what looks like a Java class—java.lang.ArithmeticException. What's that all about? [ Team LiB ]
[ Team LiB ]
Handling Specific Exception Types There are many, many different types of exceptions in Java, and they're all based on the Java Exception class. To handle specific problems, you can work with specific types of exceptions. The following is a list of some of the most common exception classes: AclNotFoundException ActivationException AlreadyBoundException ApplicationException ArithmeticException ArrayIndexOutOfBoundsException AWTException BadLocationException ClassNotFoundException CloneNotSupportedException DataFormatException ExpandVetoException FileException GeneralSecurityException IllegalAccessException InstantiationException InterruptedException IntrospectionException InvocationTargetException IOException LastOwnerException NoninvertibleTransformException
NoSuchFieldException NoSuchMethodException NotBoundException NotOwnerException ParseException PrinterException PrivilegedActionException PropertyVetoException RemarshalException RuntimeException ServerNotActiveException SQLException TooManyListenersException UnsupportedFlavorException UnsupportedLookAndFeelException UserException You can catch any type of exception by specifying the Exception object in a catch block, but you can also be more selective by specifying a particular type of exception—such as one from the previous list—to catch. Here is one example of catching an exception—in this case, the code catches an array-out-of-bounds exception using the appropriately named ArrayIndexOutOfBoundsException class:
try { . . . } catch (ArrayIndexOutOfBoundsException e) { out.println("Array index out of bounds"); }
You can see this code at work in Listing 8.5, where the code creates an array of 100 elements—array[0] to array[99]—and then tries to assign a value to the nonexistent element array[100], which Java isn't going to like.
Listing 8.5 Catching an ArrayIndexOutOfBoundsException Exception (ch08_05.jsp)
Catching an ArrayIndexOutOfBoundsException Exception Catching an ArrayIndexOutOfBoundsException Exception
You can see this page in Figure 8.5, where the code is catching an ArrayIndexOutOfBoundsException exception.
Figure 8.5. Catching an ArrayIndexOutOfBoundsException exception.
As you see, it's possible to catch specific exceptions by specifying the class of exception you want to catch. In fact, you can do more—you can catch multiple exceptions by specifying their type, which is what's coming up next. [ Team LiB ]
[ Team LiB ]
Catching Multiple Exceptions Now that you know you can catch exceptions of specific types, it's important to know that you can use multiple catch blocks in the same try/catch statement. One catch block can handle one type of exception, another can handle another, and so on, making for very specific error handlers. You can see an example of this in Listing 8.6, where the code catches array-index-out-of-bounds exceptions if there were any, and if not, checks for arithmetic exceptions. If neither one of those exceptions occurred, the catch block that catches any Exception objects will catch any other type of exception, letting you pick out the exceptions you want to specifically handle, but also to provide general error-handling code for any other exception. It's a great advantage that Java enables you to do this—not only does your code not bomb in front of the user, but by knowing what went wrong, you can take specific action to fix it.
Tip If an exception occurs and Java can't find a catch block in your code to handle it, it will use its default exception handler—which in Tomcat will display an error page.
Listing 8.6 Catching Multiple Exceptions (ch08_06.jsp) Catching an ArrayIndexOutOfBoundsException Exception Catching an ArrayIndexOutOfBoundsException Exception
Besides using multiple catch statements, you can also nest try/catch statements. [ Team LiB ]
[ Team LiB ]
Nesting try/catch Statements You can nest try blocks inside other try blocks, and if one try block doesn't have a corresponding catch block that handles an exception, Java will search the next outer try block for a catch block that will handle the exception, back through successive nestings. If Java can't find a catch block for the exception, it will pass the exception to its default exception handler. You can see an example of nested try blocks in Listing 8.7.
Listing 8.7 Nesting try/catch Statements (ch08_07.jsp) Nesting try/catch Statements Nesting try/catch Statements
You can see this page at work in Figure 8.6.
Figure 8.6. Using nested try/catch statements.
Besides waiting for Java to create an exception, you can create one yourself in code. That's called throwing an exception, and it's coming up next. [ Team LiB ]
[ Team LiB ]
Throwing Exceptions Yourself Say that some error condition happens that Java doesn't want to treat as an exception—but you do. In that case, you can cause a Java exception by throwing an Exception object. You can throw your own exceptions with the throw statement. You can see an example in Listing 8.8. In this case, the code throws an exception that will be caught in a catch block, which displays a message. Note that when you create an Exception object, like the ArithmeticException object created here, you can pass text to the object's constructor to specify the error message it will contain.
Listing 8.8 Throwing an Exception (ch08_08.jsp) Throwing an Exception Throwing an Exception
Tip Throwing exceptions is a good idea if you don't want to handle an exception in a certain exception handler—when you throw the exception, Java looks for an enclosing or following catch statement for the exception. And as we're about to see, you can throw an exception in a method that is handled in the code that called the method, which is good if you don't want to place all your exception-handling code in the method itself.
[ Team LiB ]
[ Team LiB ]
Throwing Exceptions from Methods You might remember that in Day 3, you saw this code to pass the out object to a method:
Passing the out Object to a Method Passing the out Object to a Method
This code passed the out object to the printem method. The out object is a complex and large one, and it can throw objects of the java.io.IOException class (which, as you can guess from its name, handles I/O exceptions). Java noticed that the code had no way of handling this exception if it was thrown, and will insist that you handle it (and will cause a syntax error otherwise). This code handled the error simply by adding a throws clause to the method definition. In practice, that means that if an exception occurred, it would be passed to Java's default exception handler, and the user would be left looking at an error page. On the other hand, you can handle exceptions that occur in a called method in the calling code. For example, say you have a method, doWork, that causes an ArrayIndexOutOfBoundsException:
You can handle this exception by calling doWork from inside a try block, and handling the error in a
catch block this way:
You can see this code in a sample Web page in Listing 8.9.
Listing 8.9 Reading a Cookie (ch08_09.jsp) Throwing Exceptions From Methods Throwing Exceptions From Methods
You can see this page at work in Figure 8.7, where the exception thrown in the doWork method was caught back in the calling code.
Figure 8.7. Throwing exceptions from methods.
Note that you don't have to throw any of the predefined Java exceptions—you can define your own exceptions. [ Team LiB ]
[ Team LiB ]
Creating a Custom Exception Object You can create your own exception classes by basing them on the Exception class. You haven't seen how that works in this book yet—it's coming up in Day 11, "Creating More Powerful JavaBeans"—but it's worth getting a preview here. The new exception class will be called NewException. To base this class on the Exception class, you start with the extends keyword: class NewException extends Exception { . . . }
As you'll see in Day 11, this gives the NewException class the functionality of the Exception class. To customize this new class, you can provide a constructor and a new version of the methods you plan to use, like getMessage or toString. Here's what that looks like—the toString method is called automatically if you pass an object of this class to out.println:
class NewException extends Exception { int value; public String toString() { return "NewException " + value; } NewException(int v) { value = v; } }
You can see this class at work in Listing 8.10 in a method called doWork—if the value passed to that method is 0, doWork will throw an exception of the NewException class, which is caught in the calling code, and the error message is displayed.
Listing 8.10 Creating a Custom Exception Object ( ch08_10.jsp)
Creating a Custom Exception Object Creating a Custom Exception Object
You can see this code at work in Figure 8.8—now you've created and caught a custom exception.
Figure 8.8. Catching a custom exception.
[ Team LiB ]
[ Team LiB ]
Printing to the Server Console Here's another technique to know that's helpful in handling errors—you can send text directly to the server console. For example, in Windows, that's the DOS session that opens when you start Tomcat. To do so, you use the System.out.println method instead of out.println. You can see an example using the System.out.println method in Listing 8.11, where the code sends an exception's error message to the server console if an exception occurs (and the code makes sure one does).
Listing 8.11 Printing to the Server Console (ch08_11.jsp) Printing to the Server Console Printing to the Server Console
You can see the results in the server console in Windows in Figure 8.9, where the terse Java error message / by zero appears.
Figure 8.9. Writing to the server console.
Note that displaying text on the server console isn't just useful for handling errors—you can send any type of message to the console you like. You can also send a stack trace of the kind you'll see when Java handles an exception to the server console. A stack trace is more useful in Java than in JSP—it gives you the call history that's occurred, indicating which method called which method, all the way down to where the error occurred. The reason that's not often useful in JSP is because your JSP code is translated into a servlet before it's run, which means the method named won't be familiar to you. However, if you want to see a stack trace, try the code you see in Listing 8.12, which uses the Exception class's printStackTrace method, which sends its text to the server console.
Listing 8.12 Printing a Stack Trace to the Server Console ( ch08_12.jsp) Printing a Stack Trace to the Server Console Printing a Stack Trace to the Server Console
In fact, you can see what a stack trace looks like in the next topic, where you'll learn how to use Tomcat log files. [ Team LiB ]
[ Team LiB ]
Using Log Files Tomcat itself keeps track of the errors that occur, but it can be hard to find out where tracking information goes. Here's an example of tracking down the error-tracking files. Tomcat comes with a number of examples in its examples directory (http://localhost:8080/examples/ ), and it makes provision for handling errors created by those examples. To find out how the error logging works, take a look at the server.xml file in the jakarta-tomcat-4.0.3\conf directory. You'll find a section like the following in that file, which indicates how to handle logging for errors in the examples:
From this, you learn that log files for errors in the example directory will go into files with names like (note that the filename includes the date) localhost_examples_log.2003-03-29.txt . The following is the kind of data you'll find in such a log file, where the code has thrown an arithmetic divide-by-zero exception—the rest of this data is a stack trace, showing what methods Java called to get to the error-causing code:
[View full width] 2003-05-10 10:54:22 StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exception java.lang.ArithmeticException: / by zero at org.apache.jsp.simple_0005ferror$jsp._jspService(simple_0005ferror$jsp. java:60) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:107) at javax.servlet.http.HttpServlet.service(HttpServlet.java:853) at org.apache.jasper.servlet.JspServlet$JspServletWrapper. service(JspServlet.java: 202) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet. java:382) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:474) at javax.servlet.http.HttpServlet.service(HttpServlet.java:853) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter ( ApplicationFilterChain.java:247) at org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain. java:193) at org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java: 243) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline. java:566) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline. java:472) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943) at org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:
190) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline. java:566) at org.apache.catalina.authenticator.AuthenticatorBase.invoke (AuthenticatorBase. java:475) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline. java:564) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline. java:472) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943) at org.apache.catalina.core.StandardContext.invoke(StandardContext. java:2343) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve. java:180) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline. java:566) at org.apache.catalina.valves.ErrorDispatcherValve.invoke (ErrorDispatcherValve.java: 170) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline. java:564) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve. java:170) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline. java:564) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve. java:468) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline. java:564) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline. java:472) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943) at org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:174) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline. java:566) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline. java:472) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943) at org.apache.catalina.connector.http.HttpProcessor.process(HttpProcessor. java:1012) at org.apache.catalina.connector.http.HttpProcessor.run(HttpProcessor. java:1107) at java.lang.Thread.run(Thread.java:484) 2002-05-10 10:56:13 SessionListener: contextDestroyed() 2002-05-10 10:56:13 ContextListener: contextDestroyed()
[ Team LiB ]
[ Team LiB ]
Using JSP Error Pages JSP has a powerful built-in technique for handling exceptions that you should know about—error pages. Using the page directive's errorPage attribute, you can specify a page to display if an exception occurs. You can see an example in Listing 8.13, which specifies ch08_14.jps as the error page.
Listing 8.13 Using an Error Page (ch08_13.jsp) Using an Error Page Using an Error Page
You can see the error page itself in Listing 8.14. Note that you can specify that a page is an error page by setting the page directive's isErrorPage attribute to "true" (the default is "false").
Listing 8.14 An Error Page (ch08_14.jsp) An Error Page An Error Page There was an error! Don't Panic!!! Consult your physician immediately.
You can see the results in Figure 8.10. As soon as you load ch08_13.jsp, an error occurs because of the division by zero in the JSP code. That makes Tomcat display the error page, as you see in Figure 8.10.
Figure 8.10. Using an error page.
The text in the error page you see in Figure 8.10 is not very specific—but it turns out that you can get more information on the error. [ Team LiB ]
[ Team LiB ]
Using JSP Error Pages: The exception Object The HTTP request sent to the original page is forwarded to the error page, and you have access to it in the error page as the request object. In addition, you have access to the built-in exception object. This is an object of the Java java.lang.Throwable class (see Table 8.1), so you can use methods like toString on this object to get the object's error message. For example, you can see a new error-prone page in Listing 8.15, which uses ch08_16.jsp as an error page.
Listing 8.15 Using the exception Object (ch08_15.jsp) Using the exception Object Using the exception Object
In ch06_16.jsp, you can use the exception object to display the error message for the exception, as you see in Listing 8.16.
Listing 8.16 Using the exception Object in an Error Page (ch08_16.jsp) An Error Page Using the exception Object An Error Page Using the exception Object An error occurred:
You can see the results in Figure 8.11—note that although you've navigated to ch08_15.jsp, the actual page you see is the error page, ch08_16.jsp, because there was an exception in ch08_15.jsp.
Figure 8.11. Using the exception object in an error page.
[ Team LiB ]
[ Team LiB ]
Using JSP Error Pages: request Object Attributes While on the topic of sending data to other Web pages, it's worth taking a look at request object attributes. Attributes hold named objects like String objects. To set an attribute of the request object, you use the setAttribute method, passing the name you want to use for the attribute—this example will just use "message"—and the object you want to pass, which will be a String object here, as you see in Listing 8.17.
Listing 8.17 Using request Object Attributes (ch08_17.jsp) Using request Object Attributes Using request Object Attributes
In the page that the request is forwarded to, you can use the getAttribute method to get the object associated with the attribute, simply by passing the attribute's name to this method, as you see in Listing 8.18.
Listing 8.18 Using the exception Object in an Error Page (ch08_18.jsp) An Error Page Using Request Attributes An Error Page Using the exception Object An error occurred:
The result is that you can place an object in an attribute and retrieve it in an error page, as you see in Figure 8.12.
Figure 8.12. Using request object attributes.
[ Team LiB ]
[ Team LiB ]
Summary Today you learned about handling errors. You saw that syntax errors prevent your code from being compiled, and that exceptions are runtime errors that Tomcat lets you handle. To handle exceptions, you use try/catch blocks. You place the sensitive code in try blocks and the error-handling code in catch blocks. Code that you want to run after the code in try/catch blocks can go into finally blocks. Using try/catch blocks, you can handle not just general exceptions by catching exceptions of the Exception class, but specific exception objects, such as exceptions of the ArrayIndexOutOfBoundsException class. You can use multiple catch blocks to catch exceptions of different classes from the same try block. If the last catch block catches general exceptions of the Exception class, you'll be sure to catch all possible exception objects. You can also nest try/catch statements.You can even create your own exceptions, and throw exceptions with the throw statement. JSP also provides a mechanism for working with errors—you can specify an error page with the page directive. The error page is forwarded the original request object sent to the error-causing page, as well as an exception object to let you know what exception occurred. You can add attributes to the request object before it's forwarded to the error page, which lets you pass data to the error page.
[ Team LiB ]
[ Team LiB ]
Q&A Q1:
Are there runtime errors that I can't handle with try/catch blocks?
A1:
Yes. Those kinds of errors are internal to Java, to Tomcat, and to JSP itself. Because they are internal errors, there is no provision to handle them with the try/catch mechanism. But these kinds of errors are rare. Sometimes, Java will run across errors so severe that it can't continue, in which case the try/catch mechanism is not called—the program just ends.
Q2:
What about using a debugger?
A2:
The support for debuggers is very limited at this time—that's one of the things being planned for the next version of the JSP and servlet specifications.
[ Team LiB ]
[ Team LiB ]
Workshop This workshop tests whether you understand all the concepts you learned today. It's a good idea to master today's concepts by honing your knowledge here before starting tomorrow's material. You can find the answers to the quiz questions in Appendix A.
Quiz 1:
What's the difference between a syntax error and an exception?
2:
What's the base class of the Exception class?
3:
What is the finally block used for in a try/catch statement?
4:
What Exception object method is automatically called when you pass that object to out.println?
5:
What methods do you use to set and get attributes with request objects?
Exercises 1:
Create a simple Web page and make sure that the code creates an exception at runtime. Catch the exception using a try/catch block and report it. Then convert the Web page to use an error page to do the same thing, moving from the Java way of doing things to the JSP way.
2:
Build a simple calculator that lets the user add, subtract, divide, and multiply. Use any layout you want (Suggestion: Start with a text field for the first operand, four submit buttons labeled +, -, *, and / under that text field, another text field under the buttons for the second operand, then another text field for the answer). Make sure to add an error page to handle ArithmeticException exceptions.
[ Team LiB ]
[ Team LiB ]
Day 9. Using Custom JSP Tags Welcome to Day 9! Today you're going to start learning how to create your own custom JSP tags. So far, you've used the built-in tags in JSP, like or . Today, you'll start going beyond that and begin creating your own JSP tags—and connecting Java code to those tags. Here are today's topics: Understanding and installing custom JSP tags Using the available Jakarta tag libraries Using the Request tag library in depth Creating a simple tag Creating tag descriptor files Installing tag libraries using web.xml Writing Java code for a simple tag Using the simple tag you've created You'll see what custom tag libraries are available already, and how to put one of them—the Jakarta Request tag library—to work. You'll see that it takes a little extra work to install and use tag libraries, even more work than installing and using a bean. That raises the question—why not just use beans in the first place, instead of custom tags? To some degree, it's a matter of taste—the reason usually given to use custom tags instead of beans is that bean code doesn't have direct access to the request and response objects, and custom tag code does. However, you can pass those objects to bean methods, so that's not an insurmountable complaint. On the other hand, after you've installed a custom tag library, custom tags can be a lot easier to use in JSP than continual , , and elements. Custom tags also do a better job than beans of separating your code from your data, which is a big topic in JSP programming these days. The biggest reason why custom tags are becoming popular is that no programming is involved to use them—you don't have to interface to a bean, and you don't have to use any Java code at all. That makes it easier to bring newcomers to JSP, which is one of the reasons why the creators of JSP like custom tags. As you master both beans and custom tags, you'll see that some applications are better suited to one or the other technique. And it's certainly true that knowing how to create custom tags is something you need to know if you want to be a JSP programmer. In fact, creating your own tags can seem to be a formidable task at first—you have to modify Tomcat configuration files, write the Java code, create a tag library descriptor, and more. The work you'll see today will take you through the process; after you get used to it, it's not so difficult. Today's discussion will start with an overview of tag libraries, which is how you support custom tags.
[ Team LiB ]
[ Team LiB ]
Tag Libraries Tag libraries are composed of a set of custom tags. JSP custom tags were introduced in JSP version 1.1, and new features were added in JSP version 1.2. When you create a custom tag, you really have a great deal of freedom—you can access the contents of the tag in Java code and work with it just as any other JSP tag. You'll see how that works at the end of today and the beginning of tomorrow's material. On the other hand, there are many JSP tag libraries that contain custom tags that already exist. The Jakarta Apache project (the same people who bring you the Tomcat server) has a substantial collection of tag libraries available for free download, and you can find them at http://jakarta.apache.org/taglibs. Here are the Jakarta tag libraries that have been released as final: Application Taglib— This custom tag library contains tags that can be used to access information contained in Web applications. DateTime Taglib— Contains tags that can be used to handle date- and time-related functions. Tags are supported for formatting dates, generating a Date from HTML form input, using time zones, and localization. Mailer Taglib— You can use this custom tag library to send email. Page Taglib— Contains tags that can be used to access all the information about the JSP page itself. Random Taglib— The Random tag library creates code that creates random strings and random numbers. Regexp Taglib— The Regexp custom tag library contains tags that can be used to perform regular expressions in Perl syntax that are used in search text for matches to text patterns you specify. Request Taglib— Contains tags that can be used to access all the information about the HTTP request for a JSP page. Response Taglib— Contains tags that can be used to set all the information for an HTTP response for a JSP page. Session Taglib— Contains tags for reading or modifying session information. XSL Taglib— This tag library can perform XSL Transformations, with which you can translate XML documents into other formats, such as HTML, plain text, and more. Besides these well-established tag libraries, Apache is putting together the JSP Standard Tag Library (JSTL), which is in the testing stages (beta version 2) as of this writing. JSTL might become a built-in part of future JSP versions, and you can find a tutorial on it at
http://java.sun.com/webservices/docs/ea1/tutorial/doc/JSTL.html. Here's what Apache says about JSTL on that page: JSTL has support for common, structural tasks such as iteration and conditionals, tags for manipulating XML documents, internationalization tags, and tags for accessing databases using SQL. It also introduces the concept of an expression language to simplify page development and includes several experimental languages. JSTL also provides a framework for integrating existing custom tags with JSTL tags.
Tip You can also download the JSTL specification at http://jcp.org/aboutJava/communityprocess/first/jsr052/.
To get an idea of how custom JSP tags work and what they can do, you'll work with the Jakarta Request tag library today. [ Team LiB ]
[ Team LiB ]
The Request Tag Library As you might expect, the Request tag library lets you work with the request object. For example, this tag library includes tags that you can use to call most request object methods (see Tables 4.1 and 4.2 in Day 4 , "Reading Data from Web Pages: Buttons and Text Fields," for those methods). After installing this library, you'll work through one of the Request tag library examples here:
User-Agent=
In this case, the and elements are made with custom tags from the Request library. The tag checks to see whether a particular header exists in the request object—here, the code is checking for the User-Agent header, which tells you what browser the user is using (as discussed in Day 4 ). The tag gets the actual text in the header itself. You don't have to use these custom tags, of course—you could use code like this to perform the same action:
This points out the biggest reason to use custom tags—they let you avoid writing and debugging Java code in your JSP pages. If you don't know how to write this Java code, but you do know how to use the custom tags, you're still able to accomplish the same tasks.
Downloading the Request Tag Library To find out how to install and use a tag library, download the Jakarta Request tag library at http://jakarta.apache.org/builds/jakarta-taglibs/releases/request/ .
Tip If for some reason the Request tag library has been moved by the time you read this, go to http://jakarta.apache.org/taglibs/index.html and click the link for the Request Taglib , which should take you to that library.
Downloading the Request tag library means downloading a compressed file such as jakartataglibs-request-1.0.zip for Windows, or jakarta-taglibs-request-1.0.tar.gz for Unix. To unzip those files, you'll need an unzipping utility program that can handle compressed files. When you unzip the compressed Request tag library file, you'll get four files: request.tld — The tag library descriptor file for this custom tag library. This file will normally be copied to the /WEB-INF subdirectory within your Web application. request.jar — A Java Archive (JAR) file containing the Java classes for this custom tag library. This file will normally be copied to the /WEB-INF/lib subdirectory within your Web application. request-doc.war — A Web Archive (WAR) file containing developer documentation describing how to use the tags in this custom tag library in your own application. request-examples.war — A WAR file containing examples that illustrate the use of this custom tag library. The next step is to install these files.
Installing the Request Tag Library To use the Request tag library, follow these steps (these steps are already done in the downloadable code for this book): 1. Create the webapps\ch09 directory. 2. Copy the request.tld file to a directory named webapps\ch09\WEB-INF . 3. Copy the request.jar file to a directory named webapps\ch09\WEB-INF\lib . The Request tag library comes with a set of examples, and you'll see one of those examples at work here. To access the examples, unzip the file request-examples.war . You can use a standard zip utility to do this, such as WinZip for Windows (www.winzip.com/ ). Alternatively, you can use the JAR tool that comes with Java:
C:\directory>jar xvf request-examples.war
Included in the unzipped files are the ones you'll need to run the Request tag library example—index.html , request.jsp , and web.xml . Here's how to install these files (this is already done in the downloadable code for this book): 1. Copy index.html and request.jsp to webapps\ch09 . 2. Copy the web.xml file to the webapps\ch09\WEB-INF subdirectory. Note that in the downloadable code, the Jakarta examples index.html and request.jsp are renamed ch09_01.html and ch09_02.jsp for consistency with the standard numbering throughout the book.
Now start Tomcat—if it's already running, shut it down and start it again (as you must do when you install newly compiled Java code you want to use). Navigate to index.html if you've gotten this example from the Apache Web site, or ch09_01.html if you've downloaded the code for the book—you should see the results in Figure 9.1 .
Figure 9.1. The Jakarta Request tag library example.
You can see this page's HTML in Listing 9.1 . The page you see in Listing 9.1 will send its data—including that in several hidden controls—to another page, which will use Request tag library tags to decipher what's going on in the request object.
Listing 9.1 The Jakarta Request Tag Library Example (ch09_01.html ) Jakarta REQUEST Taglib Example
This page includes a number of hidden input paramters that can then be seen when viewing the request.jsp example page.
Select the button to see the output from the request.jsp example page. See the source from the request.jsp example page.
Click the Submit button in Figure 9.1 —you should see the new page that appears in Figure 9.2 (and if you don't, you might download the code for this book and use that, which already has request.jar and so on installed).
Figure 9.2. Using Request tag library custom tags.
As you can see in Figure 9.2 , the target JSP page has decoded the request header and displayed its
contents. Only a little of that information is visible in Figure 9.2 , so here's the whole thing—you'll be seeing more on this output in a few pages as you work through the code that produced it:
Jakarta REQUEST Taglib Example Cookies received with request: Cookie name: Comment: Domain: MaxAge: Path: Secure: Value: Version:
JSESSIONID
-1 0 44454937C05623D4121E3B8ED9F36C75 0
See if JSESSIONID Cookie exists JSESSIONID=44454937C05623D4121E3B8ED9F36C75 HTTP Headers received with request: accept = image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, */* referer = http://localhost:8080/ch09/ch09_01.html accept-language = en-us content-type = application/x-www-form-urlencoded accept-encoding = gzip, deflate user-agent = Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; COM+ 1.0.2204; .NET CLR 1.0.3512) host = localhost:8080 content-length = 137 connection = Keep-Alive cache-control = no-cache cookie = JSESSIONID=44454937C05623D4121E3B8ED9F36C75 See if User-Agent Header exists User-Agent=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; COM+ 1.0.2204; .NET CLR 1.0.3512) GET or POST Parameters received with request: test4 = AAbb test3 = This is a third test test2 = This is another test test1 = This is a test submit = SUBMIT GET or POST Parameters received with request for test3: test3 = This is a third test test3 = Third test with multiple values See if test1 parameter exists
test1=This is a test See if parameter test4 equals "aabb" Parameter test4 does not equal "aabb". See if test4 equals "aabb", ignoring case test4=AAbb Set an attribute named "myatt" See if myatt attribute exists myatt=AAbb Set an attribute named "myatt2" to the Header User-agent See if myatt equals "aabb" Attribute myatt does not equal "aabb". See if myatt equals "aabb", ignoring case myatt=AAbb Now loop through all the attributes myatt2 = Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; COM+ 1.0.2204; .NET CLR 1.0.3512) myatt = AAbb Now remove the attribute myatt See if myatt attribute exists Attribute myatt does not exist. Request Information: AuthType: ContextPath: /ch09 Method: POST PathInfo: PathTranslated: QueryString: RemoteUser: RequestedSessionId: 44454937C05623D4121E3B8ED9F36C75 RequestURI: /ch09/ch09_02.jsp RequestURL: http://localhost:8080/ch09/ch09_02.jsp ServletPath: /ch09_02.jsp CharacterEncoding: ContentLength: 137 ContentType: application/x-www-form-urlencoded Protocol: HTTP/1.1 RemoteAddr: 127.0.0.1 RemoteHost: 127.0.0.1 Scheme: http ServerName: localhost ServerPort: 8080
IsSecure? Session is not using HTTPS. IsSessionFromCookie? Session is using a cookie. IsSessionFromURL? Session is not using a URL. IsSessionValid? Session is not valid. IsUserInRole "admin"? User is not in role admin. Log a message to the servlet context log.
This output is created by ch09_02.jsp using custom tags from the Request tag library. You can see how this works in ch09_02.jsp , which appears in Listing 9.2 .
Listing 9.2 The Jakarta Request lib Example (ch09_02.jsp ) [View full width]
Jakarta REQUEST Taglib Example Jakarta REQUEST Taglib Example
Cookies received with request: Cookie name: Comment: Domain: MaxAge: Path: Secure: Value: Version:
See if JSESSIONID Cookie exists JSESSIONID= Cookie JSESSIONID does not exist. HTTP Headers received with request:
= See if User-Agent Header exists User-Agent= Header User-Agent does not exist. GET or POST Parameters received with request: = GET or POST Parameters received with request for test3: = See if test1 parameter exists test1= Parameter test1 does not exist. See if parameter test4 equals "aabb" test4= Parameter test4 does not equal "aabb". See if test4 equals "aabb", ignoring case test4= Parameter test4 does not equal "aabb", ignoring case. Set an attribute named "myatt"
AAbb See if myatt attribute exists myatt= Attribute myatt does not exist. Set an attribute named "myatt2" to the Header User-agent See if myatt equals "aabb" myatt= Attribute myatt does not equal "aabb". See if myatt equals "aabb", ignoring case myatt= Attribute myatt does not equal "aabb", ignoring case.
Now loop through all the attributes =