The Java™ EE 5 Tutorial, Third Edition: For Sun Java System Application Server Platform Edition 9 By Eric Jendrock, Jennifer Ball, Debbie Carson, Ian Evans, Scott Fordin, Kim Haase ............................................... Publisher: Addison Wesley Professional Pub Date: November 03, 2006 Print ISBN-10: 0-321-49029-0 Print ISBN-13: 978-0-321-49029-2 Pages: 1360
Table of Contents | Index
The Java EE 5 Tutorial is an introduction to programming server-side Java applications. This book takes a task-oriented, example-driven approach to show you how to build applications for the Java EE 5 platform. This book also describes the features and functionalities available with NetBeans 5.5. What's new in this edition? The author team have updated the existing chapters to reflect the changes to JSP, EJB, Servlets, and more. Also, the authors have added new chapters on the Sun Java System Application Server 9 as a deployment environment for server-side technologies. The web-tier technology chapters cover the components used in developing the presentation layer of a Java EE 5 or standalone web application. The web services technology chapters cover the APIs used in developing standard web services. The Enterprise JavaBeans (EJB) technology chapters cover the components used in developing the business logic of a Java EE 5 application. The Persistence technology chapters cover the Java Persistence API, which is used for accessing databases from Java EE applications. The platform services chapters cover the system services used by all the Java EE 5 component technologies
The Java™ EE 5 Tutorial, Third Edition: For Sun Java System Application Server Platform Edition 9 By Eric Jendrock, Jennifer Ball, Debbie Carson, Ian Evans, Scott Fordin, Kim Haase ............................................... Publisher: Addison Wesley Professional Pub Date: November 03, 2006 Print ISBN-10: 0-321-49029-0 Print ISBN-13: 978-0-321-49029-2 Pages: 1360
Table of Contents | Index
Copyright About This Tutorial Chapter 1. Overview Java EE Application Model Distributed Multitiered Applications Java EE Containers Web Services Support Java EE Application Assembly and Deployment Packaging Applications Development Roles Java EE 5 APIs Sun Java System Application Server Platform Edition 9 Part One: The Web Tier Chapter 2. Getting Started with Web Applications Web Application Life Cycle Web Modules Configuring Web Applications Duke's Bookstore Examples Accessing Databases from Web Applications Further Information Chapter 3. Java Servlet Technology What Is a Servlet? The Example Servlets Servlet Life Cycle Sharing Information Initializing a Servlet Writing Service Methods Filtering Requests and Responses Invoking Other Web Resources Accessing the Web Context Maintaining Client State Finalizing a Servlet Further Information Chapter 4. JavaServer Pages Technology What Is a JSP Page? The Example JSP Pages The Life Cycle of a JSP Page Creating Static Content Creating Dynamic Content
Unified Expression Language JavaBeans Components Using Custom Tags Reusing Content in JSP Pages Transferring Control to Another Web Component Including an Applet Setting Properties for Groups of JSP Pages Further Information Chapter 5. JavaServer Pages Documents The Example JSP Document Creating a JSP Document Identifying the JSP Document to the Container Chapter 6. JavaServer Pages Standard Tag Library The Example JSP Pages Using JSTL Core Tag Library XML Tag Library Internationalization Tag Library SQL Tag Library Functions Further Information Chapter 7. Custom Tags in JSP Pages What Is a Custom Tag? The Example JSP Pages Types of Tags Encapsulating Reusable Content Using Tag Files Tag Library Descriptors Programming Simple Tag Handlers Chapter 8. Scripting in JSP Pages The Example JSP Pages Using Scripting Disabling Scripting Declarations Scriptlets Expressions Programming Tags That Accept Scripting Elements Chapter 9. JavaServer Faces Technology JavaServer Faces Technology Benefits What Is a JavaServer Faces Application? A Simple JavaServer Faces Application User Interface Component Model Navigation Model Backing Beans The Life Cycle of a JavaServer Faces Page Further Information Chapter 10. Using JavaServer Faces Technology in JSP Pages The Example JavaServer Faces Application Setting Up a Page Using the Core Tags Adding UI Components to a Page Using the HTML Component Tags Using Localized Data Using the Standard Converters Registering Listeners on Components Using the Standard Validators Binding Component Values and Instances to External Data Sources Binding Converters, Listeners, and Validators to Backing Bean Properties
Referencing a Backing Bean Method Using Custom Objects Chapter 11. Developing with JavaServer Faces Technology Writing Bean Properties Performing Localization Creating a Custom Converter Implementing an Event Listener Creating a Custom Validator Writing Backing Bean Methods Chapter 12. Creating Custom UI Components Determining Whether You Need a Custom Component or Renderer Understanding the Image Map Example Steps for Creating a Custom Component Creating Custom Component Classes Delegating Rendering to a Renderer Handling Events for Custom Components Creating the Component Tag Handler Defining the Custom Component Tag in a Tag Library Descriptor Chapter 13. Configuring JavaServer Faces Applications Application Configuration Resource File Configuring Beans Registering Custom Error Messages Registering Custom Localized Static Text Registering a Custom Validator Registering a Custom Converter Configuring Navigation Rules Registering a Custom Renderer with a Render Kit Registering a Custom Component Basic Requirements of a JavaServer Faces Application Chapter 14. Internationalizing and Localizing Web Applications Java Platform Localization Classes Providing Localized Messages and Labels Date and Number Formatting Character Sets and Encodings Further Information Part Two: Web Services Chapter 15. Building Web Services with JAX-WS Setting the Port Creating a Simple Web Service and Client with JAX-WS Types Supported by JAX-WS Web Services Interoperability and JAX-WS Further Information Chapter 16. Binding between XML Schema and Java Classes JAXB Architecture Representing XML Content Binding XML Schemas Customizing JAXB Bindings Examples Basic Examples Customizing JAXB Bindings Java-to-Schema Examples Further Information Chapter 17. Streaming API for XML Why StAX? StAX API Using StAX
Sun's Streaming XML Parser Implementation Example Code Further Information Chapter 18. SOAP with Attachments API for Java Overview of SAAJ Tutorial Code Examples Further Information Chapter 19. Java API for XML Registries Overview of JAXR Implementing a JAXR Client Running the Client Examples Using JAXR Clients in Java EE Applications Further Information Part Three: Enterprise Beans Chapter 20. Enterprise Beans What Is an Enterprise Bean? What Is a Session Bean? What Is a Message-Driven Bean? Defining Client Access with Interfaces The Contents of an Enterprise Bean Naming Conventions for Enterprise Beans The Life Cycles of Enterprise Beans Further Information Chapter 21. Getting Started with Enterprise Beans Creating the Enterprise Bean Creating the Application Client Creating the Web Client Deploying the Java EE Application Running the Application Client Running the Web Client Modifying the Java EE Application Chapter 22. Session Bean Examples The cart Example A Web Service Example: helloservice Using the Timer Service Handling Exceptions Chapter 23. A Message-Driven Bean Example Example Application Overview The Application Client The Message-Driven Bean Class Packaging, Deploying, and Running the SimpleMessage Example Creating Deployment Descriptors for Message-Driven Beans Part Four: Persistence Chapter 24. Introduction to the Java Persistence API Entities Managing Entities Chapter 25. Persistence in the Web Tier Accessing Databases from Web Applications Chapter 26. Persistence in the EJB Tier The order Application The roster Application Chapter 27. The Java Persistence Query Language Terminology
Simplified Syntax Example Queries Full Syntax Part Five: Services Chapter 28. Introduction to Security in Java EE Overview Security Implementation Mechanisms Securing Containers Securing the Application Server Working with Realms, Users, Groups, and Roles Establishing a Secure Connection Using SSL Further Information Chapter 29. Securing Java EE Applications Securing Enterprise Beans Enterprise Bean Example Applications Securing Application Clients Securing EIS Applications Example Applications in the Application Server Further Information Chapter 30. Securing Web Applications Overview Working with Security Roles Checking Caller Identity Programmatically Defining Security Requirements for Web Applications Examples: Securing Web Applications Further Information Chapter 31. The Java Message Service API Overview Basic JMS API Concepts The JMS API Programming Model Writing Simple JMS Client Applications Creating Robust JMS Applications Using the JMS API in a Java EE Application Further Information Chapter 32. Java EE Examples Using the JMS API A Java EE Application That Uses the JMS API with a Session Bean A Java EE Application That Uses the JMS API with an Entity An Application Example That Consumes Messages from a Remote Server An Application Example That Deploys a Message-Driven Bean on Two Servers Chapter 33. Transactions What Is a Transaction? Container-Managed Transactions Bean-Managed Transactions Transaction Timeouts Updating Multiple Databases Transactions in Web Components Chapter 34. Resource Connections Resources and JNDI Naming DataSource Objects and Connection Pools Resource Injection The confirmer Example Application Further Information Chapter 35. Connector Architecture About Resource Adapters Resource Adapter Contracts
Common Client Interface Further Information Part Six: Case Studies Chapter 36. The Coffee Break Application Common Code JAX-WS Coffee Supplier Service SAAJ Coffee Supplier Service Coffee Break Server Building, Packaging, Deploying, and Running the Application Chapter 37. The Duke's Bank Application Enterprise Beans Application Client Web Client Building, Packaging, Deploying, and Running the Application Appendix A. Java Encoding Schemes Further Information Appendix B. Preparation for Java EE Certification Exams CX-310-081: Sun Certified Web Component Developer SL-351: Business Component Development with Enterprise JavaBeans™ Technology About the Authors Index
Copyright Copyright © 2006 Sun Microsystems, Inc. 4150 Network Circle, Santa Clara, California 95054 U.S.A. All rights reserved. Duke logo™ designed by Joe Palrang. RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the United States Government is subject to the restrictions set forth in DFARS 252.2277013 (c)(1)(ii) and FAR 52.22719. The release described in this manual may be protected by one or more U.S. patents, foreign patents, or pending applications. Sun Microsystems, Inc. (SUN) hereby grants to you a fully paid, nonexclusive, nontransferable, perpetual, worldwide limited license (without the right to sublicense) under SUN's intellectual property rights that are essential to practice this specification. This license allows and is limited to the creation and distribution of clean room implementations of this specification that: (i) include a complete implementation of the current version of this specification without subsetting or supersetting; (ii) implement all the interfaces and functionality of the required packages of the Java™ 2 Platform, Standard Edition, as defined by SUN, without subsetting or supersetting; (iii) do not add any additional packages, classes, or interfaces to the java.* or javax.* packages or their subpackages; (iv) pass all test suites relating to the most recent published version of the specification of the Java 2 Platform, Standard Edition, that are available from SUN six (6) months prior to any beta release of the clean room implementation or upgrade thereto; (v) do not derive from SUN source code or binary materials; and (vi) do not include any SUN source code or binary materials without an appropriate and separate license from SUN. Sun, Sun Microsystems, the Sun logo, Solaris, Java, the Duke logo, JVM, JRE, JavaBeans, NetBeans, JDBC, JavaServer, JavaServer Pages, Enterprise JavaBeans, Java Naming and Directory Interface, JavaMail, EJB, JSP, J2SE, the Java Coffee Cup logo, and all Java-based trademarks or logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. UNIX is a registered trademark in the United States and other countries, exclusively licensed through X/Open Company, Ltd. THIS PUBLICATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THIS PUBLICATION COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE PERIODICALLY ADDED TO THE INFORMATION HEREIN; THESE CHANGES WILL BE INCORPORATED IN NEW EDITIONS OF THE PUBLICATION. SUN MICROSYSTEMS, INC. MAY MAKE IMPROVEMENTS AND/OR CHANGES IN THE PRODUCT(S) AND/OR THE PROGRAM(S) DESCRIBED IN THIS PUBLICATION AT ANY TIME. The publisher offers excellent discounts on this book when ordered in quantity for bulk purchases or special sales, which may include electronic versions and/or custom covers and content particular to your business, training goals, marketing focus, and branding interests. For more information, please contact: U.S. Corporate and Government Sales (800) 3823419
[email protected] For sales outside the United States please contact:
International Sales
[email protected] Visit us on the Web: www.awprofessional.com Library of Congress Cataloging-in-Publication Data The Java EE 5 tutorial / Eric Jendrock ... [et al.]. -- 3rd ed. p. cm. Previous ed: The J2EE Tutorial / by Stephanie Bodoff. Includes index. ISBN 0-321-49029-0 (pbk. : alk. paper) 1. Java (Computer program language) 2. Internet programming. I. Jendrock, Eric. QA76.73.J38J3652 2006 005.13'3--dc22
2006029908
All rights reserved. Printed in the United States of America. This publication is protected by copyright, and permission must be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any form or by any means, electronic, mechanical, photocopying, recording, or likewise. For information regarding permissions, write to: Pearson Education, Inc. Rights and Contracts Department 75 Arlington Street, Suite 300 Boston, MA 02116 Fax: (617) 848-7047 Cover art by Nathan Clement. Text printed in the United States on recycled paper at Courier in Stoughton, Massachusetts. First printing, October 2006
About This Tutorial This tutorial is a guide to developing enterprise applications for the Java Platform, Enterprise Edition 5 (Java EE 5). Here we cover all the things you need to know to make the best use of this tutorial.
Who Should Use This Tutorial This tutorial is intended for programmers who are interested in developing and deploying Java EE 5 applications on the Sun Java System Application Server Platform Edition 9.
Prerequisites Before proceeding with this tutorial, you should have a good knowledge of the Java programming language. A good way to get to that point is to work through The Java™ Tutorial, Fourth Edition, Sharon Zakhour et al. (Addison-Wesley, 2006). You should also be familiar with the relational database features described in JDBC API Tutorial and Reference, Third Edition, Maydene Fisher et al. (Addison-Wesley, 2003).
How to Read This Tutorial The Java EE 5 platform is quite large, and this tutorial reflects this. However, you don't have to digest everything in it at once. The tutorial has been divided into parts to help you navigate the content more easily. This tutorial opens with an introductory chapter, which you should read before proceeding to any specific technology area. Chapter 1 covers the Java EE 5 platform architecture and APIs along with the Sun Java System Application Server Platform Edition 9. When you have digested the basics, you can delve into one or more of the five main technology areas listed next. Because there are dependencies between some of the chapters, Figure 1 contains a roadmap for navigating through the tutorial. The web-tier technology chapters cover the components used in developing the presentation layer of a Java EE 5 or stand-alone web application: Java Servlet JavaServer Pages (JSP) JavaServer Pages Standard Tag Library (JSTL) JavaServer Faces Web application internationalization and localization The web services technology chapters cover the APIs used in developing standard web services:
The Java API for XML-based Web Services (JAX-WS) The Java API for XML Binding (JAXB) The Streaming API for XML (StAX) The SOAP with Attachments API for Java (SAAJ) The Java API for XML Registries (JAXR) The Enterprise JavaBeans (EJB) technology chapters cover the components used in developing the business logic of a Java EE 5 application: Session beans Message-driven beans The Persistence technology chapters cover the Java Persistence API, which is used for accessing databases from Java EE applications: Introduction to the Java Persistence API Persistence in the Web Tier Persistence in the EJB Tier The Java Persistence Query Language The platform services chapters cover the system services used by all the Java EE 5 component technologies: Transactions Resource connections Security Java Message Service The Connector architecture
Figure 1. Roadmap to This Tutorial
[View full size image]
After you have become familiar with some of the technology areas, you are ready to tackle the case studies, which tie together several of the technologies discussed in the tutorial. The Coffee Break Application describes an application that uses the web application and web services APIs. The Duke's Bank Application describes an application that employs web application technologies, enterprise beans, and the Java Persistence API. Finally, the appendix contains information about Java encoding schemes that may be helpful to the Java EE 5 application developer.
About the Examples This section tells you everything you need to know to install, build, and run the examples.
Required Software The following software is required to run the examples.
Tutorial Bundle The tutorial example source is contained in the tutorial bundle. If you are viewing this online, you need to click on the Download link at the top of any page. After you have installed the tutorial bundle, the example source code is in the
/javaeetutorial5/examples/ directory, with subdirectories for each of the technologies discussed in the tutorial.
Application Server The Sun Java System Application Server Platform Edition 9 is targeted as the build and runtime environment for the tutorial examples. To build, deploy, and run the examples, you need a copy of
the Application Server and Java 2 Platform, Standard Edition 5.0 (J2SE 5.0). If you already have a copy of the J2SE SDK, you can download the Application Server from: http://java.sun.com/javaee/downloads/index.html You can also download the Java EE 5 SDKwhich contains the Application Server and the J2SE SDKfrom the same site.
Application Server Installation Tips In the Admin configuration pane of the Application Server installer: Select the Don't Prompt for Admin User Name radio button. This will save the user name and password so that you won't need to provide them when performing administrative operations with asadmin. You will still have to provide the user name and password to log in to the Admin Console. Note the HTTP port at which the server is installed. This tutorial assumes that you are accepting the default port of 8080. If 8080 is in use during installation and the installer chooses another port or if you decide to change it yourself, you will need to update the common build properties file (described in the next section) and the configuration files for some of the tutorial examples to reflect the correct port. In the Installation Options pane, check the Add Bin Directory to PATH checkbox so that Application Server scripts (asadmin, wsimport, wsgen, xjc, and schemagen) override other installations.
NetBeans 5.5 The NetBeans integrated development environment (IDE) is a free, open-source IDE for developing Java applications, including enterprise applications. NetBeans 5.5 supports the Java EE 5 platform. You can build, package, deploy, and run the tutorial examples from within NetBeans 5.5, which you can download at http://www.netbeans.org/downloads/index.html. For information on creating enterprise applications in NetBeans 5.5, see http://www.netbeans.org/kb/55/index.html.
Apache Ant Ant is a Java technology-based build tool developed by the Apache Software Foundation (http://ant.apache.org), and is used to build, package, and deploy the tutorial examples. Ant is included with the Application Server. To use the ant command, add /lib/ant/bin to your PATH environment variable.
Registry Server You need a registry server to run the examples discussed in Chapter 19. Instructions for obtaining and setting up a registry server are provided in Chapter 19.
Building the Examples The tutorial examples are distributed with a configuration file for either NetBeans 5.5 or Ant. Directions for building the examples are provided in each chapter. Either NetBeans 5.5 or Ant may be used to build, package, deploy, and run the examples.
Building the Examples Using NetBeans 5.5 To run the tutorial examples in NetBeans 5.5, you must register your Application Server installation as a NetBeans Server Instance. Follow these instructions to register the Application Server in NetBeans 5.5. 1. 2. 3. 4. 5.
Select Tools
Server Manager to open the Server Manager dialog.
Click Add Server. Under Server, select Sun Java System Application Server and click Next. Under Platform Location, enter the location of your Application Server installation. Select Register Local Default Domain and click Next.
Under Admin Username and Admin Password, enter the admin name and password you 6. specified while installing the Application Server. 7.
Click Finish.
Building the Examples on the Command-Line Using Ant Build properties common to all the examples are specified in the build.properties file in the /javaeetutorial5/examples/bp-project/ directory. You must create this file before you can run the examples. We've included a sample file, build.properties.sample, that you should rename to build.properties and edit to reflect your environment. The tutorial examples use the Java BluePrints (http://java.sun.com/reference/blueprints/) build system and application layout structure. To run the Ant scripts, you must set common build properties in the file /javaeetutorial5/examples/bp-project/build.properties as follows: Set the javaee.home property to the location of your Application Server installation. The build process uses the javaee.home property to include the libraries in /lib/ in the classpath. All examples that run on the Application Server include the Java EE library archive/lib/javaee.jarin the build classpath. Some examples use additional libraries in /lib/; the required libraries are enumerated in the individual technology chapters. refers to the directory where you have installed the Application Server.
Note
On Windows, you must escape any backslashes in the javaee.home property with another backslash or use forward slashes as a path separator. So, if your Application Server installation is C:\Sun\AppServer, you must set javaee.home as follows: javaee.home = C:\\Sun\\AppServer or javaee.home=C:/Sun/AppServer
Set the javaee.tutorial.home property to the location of your tutorial. This property is used for Ant deployment and undeployment. For example, on UNIX: javaee.tutorial.home=/home/username/javaeetutorial5 On Windows: javaee.tutorial.home=C:/javaeetutorial5 Do not install the tutorial to a location with spaces in the path. If you did not use the default value (admin) for the admin user, set the value you specified when you installed the Application Server. If you did not use port 8080, set the you installed the Application Server. Set the admin user's password in the
domain.resources.port
admin.user
property to the
property to the value specified when
file in the /javaeetutorial5/examples/common/ directory to the value you specified when you installed the Application Server. The format of this file is AS_ADMIN_PASSWORD=password. For example: admin-password.txt
AS_ADMIN_PASSWORD=mypassword
Tutorial Example Directory Structure To facilitate iterative development and keep application source separate from compiled files, the tutorial examples use the Java BluePrints application directory structure. Each application module has the following structure: build.xml:
Ant build file
src/java:
Java source files for the module
src/conf:
configuration files for the module, with the exception of web applications
web:
JSP and HTML pages, style sheets, tag files, and images
web/WEB-INF:
nbproject:
configuration files for web applications
NetBeans project files
Examples that have multiple application modules packaged into an enterprise application archive (or EAR) have submodule directories that use the following naming conventions: -app-client:
Application clients
-ejb:
Enterprise bean JARs
-war:
web applications
The Ant build files (build.xml) distributed with the examples contain targets to create a build subdirectory and to copy and compile files into that directory; a dist subdirectory, which holds the packaged module file; and a client-jar directory, which holds the retrieved application client JAR.
Further Information This tutorial includes the basic information that you need to deploy applications on and administer the Application Server. See the Sun Java™ System Application Server Platform Edition 9 Developer's Guide at http://docs.sun.com/doc/819-3659 for information about developer features of the Application Server. See the Sun Java™ System Application Server Platform Edition 9 Administration Guide at http://docs.sun.com/doc/819-3658 for information about administering the Application Server. For information about the Java DB database included with the Application Server see the Apache web site at http://db.apache.org/derby.
Typographical Conventions Table 1 lists the typographical conventions used in this tutorial. Table 1. Typographical Conventions Font Style
Uses
italic
Emphasis, titles, first occurrence of terms
monospace
URLs, code examples, file names, path names, tool names, application names, programming language keywords, tag, interface, class, method, and field names, properties
italic monospace
Variables in code, file paths, and URLs
User-selected file path components
Menu selections indicated with the right-arrow character , for example, First Second, should be interpreted as: select the First menu, then choose Second from the First submenu.
Acknowledgments The Java EE tutorial team would like to thank the Java EE specification leads: Bill Shannon, Linda DeMichiel, Sekhar Vajjhala, Jan Luehe, Gregory Murray, Arun Gupta, Doug Kohlert, Ed Burns, V B Kumar Jayanti, Binod P. G., Sankara Rao, Dhiru Pandey, Rajiv Mordani, Farrukh Najmi, and Ron Monzillo. We would also like to thank the Java EE 5 SDK team members: Anil Gaur, Tony Ng, Inderjeet Singh, Carla Carlson, Nazrul Islam, Jerome Dochez, Jean-Francois Arcand, Chinmay Mehta, Suveen Nadipalli, Vipin Rajan, and Chinmayee Srivathsa. The chapters on custom tags and the Coffee Break and Duke's Bank applications use a template tag library that first appeared in Designing Enterprise Applications with the J2EE™ Platform, Second Edition, Inderjeet Singh et al., (Addison-Wesley, 2002). The JavaServer Faces technology and JSP Documents chapters benefited greatly from the invaluable documentation reviews and example code contributions of these engineers: Ed Burns, Roger Kitain, Jan Luehe, Craig McClanahan, and especially Ryan Lubke and Jayashri Visvanathan. The EJB technology and Java Persistence API chapters were written with extensive input from Sun's EJB and Persistence teams. We'd like to thank Marina Vatkina, Ken Saks, Geoff Halliwell, Shelly MacGowan, Linda DeMichiel, Markus Fuchs, Rochelle Raccah, Lance Andersen, Vince Kraemer, Michael Bouschen, and Tim Quinn for their contributions to the material and code examples. The security, JAXB, and StAX chapter writers greatly appreciate the input of Raja Perumal, Joseph Fialli, Ryan Shoemaker, Kohsuke Kawaguchi, Rebecca Searls, and Neeraj Bajaj, who were a key contributors both to the chapters and to the examples. We'd like to thank the NetBeans engineering and documentation teams, particularly Petr Jiricka, Jan Chalupa, Ludovic Champenois, Petr Blaha, Peter Williams, Geertjan Wielenga, Jesse Glick, Tomasz Slota, John Jullion-Ceccarelli, and Patrick Keegan, for their help in enabling NetBeans support for the code examples. Stephanie Bodoff and Dale Green contributed much content to the first and second editions of The J2EE Tutorial, and much of that content has been carried forward to the current edition. We are extremely grateful to the many internal and external reviewers who provided feedback on the tutorial. Their feedback helped improve the technical accuracy and presentation of the chapters and eliminate bugs from the examples. We would like to thank our manager, Alan Sommerer, for his support and steadying influence. We also thank Dwayne Wolff for developing and updating the illustrations in record time and our editor, Julie Bettis, for improving the readability and flow of the book. Thanks are also due to our copy editor, Hartley Ferguson, for helping this multiauthor project achieve a common style. Finally, we would like to express our profound appreciation to Greg Doench, Elizabeth Ryan, and the production team at Addison-Wesley for graciously seeing our large, complicated manuscript to publication.
Feedback To send comments, broken link reports, errors, suggestions, and questions about this tutorial to the tutorial team, please use the feedback form at http://java.sun.com/javaee/5/docs/tutorial/information/sendusmail.html.
1. Overview Developers today increasingly recognize the need for distributed, transactional, and portable applications that leverage the speed, security, and reliability of server-side technology. In the world of information technology, enterprise applications must be designed, built, and produced for less money, with greater speed, and with fewer resources. With the Java™ Platform, Enterprise Edition (Java EE), development of Java enterprise applications has never been easier or faster. The aim of the Java EE 5 platform is to provide developers a powerful set of APIs while reducing development time, reducing application complexity, and improving application performance. The Java EE 5 platform introduces a simplified programming model. With Java EE 5 technology, XML deployment descriptors are now optional. Instead, a developer can simply enter the information as an annotation directly into a Java source file, and the Java EE server will configure the component at deployment and runtime. These annotations are generally used to embed in a program data that would otherwise be furnished in a deployment descriptor. With annotations, the specification information is put directly in your code next to the program element that it affects. In the Java EE platform, dependency injection can be applied to all resources that a component needs, effectively hiding the creation and lookup of resources from application code. Dependency injection can be used in EJB containers, web containers, and application clients. Dependency injection allows the Java EE container to automatically insert references to other required components or resources using annotations. The Java™ Persistence API is new to the Java EE 5 platform. The Java Persistence API provides an object/relational mapping for managing relational data in enterprise beans, web components, and application clients. It can also be used in Java SE applications, outside of the Java EE environment. This tutorial uses examples to describe the features and functionalities available in the Java EE 5 platform for developing enterprise applications. Whether you are a new or experienced Enterprise developer, you should find the examples and accompanying text a valuable and accessible knowledge base for creating your own solutions. If you are new to Java EE enterprise application development, this chapter is a good place to start. Here you will review development basics, learn about the Java EE architecture and APIs, become acquainted with important terms and concepts, and find out how to approach Java EE application programming, assembly, and deployment.
Java EE Application Model The Java EE application model begins with the Java programming language and the Java virtual machine. The proven portability, security, and developer productivity they provide forms the basis of the application model. Java EE is designed to support applications that implement enterprise services for customers, employees, suppliers, partners, and others who make demands on or contributions to the enterprise. Such applications are inherently complex, potentially accessing data from a variety of sources and distributing applications to a variety of clients. To better control and manage these applications, the business functions to support these various users are conducted in the middle tier. The middle tier represents an environment that is closely controlled by an enterprise's information technology department. The middle tier is typically run on dedicated server hardware and has access to the full services of the enterprise. The Java EE application model defines an architecture for implementing services as multitier applications that deliver the scalability, accessibility, and manageability needed by enterprise-level applications. This model partitions the work needed to implement a multitier service into two parts: the business and presentation logic to be implemented by the developer, and the standard system services provided by the Java EE platform. The developer can rely on the platform to provide solutions for the hard systems-level problems of developing a multitier service.
Distributed Multitiered Applications The Java EE platform uses a distributed multitiered application model for enterprise applications. Application logic is divided into components according to function, and the various application components that make up a Java EE application are installed on different machines depending on the tier in the multitiered Java EE environment to which the application component belongs. Figure 11 shows two multitiered Java EE applications divided into the tiers described in the following list. The Java EE application parts shown in Figure 11 are presented in Java EE Components (page 4). Client-tier components run on the client machine. Web-tier components run on the Java EE server. Business-tier components run on the Java EE server. Enterprise information system (EIS)-tier software runs on the EIS server.
Figure 11. Multitiered Applications
[View full size image]
Although a Java EE application can consist of the three or four tiers shown in Figure 11, Java EE multitiered applications are generally considered to be three-tiered applications because they are distributed over three locations: client machines, the Java EE server machine, and the database or legacy machines at the back end. Three-tiered applications that run in this way extend the standard two-tiered client and server model by placing a multithreaded application server between the client application and back-end storage.
Security
While other enterprise application models require platform-specific security measures in each application, the Java EE security environment enables security constraints to be defined at deployment time. The Java EE platform makes applications portable to a wide variety of security implementations by shielding application developers from the complexity of implementing security features. The Java EE platform provides standard declarative access control rules that are defined by the developer and interpreted when the application is deployed on the server. Java EE also provides standard login mechanisms so application developers do not have to implement these mechanisms in their applications. The same application works in a variety of different security environments without changing the source code.
Java EE Components Java EE applications are made up of components. A Java EE component is a self-contained functional software unit that is assembled into a Java EE application with its related classes and files and that communicates with other components. The Java EE specification defines the following Java EE components: Application clients and applets are components that run on the client. Java Servlet, JavaServer Faces, and JavaServer Pages™ (JSP™) technology components are web components that run on the server. Enterprise JavaBeans™ (EJB™) components (enterprise beans) are business components that run on the server. Java EE components are written in the Java programming language and are compiled in the same way as any program in the language. The difference between Java EE components and "standard" Java classes is that Java EE components are assembled into a Java EE application, are verified to be well formed and in compliance with the Java EE specification, and are deployed to production, where they are run and managed by the Java EE server.
Java EE Clients A Java EE client can be a web client or an application client.
Web Clients A web client consists of two parts: (1) dynamic web pages containing various types of markup language (HTML, XML, and so on), which are generated by web components running in the web tier, and (2) a web browser, which renders the pages received from the server. A web client is sometimes called a thin client. Thin clients usually do not query databases, execute complex business rules, or connect to legacy applications. When you use a thin client, such heavyweight operations are off-loaded to enterprise beans executing on the Java EE server, where they can leverage the security, speed, services, and reliability of Java EE server-side technologies.
Applets A web page received from the web tier can include an embedded applet. An applet is a small client application written in the Java programming language that executes in the Java virtual machine installed in the web browser. However, client systems will likely need the Java Plug-in and possibly a security policy file for the applet to successfully execute in the web browser. Web components are the preferred API for creating a web client program because no plug-ins or security policy files are needed on the client systems. Also, web components enable cleaner and more modular application design because they provide a way to separate applications programming from web page design. Personnel involved in web page design thus do not need to understand Java programming language syntax to do their jobs.
Application Clients An application client runs on a client machine and provides a way for users to handle tasks that require a richer user interface than can be provided by a markup language. It typically has a graphical user interface (GUI) created from the Swing or the Abstract Window Toolkit (AWT) API, but a command-line interface is certainly possible. Application clients directly access enterprise beans running in the business tier. However, if application requirements warrant it, an application client can open an HTTP connection to establish communication with a servlet running in the web tier. Application clients written in languages other than Java can interact with Java EE 5 servers, enabling the Java EE 5 platform to interoperate with legacy systems, clients, and non-Java languages.
The JavaBeans™ Component Architecture The server and client tiers might also include components based on the JavaBeans component architecture (JavaBeans components) to manage the data flow between an application client or applet and components running on the Java EE server, or between server components and a database. JavaBeans components are not considered Java EE components by the Java EE specification. JavaBeans components have properties and have get and set methods for accessing the properties. JavaBeans components used in this way are typically simple in design and implementation but should conform to the naming and design conventions outlined in the JavaBeans component architecture.
Java EE Server Communications Figure 12 shows the various elements that can make up the client tier. The client communicates with the business tier running on the Java EE server either directly or, as in the case of a client running in a browser, by going through JSP pages or servlets running in the web tier.
Figure 12. Server Communication
[View full size image]
Your Java EE application uses a thin browser-based client or thick application client. In deciding which one to use, you should be aware of the trade-offs between keeping functionality on the client and close to the user (thick client) and off-loading as much functionality as possible to the server (thin client). The more functionality you off-load to the server, the easier it is to distribute, deploy, and manage the application; however, keeping more functionality on the client can make for a better perceived user experience.
Web Components Java EE web components are either servlets or pages created using JSP technology (JSP pages) and/or JavaServer Faces technology. Servlets are Java programming language classes that dynamically process requests and construct responses. JSP pages are text-based documents that execute as servlets but allow a more natural approach to creating static content. JavaServer Faces technology builds on servlets and JSP technology and provides a user interface component framework for web applications. Static HTML pages and applets are bundled with web components during application assembly but are not considered web components by the Java EE specification. Server-side utility classes can also be bundled with web components and, like HTML pages, are not considered web components. As shown in Figure 13, the web tier, like the client tier, might include a JavaBeans component to manage the user input and send that input to enterprise beans running in the business tier for processing.
Figure 13. Web Tier and Java EE Applications
[View full size image]
Business Components Business code, which is logic that solves or meets the needs of a particular business domain such as banking, retail, or finance, is handled by enterprise beans running in the business tier. Figure 14 shows how an enterprise bean receives data from client programs, processes it (if necessary), and sends it to the enterprise information system tier for storage. An enterprise bean also retrieves data from storage, processes it (if necessary), and sends it back to the client program.
Figure 14. Business and EIS Tiers
[View full size image]
Enterprise Information System Tier The enterprise information system tier handles EIS software and includes enterprise infrastructure systems such as enterprise resource planning (ERP), mainframe transaction processing, database systems, and other legacy information systems. For example, Java EE application components
might need access to enterprise information systems for database connectivity.
Java EE Containers Normally, thin-client multitiered applications are hard to write because they involve many lines of intricate code to handle transaction and state management, multithreading, resource pooling, and other complex low-level details. The component-based and platform-independent Java EE architecture makes Java EE applications easy to write because business logic is organized into reusable components. In addition, the Java EE server provides underlying services in the form of a container for every component type. Because you do not have to develop these services yourself, you are free to concentrate on solving the business problem at hand.
Container Services Containers are the interface between a component and the low-level platform-specific functionality that supports the component. Before a web, enterprise bean, or application client component can be executed, it must be assembled into a Java EE module and deployed into its container. The assembly process involves specifying container settings for each component in the Java EE application and for the Java EE application itself. Container settings customize the underlying support provided by the Java EE server, including services such as security, transaction management, Java Naming and Directory Interface™ (JNDI) lookups, and remote connectivity. Here are some of the highlights: The Java EE security model lets you configure a web component or enterprise bean so that system resources are accessed only by authorized users. The Java EE transaction model lets you specify relationships among methods that make up a single transaction so that all methods in one transaction are treated as a single unit. JNDI lookup services provide a unified interface to multiple naming and directory services in the enterprise so that application components can access these services. The Java EE remote connectivity model manages low-level communications between clients and enterprise beans. After an enterprise bean is created, a client invokes methods on it as if it were in the same virtual machine. Because the Java EE architecture provides configurable services, application components within the same Java EE application can behave differently based on where they are deployed. For example, an enterprise bean can have security settings that allow it a certain level of access to database data in one production environment and another level of database access in another production environment. The container also manages nonconfigurable services such as enterprise bean and servlet life cycles, database connection resource pooling, data persistence, and access to the Java EE platform APIs (see Java EE 5 APIs, page 18).
Container Types The deployment process installs Java EE application components in the Java EE containers as
illustrated in Figure 15.
Figure 15. Java EE Server and Containers
[View full size image]
Java EE server: The runtime portion of a Java EE product. A Java EE server provides EJB and web containers. Enterprise JavaBeans (EJB) container: Manages the execution of enterprise beans for Java EE applications. Enterprise beans and their container run on the Java EE server. Web container: Manages the execution of JSP page and servlet components for Java EE applications. Web components and their container run on the Java EE server. Application client container: Manages the execution of application client components. Application clients and their container run on the client. Applet container: Manages the execution of applets. Consists of a web browser and Java Plug-in running on the client together.
Web Services Support Web services are web-based enterprise applications that use open, XML-based standards and transport protocols to exchange data with calling clients. The Java EE platform provides the XML APIs and tools you need to quickly design, develop, test, and deploy web services and clients that fully interoperate with other web services and clients running on Java-based or non-Java-based platforms. To write web services and clients with the Java EE XML APIs, all you do is pass parameter data to the method calls and process the data returned; or for document-oriented web services, you send documents containing the service data back and forth. No low-level programming is needed because the XML API implementations do the work of translating the application data to and from an XML-based data stream that is sent over the standardized XML-based transport protocols. These XML-based standards and protocols are introduced in the following sections. The translation of data to a standardized XML-based data stream is what makes web services and clients written with the Java EE XML APIs fully interoperable. This does not necessarily mean that the data being transported includes XML tags because the transported data can itself be plain text, XML data, or any kind of binary data such as audio, video, maps, program files, computer-aided design (CAD) documents and the like. The next section introduces XML and explains how parties doing business can use XML tags and schemas to exchange data in a meaningful way.
XML XML is a cross-platform, extensible, text-based standard for representing data. When XML data is exchanged between parties, the parties are free to create their own tags to describe the data, set up schemas to specify which tags can be used in a particular kind of XML document, and use XML stylesheets to manage the display and handling of the data. For example, a web service can use XML and a schema to produce price lists, and companies that receive the price lists and schema can have their own stylesheets to handle the data in a way that best suits their needs. Here are examples: One company might put XML pricing information through a program to translate the XML to HTML so that it can post the price lists to its intranet. A partner company might put the XML pricing information through a tool to create a marketing presentation. Another company might read the XML pricing information into an application for processing.
SOAP Transport Protocol Client requests and web service responses are transmitted as Simple Object Access Protocol (SOAP) messages over HTTP to enable a completely interoperable exchange between clients and web services, all running on different platforms and at various locations on the Internet. HTTP is a familiar request-and response standard for sending messages over the Internet, and SOAP is an XML-based protocol that follows the HTTP request-and-response model.
The SOAP portion of a transported message handles the following: Defines an XML-based envelope to describe what is in the message and how to process the message Includes XML-based encoding rules to express instances of application-defined data types within the message Defines an XML-based convention for representing the request to the remote service and the resulting response
WSDL Standard Format The Web Services Description Language (WSDL) is a standardized XML format for describing network services. The description includes the name of the service, the location of the service, and ways to communicate with the service. WSDL service descriptions can be stored in UDDI registries or published on the web (or both). The Sun Java System Application Server Platform Edition 8 provides a tool for generating the WSDL specification of a web service that uses remote procedure calls to communicate with clients.
UDDI and ebXML Standard Formats Other XML-based standards, such as Universal Description, Discovery and Integration (UDDI) and ebXML, make it possible for businesses to publish information on the Internet about their products and web services, where the information can be readily and globally accessed by clients who want to do business.
Java EE Application Assembly and Deployment A Java EE application is packaged into one or more standard units for deployment to any Java EE platform-compliant system. Each unit contains: A functional component or components (enterprise bean, JSP page, servlet, applet, etc.) An optional deployment descriptor that describes its content Once a Java EE unit has been produced, it is ready to be deployed. Deployment typically involves using a platform's deployment tool to specify location-specific information, such as a list of local users that can access it and the name of the local database. Once deployed on a local platform, the application is ready to run.
Packaging Applications A Java EE application is delivered in an Enterprise Archive (EAR) file, a standard Java Archive (JAR) file with an .ear extension. Using EAR files and modules makes it possible to assemble a number of different Java EE applications using some of the same components. No extra coding is needed; it is only a matter of assembling (or packaging) various Java EE modules into Java EE EAR files. An EAR file (see Figure 16) contains Java EE modules and deployment descriptors. A deployment descriptor is an XML document with an .xml extension that describes the deployment settings of an application, a module, or a component. Because deployment descriptor information is declarative, it can be changed without the need to modify the source code. At runtime, the Java EE server reads the deployment descriptor and acts upon the application, module, or component accordingly.
Figure 16. EAR File Structure
There are two types of deployment descriptors: Java EE and runtime. A Java EE deployment descriptor is defined by a Java EE specification and can be used to configure deployment settings on any Java EE-compliant implementation. A runtime deployment descriptor is used to configure Java EE implementation-specific parameters. For example, the Sun Java System Application Server Platform Edition 9 runtime deployment descriptor contains information such as the context root of a web application, the mapping of portable names of an application's resources to the server's resources, and Application Server implementation-specific parameters, such as caching directives. The Application Server runtime deployment descriptors are named sun-moduleType.xml and are located in the same directory as the Java EE deployment descriptor. A Java EE module consists of one or more Java EE components for the same container type and one component deployment descriptor of that type. An enterprise bean module deployment descriptor, for example, declares transaction attributes and security authorizations for an enterprise bean. A Java EE module without an application deployment descriptor can be deployed as a stand-alone module. The four types of Java EE modules are as follows: EJB modules, which contain class files for enterprise beans and an EJB deployment descriptor. EJB modules are packaged as JAR files with a .jar extension.
Web modules, which contain servlet class files, JSP files, supporting class files, GIF and HTML files, and a web application deployment descriptor. Web modules are packaged as JAR files with a .war (Web ARchive) extension. Application client modules, which contain class files and an application client deployment descriptor. Application client modules are packaged as JAR files with a .jar extension. Resource adapter modules, which contain all Java interfaces, classes, native libraries, and other documentation, along with the resource adapter deployment descriptor. Together, these implement the Connector architecture (see J2EE Connector Architecture, page 23) for a particular EIS. Resource adapter modules are packaged as JAR files with an .rar (resource adapter archive) extension.
Development Roles Reusable modules make it possible to divide the application development and deployment process into distinct roles so that different people or companies can perform different parts of the process. The first two roles involve purchasing and installing the Java EE product and tools. After software is purchased and installed, Java EE components can be developed by application component providers, assembled by application assemblers, and deployed by application deployers. In a large organization, each of these roles might be executed by different individuals or teams. This division of labor works because each of the earlier roles outputs a portable file that is the input for a subsequent role. For example, in the application component development phase, an enterprise bean software developer delivers EJB JAR files. In the application assembly role, another developer combines these EJB JAR files into a Java EE application and saves it in an EAR file. In the application deployment role, a system administrator at the customer site uses the EAR file to install the Java EE application into a Java EE server. The different roles are not always executed by different people. If you work for a small company, for example, or if you are prototyping a sample application, you might perform the tasks in every phase.
Java EE Product Provider The Java EE product provider is the company that designs and makes available for purchase the Java EE platform APIs, and other features defined in the Java EE specification. Product providers are typically application server vendors who implement the Java EE platform according to the Java EE 5 Platform specification.
Tool Provider The tool provider is the company or person who creates development, assembly, and packaging tools used by component providers, assemblers, and deployers.
Application Component Provider The application component provider is the company or person who creates web components, enterprise beans, applets, or application clients for use in Java EE applications.
Enterprise Bean Developer An enterprise bean developer performs the following tasks to deliver an EJB JAR file that contains the enterprise bean(s): Writes and compiles the source code Specifies the deployment descriptor
Packages the
.class
files and deployment descriptor into the EJB JAR file
Web Component Developer A web component developer performs the following tasks to deliver a WAR file containing the web component(s): Writes and compiles servlet source code Writes JSP, JavaServer Faces, and HTML files Specifies the deployment descriptor Packages the
.class, .jsp,
and
.html
files and deployment descriptor into the WAR file
Application Client Developer An application client developer performs the following tasks to deliver a JAR file containing the application client: Writes and compiles the source code Specifies the deployment descriptor for the client Packages the
.class
files and deployment descriptor into the JAR file
Application Assembler The application assembler is the company or person who receives application modules from component providers and assembles them into a Java EE application EAR file. The assembler or deployer can edit the deployment descriptor directly or can use tools that correctly add XML tags according to interactive selections. A software developer performs the following tasks to deliver an EAR file containing the Java EE application: Assembles EJB JAR and WAR files created in the previous phases into a Java EE application (EAR) file Specifies the deployment descriptor for the Java EE application Verifies that the contents of the EAR file are well formed and comply with the Java EE specification
Application Deployer and Administrator The application deployer and administrator is the company or person who configures and deploys
the Java EE application, administers the computing and networking infrastructure where Java EE applications run, and oversees the runtime environment. Duties include such things as setting transaction controls and security attributes and specifying connections to databases. During configuration, the deployer follows instructions supplied by the application component provider to resolve external dependencies, specify security settings, and assign transaction attributes. During installation, the deployer moves the application components to the server and generates the container-specific classes and interfaces. A deployer or system administrator performs the following tasks to install and configure a Java EE application: Adds the Java EE application (EAR) file created in the preceding phase to the Java EE server Configures the Java EE application for the operational environment by modifying the deployment descriptor of the Java EE application Verifies that the contents of the EAR file are well formed and comply with the Java EE specification Deploys (installs) the Java EE application EAR file into the Java EE server
Java EE 5 APIs Figure 17 illustrates the availability of the Java EE 5 platform APIs in each Java EE container type. The following sections give a brief summary of the technologies required by the Java EE platform, and the APIs used in Java EE applications.
Figure 17. Java EE Platform APIs
[View full size image]
Enterprise JavaBeans Technology An Enterprise JavaBeans™ (EJB™) component, or enterprise bean, is a body of code having fields and methods to implement modules of business logic. You can think of an enterprise bean as a building block that can be used alone or with other enterprise beans to execute business logic on the Java EE server. There are two kinds of enterprise beans: session beans and message-driven beans. A session bean represents a transient conversation with a client. When the client finishes executing, the session bean and its data are gone. A message-driven bean combines features of a session bean and a message listener, allowing a business component to receive messages asynchronously. Commonly, these are Java Message Service (JMS) messages. In Java EE 5, entity beans have been replaced by Java™ persistence API entities. An entity represents persistent data stored in one row of a database table. If the client terminates, or if the server shuts down, the persistence manager ensures that the entity data is saved.
Java Servlet Technology Java servlet technology lets you define HTTP-specific servlet classes. A servlet class extends the capabilities of servers that host applications that are accessed by way of a request-response programming model. Although servlets can respond to any type of request, they are commonly used to extend the applications hosted by web servers.
JavaServer Pages Technology JavaServer Pages™ (JSP™) technology lets you put snippets of servlet code directly into a textbased document. A JSP page is a text-based document that contains two types of text: static data (which can be expressed in any text-based format such as HTML, WML, and XML) and JSP elements, which determine how the page constructs dynamic content.
JavaServer Pages Standard Tag Library The JavaServer Pages Standard Tag Library (JSTL) encapsulates core functionality common to many JSP applications. Instead of mixing tags from numerous vendors in your JSP applications, you employ a single, standard set of tags. This standardization allows you to deploy your applications on any JSP container that supports JSTL and makes it more likely that the implementation of the tags is optimized. JSTL has iterator and conditional tags for handling flow control, tags for manipulating XML documents, internationalization tags, tags for accessing databases using SQL, and commonly used functions.
JavaServer Faces JavaServer Faces technology is a user interface framework for building web applications. The main components of JavaServer Faces technology are as follows: A GUI component framework. A flexible model for rendering components in different kinds of HTML or different markup languages and technologies. A Renderer object generates the markup to render the component and converts the data stored in a model object to types that can be represented in a view. A standard
RenderKit
for generating HTML/4.01 markup.
The following features support the GUI components: Input validation Event handling Data conversion between model objects and components Managed model object creation Page navigation configuration All this functionality is available using standard Java APIs and XML-based configuration files.
Java Message Service API The Java Message Service (JMS) API is a messaging standard that allows Java EE application components to create, send, receive, and read messages. It enables distributed communication that is loosely coupled, reliable, and asynchronous.
Java Transaction API The Java Transaction API (JTA) provides a standard interface for demarcating transactions. The Java EE architecture provides a default auto commit to handle transaction commits and rollbacks. An auto commit means that any other applications that are viewing data will see the updated data after each database read or write operation. However, if your application performs two separate database access operations that depend on each other, you will want to use the JTA API to demarcate where the entire transaction, including both operations, begins, rolls back, and commits.
JavaMail API Java EE applications use the JavaMail™ API to send email notifications. The JavaMail API has two parts: an application-level interface used by the application components to send mail, and a service provider interface. The Java EE platform includes JavaMail with a service provider that allows application components to send Internet mail.
JavaBeans Activation Framework The JavaBeans Activation Framework (JAF) is included because JavaMail uses it. JAF provides standard services to determine the type of an arbitrary piece of data, encapsulate access to it, discover the operations available on it, and create the appropriate JavaBeans component to perform those operations.
Java API for XML Processing The Java API for XML Processing (JAXP), part of the Java SE platform, supports the processing of XML documents using Document Object Model (DOM), Simple API for XML (SAX), and Extensible Stylesheet Language Transformations (XSLT). JAXP enables applications to parse and transform XML documents independent of a particular XML processing implementation. JAXP also provides namespace support, which lets you work with schemas that might otherwise have naming conflicts. Designed to be flexible, JAXP lets you use any XML-compliant parser or XSL processor from within your application and supports the W3C schema. You can find information on the W3C schema at this URL: http://www.w3.org/XML/Schema.
Java API for XML Web Services (JAX-WS) The JAX-WS specification provides support for web services that use the JAXB API for binding XML
data to Java objects. The JAX-WS specification defines client APIs for accessing web services as well as techniques for implementing web service endpoints. The Web Services for J2EE specification describes the deployment of JAX-WS-based services and clients. The EJB and servlet specifications also describe aspects of such deployment. It must be possible to deploy JAX-WSbased applications using any of these deployment models. The JAX-WS specification describes the support for message handlers that can process message requests and responses. In general, these message handlers execute in the same container and with the same privileges and execution context as the JAX-WS client or endpoint component with which they are associated. These message handlers have access to the same JNDI java:comp/env namespace as their associated component. Custom serializers and deserializers, if supported, are treated in the same way as message handlers.
Java Architecture for XML Binding (JAXB) The Java Architecture for XML Binding (JAXB) provides a convenient way to bind an XML schema to a representation in Java language programs. JAXB can be used independently or in combination with JAX-WS, where it provides a standard data binding for web service messages. All Java EE application client containers, web containers, and EJB containers support the JAXB API.
SOAP with Attachments API for Java The SOAP with Attachments API for Java (SAAJ) is a low-level API on which JAX-WS and JAXR depend. SAAJ enables the production and consumption of messages that conform to the SOAP 1.1 specification and SOAP with Attachments note. Most developers do not use the SAAJ API, instead using the higher-level JAX-WS API.
Java API for XML Registries The Java API for XML Registries (JAXR) lets you access business and general-purpose registries over the web. JAXR supports the ebXML Registry and Repository standards and the emerging UDDI specifications. By using JAXR, developers can learn a single API and gain access to both of these important registry technologies. Additionally, businesses can submit material to be shared and search for material that others have submitted. Standards groups have developed schemas for particular kinds of XML documents; two businesses might, for example, agree to use the schema for their industry's standard purchase order form. Because the schema is stored in a standard business registry, both parties can use JAXR to access it.
J2EE Connector Architecture The J2EE Connector architecture is used by tools vendors and system integrators to create resource adapters that support access to enterprise information systems that can be plugged in to any Java EE product. A resource adapter is a software component that allows Java EE application components to access and interact with the underlying resource manager of the EIS. Because a resource adapter is specific to its resource manager, typically there is a different resource adapter for each type of database or enterprise information system.
The J2EE Connector architecture also provides a performance-oriented, secure, scalable, and message-based transactional integration of Java EE-based web services with existing EISs that can be either synchronous or asynchronous. Existing applications and EISs integrated through the J2EE Connector architecture into the Java EE platform can be exposed as XML-based web services by using JAX-WS and Java EE component models. Thus JAX-WS and the J2EE Connector architecture are complementary technologies for enterprise application integration (EAI) and endto-end business integration.
Java Database Connectivity API The Java™ Database Connectivity (JDBC) API lets you invoke SQL commands from Java programming language methods. You use the JDBC API in an enterprise bean when you have a session bean access the database. You can also use the JDBC API from a servlet or a JSP page to access the database directly without going through an enterprise bean. The JDBC API has two parts: an application-level interface used by the application components to access a database, and a service provider interface to attach a JDBC driver to the Java EE platform.
Java Persistence API The Java™ Persistence API is a Java standards-based solution for persistence. Persistence uses an object-relational mapping approach to bridge the gap between an object oriented model and a relational database. Java Persistence consists of three areas: The Java Persistence API The query language Object/relational mapping metadata
Java Naming and Directory Interface The Java Naming and Directory Interface™ (JNDI) provides naming and directory functionality, enabling applications to access multiple naming and directory services, including existing naming and directory services such as LDAP, NDS, DNS, and NIS. It provides applications with methods for performing standard directory operations, such as associating attributes with objects and searching for objects using their attributes. Using JNDI, a Java EE application can store and retrieve any type of named Java object, allowing Java EE applications to coexist with many legacy applications and systems. Java EE naming services provide application clients, enterprise beans, and web components with access to a JNDI naming environment. A naming environment allows a component to be customized without the need to access or change the component's source code. A container implements the component's environment and provides it to the component as a JNDI naming context. A Java EE component can locate its environment naming context using JNDI interfaces. A component can create a javax.naming.InitialContext object and looks up the environment naming
context in InitialContext under the name java:comp/env. A component's naming environment is stored directly in the environment naming context or in any of its direct or indirect subcontexts. A Java EE component can access named system-provided and user-defined objects. The names of system-provided objects, such as JTA UserTransaction objects, are stored in the environment naming context, java:comp/env. The Java EE platform allows a component to name user-defined objects, such as enterprise beans, environment entries, JDBC DataSource objects, and message connections. An object should be named within a subcontext of the naming environment according to the type of the object. For example, enterprise beans are named within the subcontext java:comp/env/ejb, and JDBC DataSource references in the subcontext java:comp/env/jdbc.
Java Authentication and Authorization Service The Java Authentication and Authorization Service (JAAS) provides a way for a Java EE application to authenticate and authorize a specific user or group of users to run it. JAAS is a Java programming language version of the standard Pluggable Authentication Module (PAM) framework, which extends the Java Platform security architecture to support user-based authorization.
Simplified Systems Integration The Java EE platform is a platform-independent, full systems integration solution that creates an open marketplace in which every vendor can sell to every customer. Such a marketplace encourages vendors to compete, not by trying to lock customers into their technologies but instead by trying to outdo each other in providing products and services that benefit customers, such as better performance, better tools, or better customer support. The Java EE 5 APIs enable systems and applications integration through the following: Unified application model across tiers with enterprise beans Simplified request-and-response mechanism with JSP pages and servlets Reliable security model with JAAS XML-based data interchange integration with JAXP, SAAJ, and JAX-WS Simplified interoperability with the J2EE Connector architecture Easy database connectivity with the JDBC API Enterprise application integration with message-driven beans and JMS, JTA, and JNDI
Sun Java System Application Server Platform Edition 9 The Sun Java System Application Server Platform Edition 9 is a fully compliant implementation of the Java EE 5 platform. In addition to supporting all the APIs described in the previous sections, the Application Server includes a number of Java EE tools that are not part of the Java EE 5 platform but are provided as a convenience to the developer. This section briefly summarizes the tools that make up the Application Server, and instructions for starting and stopping the Application Server, starting the Admin Console, and starting and stopping the Java DB database server. Other chapters explain how to use the remaining tools.
Tools The Application Server contains the tools listed in Table 11. Basic usage information for many of the tools appears throughout the tutorial. For detailed information, see the online help in the GUI tools. Table 11. Application Server Tools Tool
Description
Admin Console
A web-based GUI Application Server administration utility. Used to stop the Application Server and manage users, resources, and applications.
asadmin
A command-line Application Server administration utility. Used to start and stop the Application Server and manage users, resources, and applications.
asant
A portable command-line build tool that is an extension of the Ant tool developed by the Apache Software Foundation (see http://ant.apache.org/). asant contains additional tasks that interact with the Application Server administration utility.
appclient
A command-line tool that launches the application client container and invokes the client application packaged in the application client JAR file.
capture-schema
A command-line tool to extract schema information from a database, producing a schema file that the Application Server can use for container-managed persistence.
package-appclient
A command-line tool to package the application client container libraries and JAR files.
Java DB database
A copy of the Java DB database server.
verifier
A command-line tool to validate Java EE deployment descriptors.
xjc
A command-line tool to transform, or bind, a source XML schema to a set of JAXB content classes in the Java programming language.
schemagen
A command-line tool to create a schema file for each namespace referenced in your Java classes.
wsimport
A command-line tool to generate JAX-WS portable artifacts for a given WSDL file. After generation, these artifacts can be packaged in a WAR file with the WSDL and schema documents along with the endpoint implementation and then deployed.
wsgen
A command-line tool to read a web service endpoint class and generate all the required JAX-WS portable artifacts for web service deployment and invocation.
Starting and Stopping the Application Server To start the Application Server, open a terminal window or command prompt and execute the following: asadmin start-domain --verbose domain1
A domain is a set of one or more Application Server instances managed by one administration server. Associated with a domain are the following: The Application Server's port number. The default is 8080. The administration server's port number. The default is 4848. An administration user name and password. You specify these values when you install the Application Server. The examples in this tutorial assume that you chose the default ports. With no arguments, the start-domain command initiates the default domain, which is domain1. The -verbose flag causes all logging and debugging output to appear on the terminal window or command prompt (it will also go into the server log, which is located in /domains/domain1/logs/server.log). Or, on Windows, you can choose: Programs
Sun Microsystems
Application Server PE
Start Default Server
After the server has completed its startup sequence, you will see the following output: Domain domain1 started.
To stop the Application Server, open a terminal window or command prompt and execute: asadmin stop-domain domain1
-
Or, on Windows, choose: Programs
Sun Microsystems
Application Server PE
Stop Default Server
When the server has stopped you will see the following output: Domain domain1 stopped.
Starting the Admin Console To administer the Application Server and manage users, resources, and Java EE applications, use the Admin Console tool. The Application Server must be running before you invoke the Admin Console. To start the Admin Console, open a browser at the following URL: http://localhost:4848/asadmin/
On Windows, from the Start menu, choose: Programs
Sun Microsystems
Application Server PE
Admin Console
Starting and Stopping the Java DB Database Server The Application Server includes the Java DB database. To start the Java DB database server, open a terminal window or command prompt and execute: asadmin start-database
On Windows, from the Start menu, choose: Programs
Sun Microsystem
Application Server PE
Start Java DB
To stop the Java DB server, open a terminal window or command prompt and execute: asadmin stop-database
On Windows, from the Start menu, choose: Programs
Sun Microsystems
Application Server PE
Stop Java DB
For information about the Java DB database included with the Application Server, see the Apache Derby Project web site at http://db.apache.org/derby/.
Debugging Java EE Applications This section describes how to determine what is causing an error in your application deployment or execution.
Using the Server Log One way to debug applications is to look at the server log in /domains/domain1/logs/server.log. The log contains output from the Application Server and your applications. You can log messages from any Java class in your application with System.out.println and the Java Logging APIs (documented at http://java.sun.com/j2se/1.5.0/docs/guide/logging/index.html) and from web components with the ServletContext.log method. If you start the Application Server with the --verbose flag, all logging and debugging output will appear on the terminal window or command prompt and the server log. If you start the Application Server in the background, debugging information is only available in the log. You can view the server log with a text editor or with the Admin Console log viewer. To use the log viewer: 1. 2. 3.
Select the Application Server node. Select the Logging tab. Click the Open Log Viewer button. The log viewer will open and display the last 40 entries.
If you wish to display other entries: 1. 2. 3.
Click the Modify Search button. Specify any constraints on the entries you want to see. Click the Search button at the bottom of the log viewer.
Using a Debugger The Application Server supports the Java Platform Debugger Architecture (JPDA). With JPDA, you can configure the Application Server to communicate debugging information using a socket. To debug an application using a debugger: Enable debugging in the Application Server using the Admin Console:
a. Select the Application Server node. b. Select the JVM Settings tab. The default debug options are set to:
1.
-Xdebug -Xrunjdwp:transport=dt_socket,server=y, suspend=n,address=9009
As you can see, the default debugger socket port is 9009. You can change it to a port not in use by the Application Server or another service. c. Check the Enabled box of the Debug field. d. Click the Save button.
2.
Stop the Application Server and then restart it.
Part One: The Web Tier Part One explores the technologies in the web tier.
2. Getting Started with Web Applications A web application is a dynamic extension of a web or application server. There are two types of web applications: Presentation-oriented: A presentation-oriented web application generates interactive web pages containing various types of markup language (HTML, XML, and so on) and dynamic content in response to requests. Chapters 3 through 14 cover how to develop presentationoriented web applications. Service-oriented: A service-oriented web application implements the endpoint of a web service. Presentation-oriented applications are often clients of service-oriented web applications. Chapters 15 and 18 cover how to develop service-oriented web applications. In the Java 2 platform, web components provide the dynamic extension capabilities for a web server. Web components are either Java servlets, JSP pages, or web service endpoints. The interaction between a web client and a web application is illustrated in Figure 21. The client sends an HTTP request to the web server. A web server that implements Java Servlet and JavaServer Pages technology converts the request into an HTTPServletRequest object. This object is delivered to a web component, which can interact with JavaBeans components or a database to generate dynamic content. The web component can then generate an HTTPServletResponse or it can pass the request to another web component. Eventually a web component generates a HTTPServletResponse object. The web server converts this object to an HTTP response and returns it to the client.
Figure 21. Java Web Application Request Handling
Servlets are Java programming language classes that dynamically process requests and construct responses. JSP pages are text-based documents that execute as servlets but allow a more natural approach to creating static content. Although servlets and JSP pages can be used interchangeably, each has its own strengths. Servlets are best suited for service-oriented applications (web service endpoints are implemented as servlets) and the control functions of a presentation-oriented application, such as dispatching requests and handling nontextual data. JSP pages are more appropriate for generating text-based markup such as HTML, Scalable Vector Graphics (SVG), Wireless Markup Language (WML), and XML.
Since the introduction of Java Servlet and JSP technology, additional Java technologies and frameworks for building interactive web applications have been developed. Figure 22 illustrates these technologies and their relationships.
Figure 22. Java Web Application Technologies
Notice that Java Servlet technology is the foundation of all the web application technologies, so you should familiarize yourself with the material in Chapter 3 even if you do not intend to write servlets. Each technology adds a level of abstraction that makes web application prototyping and development faster and the web applications themselves more maintainable, scalable, and robust. Web components are supported by the services of a runtime platform called a web container. A web container provides services such as request dispatching, security, concurrency, and life-cycle management. It also gives web components access to APIs such as naming, transactions, and email. Certain aspects of web application behavior can be configured when the application is installed, or deployed, to the web container. The configuration information is maintained in a text file in XML format called a web application deployment descriptor (DD). A DD must conform to the schema described in the Java Servlet Specification. This chapter gives a brief overview of the activities involved in developing web applications. First we summarize the web application life cycle. Then we describe how to package and deploy very simple web applications on the Application Server. We move on to configuring web applications and discuss how to specify the most commonly used configuration parameters. We then introduce an exampleDuke's Bookstorethat we use to illustrate all the Java EE web-tier technologies, and we describe how to set up the shared components of this example. Finally we discuss how to access databases from web applications and set up the database resources needed to run Duke's Bookstore.
Web Application Life Cycle A web application consists of web components, static resource files such as images, and helper classes and libraries. The web container provides many supporting services that enhance the capabilities of web components and make them easier to develop. However, because a web application must take these services into account, the process for creating and running a web application is different from that of traditional stand-alone Java classes. The process for creating, deploying, and executing a web application can be summarized as follows: 1. 2. 3. 4. 5. 6.
Develop the web component code. Develop the web application deployment descriptor. Compile the web application components and helper classes referenced by the components. Optionally package the application into a deployable unit. Deploy the application into a web container. Access a URL that references the web application.
Developing web component code is covered in the later chapters. Steps 2 through 4 are expanded on in the following sections and illustrated with a Hello, World-style presentation-oriented application. This application allows a user to enter a name into an HTML form (Figure 23) and then displays a greeting after the name is submitted (Figure 24).
Figure 23. Greeting Form
[View full size image]
Figure 24. Response
[View full size image]
The Hello application contains two web components that generate the greeting and the response. This chapter discusses two versions of the application: a JSP version called hello1, in which the components are implemented by two JSP pages (index.jsp and response.jsp) and a servlet version called hello2, in which the components are implemented by two servlet classes (GreetingServlet.java and ResponseServlet.java). The two versions are used to illustrate tasks involved in packaging, deploying, configuring, and running an application that contains web components. The section About the Examples (page xxxiv) explains how to get the code for these examples. After you install the tutorial bundle, the source code for the examples is in the following directories: /javaeetutorial5/examples/web/hello1/
/javaeetutorial5/examples/web/hello2/
Web Modules In the Java EE architecture, web components and static web content files such as images are called web resources. A web module is the smallest deployable and usable unit of web resources. A Java EE web module corresponds to a web application as defined in the Java Servlet specification. In addition to web components and web resources, a web module can contain other files: Server-side utility classes (database beans, shopping carts, and so on). Often these classes conform to the JavaBeans component architecture. Client-side classes (applets and utility classes). A web module has a specific structure. The top-level directory of a web module is the document root of the application. The document root is where JSP pages, client-side classes and archives, and static web resources, such as images, are stored. The document root contains a subdirectory named directories: web.xml:
/WEB-INF/,
which contains the following files and
The web application deployment descriptor
Tag library descriptor files (see Tag Library Descriptors, page 229) classes:
A directory that contains server-side classes: servlets, utility classes, and JavaBeans components tags:
A directory that contains tag files, which are implementations of tag libraries (see Tag File Location, page 214) lib:
A directory that contains JAR archives of libraries called by server-side classes
If your web module does not contain any servlets, filter, or listener components then it does not need a web application deployment descriptor. In other words, if your web module only contains JSP pages and static files then you are not required to include a web.xml file. The hello1 example, first discussed in Packaging Web Modules (page 39), contains only JSP pages and images and therefore does not include a deployment descriptor. You can also create application-specific subdirectories (that is, package directories) in either the document root or the /WEB-INF/classes/ directory. A web module can be deployed as an unpacked file structure or can be packaged in a JAR file known as a web archive (WAR) file. Because the contents and use of WAR files differ from those of JAR files, WAR file names use a .war extension. The web module just described is portable; you can deploy it into any web container that conforms to the Java Servlet Specification. To deploy a WAR on the Application Server, the file must also contain a runtime deployment descriptor. The runtime deployment descriptor is an XML file that contains information such as the context root of the web application and the mapping of the portable names of an application's resources to the Application Server's resources. The Application Server web application runtime
DD is named sun-web.xml and is located in /WEB-INF/ along with the web application DD. The structure of a web module that can be deployed on the Application Server is shown in Figure 25.
Figure 25. Web Module Structure
Packaging Web Modules A web module must be packaged into a WAR in certain deployment scenarios and whenever you want to distribute the web module. You package a web module into a WAR by executing the jar command in a directory laid out in the format of a web module, by using the ant utility, or by using the IDE tool of your choice. This tutorial shows you how to use NetBeans 5.5 or ant to build, package, and deploy the sample applications. To build the 1.
hello1
application with NetBeans 5.5, follow these instructions:
In NetBeans 5.5, select File
Open Project.
In the Open Project dialog, navigate to: 2. /javaeetutorial5/examples/web/
3. 4.
Select the
hello1
folder.
Select the Open as Main Project checkbox. Click Open Project Folder.
5. 6.
In the Projects tab, right-click the
To build the 1.
hello1
application using the
In a terminal window, go to Run
hello1
ant
project and select Build Project.
utility, follow these steps:
/javaeetutorial5/examples/web/hello1/.
ant.
This target will spawn any necessary compilations, copy files to the /javaeetutorial5/examples/web/hello1/build/ directory, create the WAR file, and copy it to the 2. /javaeetutorial5/examples/web/hello1/dist/ directory.
Deploying a WAR File You can deploy a WAR file to the Application Server in a few ways: Copying the WAR into the
/domains/domain1/autodeploy/
directory.
Using the Admin Console. By running
asadmin
or
ant
to deploy the WAR.
All these methods are described briefly in this chapter; however, throughout the tutorial, we use ant and NetBeans 5.5 for packaging and deploying.
Setting the Context Root A context root identifies a web application in a Java EE server. You specify the context root when you deploy a web module. A context root must start with a forward slash (/) and end with a string. In a packaged web module for deployment on the Application Server, the context root is stored in sun-web.xml. To edit the context root, do the following: 1. 2. 3. 4. 5.
Expand your project tree in the Projects pane of NetBeans 5.5. Expand the Web Pages and WEB-INF nodes of your project. Double-click
sun-web.xml.
In the editor pane, click Edit As XML. Edit the context root, which is enclosed by the
context-root
element.
Deploying a Packaged Web Module If you have deployed the hello1 application, before proceeding with this section, undeploy the application by following one of the procedures described in Undeploying Web Modules (page 45).
Deploying with the Admin Console Expand the Applications node.
1.
Select the Web Applications node.
2.
Click the Deploy button.
3.
Select the radio button labeled "Package file to be uploaded to the Application Server."
4.
Type the full path to the WAR file (or click on Browse to find it), and then click the OK button.
5.
Click Next.
6.
Type the application name.
7.
Type the context root.
8.
Select the Enabled box.
9. 10.
Click the Finish button.
Deploying with asadmin To deploy a WAR with
asadmin,
open a terminal window or command prompt and execute
asadmin deploy full-path-to-war-file
Deploying with ant To deploy a WAR with ant, open a terminal window or command prompt in the directory where you built and packaged the WAR, and execute ant deploy
Deploying with NetBeans 5.5
To deploy a WAR with NetBeans 5.5, do the following: 1. 2. 3.
In NetBeans 5.5, select File
Open Project.
In the Open Project dialog, navigate to your project and open it. In the Projects tab, right-click the project and select Deploy Project.
Testing Deployed Web Modules Now that the web module is deployed, you can view it by opening the application in a web browser. By default, the application is deployed to host localhost on port 8080. The context root of the web application is hello1. To test the application, follow these steps: 1.
Open a web browser. Enter the following URL in the web address box:
2. http://localhost:8080/hello1
3.
Enter your name, and click Submit.
The application should display the name you submitted as shown in Figure 23 and Figure 24.
Listing Deployed Web Modules The Application Server provides two ways to view the deployed web modules: Admin Console 1. Open the URL
http://localhost:4848/asadmin
2. Expand the nodes Applications
asadmin
1. Execute asadmin list-components
in a browser.
Web Applications.
Updating Web Modules A typical iterative development cycle involves deploying a web module and then making changes to the application components. To update a deployed web module, you must do the following: 1. 2. 3. 4.
Recompile any modified classes. If you have deployed a packaged web module, update any modified components in the WAR. Redeploy the module. Reload the URL in the client.
Updating a Packaged Web Module This section describes how to update the First, change the greeting in the file
hello1
web module that you packaged.
/javaeetutorial5/examples/web/hello1/web/index.jsp
Hi, my name is Duke. What's yours?
To update the project in NetBeans 5.5: Right-click on the project and select Build Project. Right-click on the project and select Deploy Project. To update the project using the Ant build tool: Run
ant to
Run
copy the modified JSP page into the
ant deploy
build
directory.
to deploy the WAR file.
To view the modified module, reload the URL in the browser. You should see the screen in Figure 26 in the browser.
Figure 26. New Greeting
[View full size image]
to
Dynamic Reloading If dynamic reloading is enabled, you do not have to redeploy an application or module when you change its code or deployment descriptors. All you have to do is copy the changed JSP or class files into the deployment directory for the application or module. The deployment directory for a web module named context_root is /domains/domain1/applications/j2eemodules/context_root. The server checks for changes periodically and redeploys the application, automatically and dynamically, with the changes. This capability is useful in a development environment, because it allows code changes to be tested quickly. Dynamic reloading is not recommended for a production environment, however, because it may degrade performance. In addition, whenever a reload is done, the sessions at that time become invalid and the client must restart the session. To enable dynamic reloading, use the Admin Console: 1. 2. 3.
Select the Applications Server node. Select the Advanced tab. Check the Reload Enabled box to enable dynamic reloading.
Enter a number of seconds in the Reload Poll Interval field to set the interval at which 4. applications and modules are checked for code changes and dynamically reloaded. 5.
Click the Save button.
In addition, to load new servlet files or reload deployment descriptor changes, you must do the following: Create an empty file named
.reload
at the root of the module:
1. /domains/domain1/applications/j2ee-modules/
context_root/.reload
Explicitly update the execute
.reload
file's time stamp each time you make these changes. On UNIX,
2. touch .reload
For JSP pages, changes are reloaded automatically at a frequency set in the Reload Poll Interval field. To disable dynamic reloading of JSP pages, set the Reload Poll Interval field value to 1.
Undeploying Web Modules You can undeploy web modules in four ways: NetBeans 5.5 1. Ensure the Sun Java System Application Server is running. 2. In the Runtime window, expand the Sun Java System Application Server instance and the node containing the application or module. 3. Right-click the application or module and choose Undeploy.
Admin Console 1. Open the URL
http://localhost:4848/asadmin
in a browser.
2. Expand the Applications node. 3. Select Web Applications. 4. Click the checkbox next to the module you wish to undeploy. 5. Click the Undeploy button.
asadmin
1. Execute asadmin undeploy context_root ant
1. In the directory where you built and packaged the WAR, execute
ant undeploy
Configuring Web Applications Web applications are configured via elements contained in the web application deployment descriptor. The following sections give a brief introduction to the web application features you will usually want to configure. A number of security parameters can be specified; these are covered in Securing Web Applications (page 987). In the following sections, examples demonstrate procedures for configuring the Hello, World application. If Hello, World does not use a specific configuration feature, the section gives references to other examples that illustrate how to specify the deployment descriptor element.
Mapping URLs to Web Components When a request is received by the web container it must determine which web component should handle the request. It does so by mapping the URL path contained in the request to a web application and a web component. A URL path contains the context root and an alias: http://host:port/context_root/alias
Setting the Component Alias The alias identifies the web component that should handle a request. The alias path must start with a forward slash (/) and end with a string or a wildcard expression with an extension (for example, *.jsp). Since web containers automatically map an alias that ends with *.jsp, you do not have to specify an alias for a JSP page unless you wish to refer to the page by a name other than its file name. The hello2 application has two servlets that need to be mapped in the web application's web.xml file in NetBeans 5.5 by doing the following: 1.
In NetBeans 5.5, select File
Open Project.
In the Open Project dialog, navigate to: 2. /javaeetutorial5/examples/web/
3. 4. 5.
Select the
hello2
folder.
Select the Open as Main Project checkbox. Click Open Project Folder. Expand the project tree in the Projects pane.
web.xml
file. You can edit a
6. 7. 8.
Expand the Web pages node and then the WEB-INF node in the project tree. Double-click the
web.xml
file inside the WEB-INF node.
The following steps detail how we made the necessary edits to the web.xml file, including how to set the display name and how to map the servlet components. Because we've already made the edits, you can just use the steps to view the settings we've made. To set the display name: 1. 2.
Click General at the top of the editor to open the general view. Enter
hello2
in the Display Name field.
To perform the servlet mappings: 1. 2. 3. 4. 5. 6. 7.
Click Servlets at the top of the editor to open the servlets view. Click Add Servlet. In the Add Servlet dialog, enter Enter
servlets.GreetingServlet
Enter
/greeting
GreetingServlet
in the Servlet Name field.
in the Servlet Class field.
in the URL Pattern field.
Click OK. Repeat the preceding steps, except enter ResponseServlet as the servlet name, servlets.ResponseServlet as the servlet class, and /response as the URL pattern.
If you are not using NetBeans 5.5, you can add these settings using a text editor. To package the example with NetBeans 5.5, do the following: 1.
In NetBeans 5.5, select File
Open Project.
In the Open Project dialog, navigate to: 2. /javaeetutorial5/examples/web/
3. 4.
Select the
hello2
folder.
Select the Open as Main Project checkbox.
5. Click Open Project Folder. 6.
In the Projects tab, right-click the
To package the example with the 1.
In a terminal window, go to Run
ant
hello2
project and select Build Project.
utility, do the following:
/javaeetutorial5/examples/web/hello2/.
ant.
This target will build the WAR file and copy it to the 2. /javaeetutorial5/examples/web/hello2/dist/ directory.
To deploy the example using NetBeans 5.5, right-click on the project in the Projects pane and select Deploy Project. To deploy the example using ant, run ant deploy. The deploy target in this case gives you an incorrect URL to run the application. To run the application, please use the URL shown at the end of this section. To run the application, first deploy the web module, and then open the URL http://localhost:8080/hello2/greeting in a browser.
Declaring Welcome Files The welcome files mechanism allows you to specify a list of files that the web container will use for appending to a request for a URL (called a valid partial request) that is not mapped to a web component. For example, suppose you define a welcome file welcome.html. When a client requests a URL such as host:port/webapp/directory, where directory is not mapped to a servlet or JSP page, the file host:port/webapp/directory/welcome.html is returned to the client. If a web container receives a valid partial request, the web container examines the welcome file list and appends to the partial request each welcome file in the order specified and checks whether a static resource or servlet in the WAR is mapped to that request URL. The web container then sends the request to the first resource in the WAR that matches. If no welcome file is specified, the Application Server will use a file named index. XXX, where XXX can be html or jsp, as the default welcome file. If there is no welcome file and no file named index. XXX, the Application Server returns a directory listing. To specify a welcome file in the web application deployment descriptor using NetBeans 5.5, do the following: 1. 2. 3.
Open the project if you haven't already. Expand the project's node in the Projects pane. Expand the Web Pages node and then the WEB-INF node. Double-click
web.xml.
4. Do one of the following, making sure that the JSP pages you specify are actually included in the WAR file:
5.
a. Click Pages at the top of the editor pane and enter the names of the JSP pages that act as welcome files in the Welcome Files field. b. Click XML at the top of the editor pane, specify the JSP pages using welcome-file elements and include these elements inside a welcome-file-list element. The welcome-file element defines the JSP page to be used as the welcome page.
The example discussed in Encapsulating Reusable Content Using Tag Files (page 212) has a welcome file.
Setting Initialization Parameters The web components in a web module share an object that represents their application context (see Accessing the Web Context, page 88). You can pass initialization parameters to the context or to a web component. To add a context parameter using NetBeans 5.5, do the following: 1. 2. 3. 4. 5. 6. 7.
Open the project if you haven't already. Expand the project's node in the Projects pane. Expand the Web Pages node and then the WEB-INF node. Double-click
web.xml.
Click General at the top of the editor pane. Select the Context Parameters node. Click Add. In the Add Context Parameter dialog, do the following:
a. Enter the name that specifies the context object in the Param Name field. 8.
b. Enter the parameter to pass to the context object in the Param Value field. c. Click OK.
Alternatively, you can edit the XML of the web.xml directly by clicking XML at the top of the editor pane and using the following elements to add a context parameter: A
param-name
element that specifies the context object.
A
param-value
A
context-param
element that specifies the parameter to pass to the context object. element that encloses the previous two elements.
For a sample context parameter, see the example discussed in The Example JSP Pages (page 101). To add a web component initialization parameter using NetBeans 5.5, do the following: 1. 2. 3. 4. 5.
Open the project if you haven't already. Expand the project's node in the Projects pane. Expand the Web Pages node and then the WEB-INF node. Double-click
web.xml.
Click Servlets at the top of the editor pane.
After entering the servlet's name, class, and URL pattern, click the Add button under the 6. Initialization Parameters table. In the Add Initialization Parameter dialog:
a. Enter the name of the parameter in the Param Name field. 7.
b. Enter the parameter's value in the Param Value Field. c. Click OK.
Alternatively, you can edit the XML of the web.xml file directly by clicking XML at the top of the editor pane and using the following elements to add a context parameter: A
param-name
A
param-value
An
element that specifies the name of the initialization parameter
init-param
element that specifies the value of the initialization parameter. element that encloses the previous two elements.
Mapping Errors to Error Screens When an error occurs during execution of a web application, you can have the application display
a specific error screen according to the type of error. In particular, you can specify a mapping between the status code returned in an HTTP response or a Java programming language exception returned by any web component (see Handling Errors, page 66) and any type of error screen. To set up error mappings using NetBeans 5.5, do the following: 1. 2. 3. 4. 5. 6. 7.
Open the project if you haven't already. Expand the project's node in the Projects pane. Expand the Web Pages node and then the WEB-INF node. Double-click
web.xml.
Click Pages at the top of the editor pane. Expand the Error Pages node. Click Add. In the Add Error Page dialog:
a. Click Browse to locate the page that you want to act as the error page. b. Enter the HTTP status code that will cause the error page to be opened in the Error Code field.
8.
c. Enter the exception that will cause the error page to load in the Exception Type field. d. Click OK.
Alternatively, you can click XML at the top of the editor pane and enter the error page mapping by hand using the following elements: An exception-type element specifying either the exception or the HTTP status code that will cause the error page to be opened. A location element that specifies the name of a web resource to be invoked when the status code or exception is returned. The name should have a leading forward slash (/). An
error-page
element that encloses the previous two elements.
You can have multiple error-page elements in your deployment descriptor. Each one of the elements identifies a different error that causes an error page to open. This error page can be the same for any number of error-page elements.
Note
You can also define error screens for a JSP page contained in a WAR. If error screens are defined for both the WAR and a JSP page, the JSP page's error page takes precedence. See Handling Errors (page 109).
For a sample error page mapping, see the example discussed in The Example Servlets (page 60).
Declaring Resource References If your web component uses objects such as enterprise beans, data sources, or web services, you use Java EE annotations to inject these resources into your application. Annotations eliminate a lot of the boilerplate lookup code and configuration elements that previous versions of Java EE required. Although resource injection using annotations can be more convenient for the developer, there are some restrictions from using it in web applications. First, you can only inject resources into container-managed objects. This is because a container must have control over the creation of a component so that it can perform the injection into a component. As a result, you cannot inject resources into objects such as simple JavaBeans components. However, JavaServer Faces managed beans are managed by the container; therefore, they can accept resource injections. Additionally, JSP pages cannot accept resource injections. This is because the information represented by annotations must be available at deployment time, but the JSP page is compiled after that; therefore, the annotation will not be seen when it is needed. Those components that can accept resource injections are listed in Table 21. Table 21. Web Components That Accept Resource Injections Component
Interface/Class
Servlets
javax.servlet.Servlet
Servlet Filters
javax.servlet.ServletFilter
Event Listeners
javax.servlet.ServletContextListener javax.servlet.ServletContextAttributeListener javax.servlet.ServletRequestListener javax.servlet.ServletRequestAttributeListener javax.servlet.http.HttpSessionListener javax.servlet.http.HttpSessionAttributeListener javax.servlet.http.HttpSessionBindingListener
Taglib Listeners
same as above
Taglib Tag Handlers
javax.servlet.jsp.tagext.JspTag
Managed Beans
Plain Old Java Objects
This section describes how to use a couple of the annotations supported by a servlet container to inject resources. Chapter 25 describes how web applications use annotations supported by the Java Persistence API. Chapter 30 describes how to use annotations to specify information about securing web applications.
Declaring a Reference to a Resource The @Resource annotation is used to declare a reference to a resource such as a data source, an enterprise bean, or an environment entry. This annotation is equivalent to declaring a resource-ref element in the deployment descriptor. The @Resource annotation is specified on a class, method or field. The container is responsible for injecting references to resources declared by the @Resource annotation and mapping it to the proper JNDI resources. In the following example, the @Resource annotation is used to inject a data source into a component that needs to make a connection to the data source, as is done when using JDBC technology to access a relational database: @Resource javax.sql.DataSource catalogDS; public getProductsByCategory() { // get a connection and execute the query Connection conn = catalogDS.getConnection(); .. }
The container injects this data source prior to the component being made available to the application. The data source JNDI mapping is inferred from the field name catalogDS and the type, javax.sql.DataSource. If you have multiple resources that you need to inject into one component, you need to use the @Resources annotation to contain them, as shown by the following example: @Resources ({ @Resource (name="myDB" type=java.sql.DataSource), @Resource(name="myMQ" type=javax.jms.ConnectionFactory) })
The web application examples in this tutorial use the Java Persistence API to access relational databases. This API does not require you to explicitly create a connection to a data source. Therefore, the examples do not use the @Resource annotation to inject a data source. However, this API supports the @PersistenceUnit and @PersistenceContext annotations for injecting EntityManagerFactory and EntityManager instances, respectively. Chapter 25 describes these annotations and the use of the Java Persistence API in web applications.
Declaring a Reference to a Web Service The @WebServiceRef annotation provides a reference to a web service. The following example shows uses the @WebServiceRef annotation to declare a reference to a web service. WebServiceRef uses the
wsdlLocation
element to specify the URI of the deployed service's WSDL file:
... import javax.xml.ws.WebServiceRef; ... public class ResponseServlet extends HTTPServlet { @WebServiceRef(wsdlLocation= "http://localhost:8080/helloservice/hello?wsdl") static HelloService service;
Duke's Bookstore Examples In Chapters 3 through 14 a common exampleDuke's Bookstoreis used to illustrate the elements of Java Servlet technology, JavaServer Pages technology, the JSP Standard Tag Library, and JavaServer Faces technology. The example emulates a simple online shopping application. It provides a book catalog from which users can select books and add them to a shopping cart. Users can view and modify the shopping cart. When users are finished shopping, they can purchase the books in the cart. The Duke's Bookstore examples share common classes and a database schema. These files are located in the directory /javaeetutorial5/examples/web/bookstore/. The common classes are packaged into a JAR. Each of the Duke's Bookstore examples must include this JAR file in their WAR files. The process that builds and packages each application also builds and packages the common JAR file and includes it in the example WAR file. The next section describes how to create the bookstore database tables and resources required to run the examples.
Accessing Databases from Web Applications Data that is shared between web components and is persistent between invocations of a web application is usually maintained in a database. To maintain a catalog of books, the Duke's Bookstore examples described in Chapters 3 through 14 use the Java DB database included with the Application Server. To access the data in a database, web applications use the new Java Persistence API (see chapter 24). See chapter 25 to learn how the Duke's Bookstore applications use this API to access the book data. To run the Duke's Bookstore applications, you need to first populate the database with the book data and create a data source in the application server. The rest of this section explains how to perform these tasks.
Populating the Example Database When you deploy any of the Duke's Bookstore applications using ant deploy, the database is automatically populated at the same time. If you want to populate the database separately from the deploy task or are using NetBeans 5.5 to deploy the application, follow these steps: In a terminal window, go to the 1. example directories.
books
directory or any one of the
bookstore1
through
bookstore6
Start the Java DB database server. For instructions, see Starting and Stopping the Java DB Database Server (page 29). You don't have to do this if you are using NetBeans 5.5. It starts 2. the database server automatically. Run ant create-tables. This task runs a command to read the file 3. SQL commands contained in the file.
tutorial.sql
and execute the
At the end of the processing, you should see the following output: 4. ... [sql] 185 of 185 SQL statements executed successfully
When you are running create-tables, don't worry if you see a message that an SQL statement failed. This usually happens the first time you run the command because it always tries to delete an existing database table first before it creates a new one. The first time through, there is no table yet, of course.
Creating a Data Source in the Application Server A DataSource object has a set of properties that identify and describe the real world data source that it represents. These properties include information such as the location of the database server, the name of the database, the network protocol to use to communicate with the server, and so on.
Data sources in the Application Server implement connection pooling. To define the Duke's Bookstore data source, you use the installed Derby connection pool named DerbyPool. You create the data source using the Application Server Admin Console, following this procedure: 1. 2. 3. 4. 5. 6. 7.
Expand the Resources node. Expand the JDBC node. Select the JDBC Resources node. Click the New... button. Type
jdbc/BookDB
Choose
in the JNDI Name field.
DerbyPool
Click OK.
for the Pool Name.
Further Information For more information about web applications, refer to the following: Java Servlet specification: http://java.sun.com/products/servlet/download.html#specs The Java Servlet web site: http://java.sun.com/products/servlet
3. Java Servlet Technology As soon as the web began to be used for delivering services, service providers recognized the need for dynamic content. Applets, one of the earliest attempts toward this goal, focused on using the client platform to deliver dynamic user experiences. At the same time, developers also investigated using the server platform for this purpose. Initially, Common Gateway Interface (CGI) scripts were the main technology used to generate dynamic content. Although widely used, CGI scripting technology has a number of shortcomings, including platform dependence and lack of scalability. To address these limitations, Java servlet technology was created as a portable way to provide dynamic, user-oriented content.
What Is a Servlet? A servlet is a Java programming language class that is used to extend the capabilities of servers that host applications access via a request-response programming model. Although servlets can respond to any type of request, they are commonly used to extend the applications hosted by web servers. For such applications, Java Servlet technology defines HTTP-specific servlet classes. The javax.servlet and javax.servlet.http packages provide interfaces and classes for writing servlets. All servlets must implement the Servlet interface, which defines life-cycle methods. When implementing a generic service, you can use or extend the GenericServlet class provided with the Java Servlet API. The HttpServlet class provides methods, such as doGet and doPost, for handling HTTP-specific services. This chapter focuses on writing servlets that generate responses to HTTP requests.
The Example Servlets This chapter uses the Duke's Bookstore application to illustrate the tasks involved in programming servlets. Table 31 lists the servlets that handle each bookstore function. Each programming task is illustrated by one or more servlets. For example, BookDetailsServlet illustrates how to handle HTTP GET requests, BookDetailsServlet and CatalogServlet show how to construct responses, and CatalogServlet illustrates how to track session information. Table 31. Duke's Bookstore Example Servlets Function
Servlet
Enter the bookstore
BookStoreServlet
Create the bookstore banner
BannerServlet
Browse the bookstore catalog
CatalogServlet
Put a book in a shopping cart
CatalogServlet , BookDetailsServlet
Get detailed information on a specific book
BookDetailsServlet
Display the shopping cart
ShowCartServlet
Remove one or more books from the shopping cart
ShowCartServlet
Buy the books in the shopping cart
CashierServlet
Send an acknowledgment of the purchase
ReceiptServlet
The data for the bookstore application is maintained in a database and accessed through the database access class database.BookDBAO. The database package also contains the class Book which represents a book. The shopping cart and shopping cart items are represented by the classes cart.ShoppingCart and cart.ShoppingCartItem, respectively. The source code for the bookstore application is located in the /javaeetutorial5javaeetutorial5/examples/web/bookstore1/ directory, which is created when you unzip the tutorial bundle (see Building the Examples, page xxxv). To deploy and run the application using NetBeans 5.5, follow these steps: 1. 2.
Perform all the operations described in Accessing Databases from Web Applications (page 55). In NetBeans 5.5, select File
Open Project Folder.
In the Open Project dialog, navigate to: 3. /javaeetutorial5/examples/web/
4. 5. 6. 7. 8.
Select the
bookstore1
folder.
Select the Open as Main Project checkbox and the Open Required Projects checkbox. Click Open Project Folder. In the Projects tab, right-click the
bookstore1
project, and select Deploy Project.
To run the application, open the bookstore URL
http://localhost:8080/bookstore1/bookstore.
To deploy and run the application using Ant, follow these steps: 1.
In a terminal window, go to Run the command
/javaeetutorial5/examples/web/bookstore1/.
This target will spawn any necessary compilations, copy files to the /javaeetutorial5/examples/web/bookstore1/build/ directory, and create a WAR file and copy it 2. to the /javaeetutorial5/examples/web/bookstore1/dist/ directory. 3.
ant.
Start the Application Server.
Perform all the operations described in Creating a Data Source in the Application Server (page 4. 56). To deploy the example, run ant deploy. The deploy target outputs a URL for running the 5. application. Ignore this URL, and instead use the one shown in the next step. 6.
To run the application, open the bookstore URL
http://localhost:8080/bookstore1/bookstore.
To learn how to configure the example, refer to the deployment descriptor (the includes the following configurations: A
display-name
A set of
web.xml
file), which
element that specifies the name that tools use to identify the application.
filter
elements that identify servlet filters contained in the application.
A set of filter-mapping elements that identify which servlets will have their requests or responses filtered by the filters identified by the filter elements. A filter-mapping element can define more than one servlet mapping and more than one URL pattern for a particular filter. A set of
servlet
elements that identify all the servlet instances of the application.
A set of servlet-mapping elements that map the servlets to URL patterns. More than one URL pattern can be defined for a particular servlet. A set of error-page mappings that map exception types to an HTML page, so that the HTML page opens when an exception of that type is thrown by the application.
Troubleshooting The Duke's Bookstore database access object returns the following exceptions: Returned if a book can't be located in the bookstore database. This will occur if you haven't loaded the bookstore database with data or the server has not been started or has crashed. You can populate the database by running ant create-tables. BookNotFoundException:
Returned if the bookstore data can't be retrieved. This will occur if you haven't loaded the bookstore database with data or if the database server hasn't been started or it has crashed. BooksNotFoundException:
Returned if a servlet can't retrieve the web context attribute representing the bookstore. This will occur if the database server hasn't been started. UnavailableException:
Because we have specified an error page, you will see the message The application is unavailable. Please try later.
If you don't specify an error page, the web container generates a default page containing the message A Servlet Exception Has Occurred
and a stack trace that can help you diagnose the cause of the exception. If you use you will have to look in the server log to determine the cause of the exception.
errorpage.html,
Servlet Life Cycle The life cycle of a servlet is controlled by the container in which the servlet has been deployed. When a request is mapped to a servlet, the container performs the following steps. If an instance of the servlet does not exist, the web container
a. Loads the servlet class. 1.
b. Creates an instance of the servlet class. c. Initializes the servlet instance by calling the Initializing a Servlet (page 70).
init
method. Initialization is covered in
Invokes the service method, passing request and response objects. Service methods are 2. discussed in Writing Service Methods (page 71).
If the container needs to remove the servlet, it finalizes the servlet by calling the servlet's method. Finalization is discussed in Finalizing a Servlet (page 92).
destroy
Handling Servlet Life-Cycle Events You can monitor and react to events in a servlet's life cycle by defining listener objects whose methods get invoked when life-cycle events occur. To use these listener objects you must define and specify the listener class.
Defining the Listener Class You define a listener class as an implementation of a listener interface. Table 32 lists the events that can be monitored and the corresponding interface that must be implemented. When a listener method is invoked, it is passed an event that contains information appropriate to the event. For example, the methods in the HttpSessionListener interface are passed an HttpSessionEvent, which contains an HttpSession. Table 32. Servlet Life-Cycle Events Object
Web context (see Accessing the Web Context, page 88)
Session (See
Event
Listener Interface and Event Class
Initialization and destruction
javax.servlet.ServletContextListener ServletContextEvent
Attribute added, removed, or replaced
javax.servlet.ServletContextAttributeListener and ServletContextAttributeEvent
Creation, invalidation, activation, passivation, and
and
javax.servlet.http.HttpSessionListener , javax.servlet.http.HttpSessionActivationListener , and HttpSessionEvent
Maintaining Client State, page 89)
timeout Attribute added, removed, or replaced
javax.servlet.http.HttpSessionAttributeListener and HttpSessionBindingEvent
A servlet request has started being processed by web components
javax.servlet.ServletRequestListener ServletRequestEvent
Attribute added, removed, or replaced
javax.servlet.ServletRequestAttributeListener and ServletRequestAttributeEvent
and
Request
The listeners.ContextListener class creates and removes the database access and counter objects used in the Duke's Bookstore application. The methods retrieve the web context object from ServletContextEvent and then store (and remove) the objects as servlet context attributes. import database.BookDBAO; import javax.servlet.*; import util.Counter; import javax.ejb.*; import javax.persistence.*; public final class ContextListener implements ServletContextListener { private ServletContext context = null; @PersistenceUnit EntityManagerFactory emf; public void contextInitialized(ServletContextEvent event) { context = event.getServletContext(); try { BookDBAO bookDB = new BookDBAO(emf); context.setAttribute("bookDB", bookDB); } catch (Exception ex) { System.out.println( "Couldn't create database: " + ex.getMessage()); } Counter counter = new Counter(); context.setAttribute("hitCounter", counter); counter = new Counter(); context.setAttribute("orderCounter", counter); } public void contextDestroyed(ServletContextEvent event) { context = event.getServletContext(); BookDBAO bookDB = context.getAttribute("bookDB"); bookDB.remove(); context.removeAttribute("bookDB"); context.removeAttribute("hitCounter");
context.removeAttribute("orderCounter"); } }
Specifying Event Listener Classes You specify an event listener class using the listener element of the deployment descriptor. Review The Example Servlets (page 60) for information on how to specify the ContextListener listener class. You can specify an event listener using the deployment descriptor editor of NetBeans 5.5 by doing the following: 1. 2. 3. 4. 5. 6. 7. 8.
Expand your application's project node. Expand the project's Web Pages and WEB-INF nodes. Double-click
web.xml.
Click General at the top of the
web.xml
editor.
Expand the Web Application Listeners node. Click Add. In the Add Listener dialog, click Browse to locate the listener class. Click OK.
Handling Errors Any number of exceptions can occur when a servlet executes. When an exception occurs, the web container generates a default page containing the message A Servlet Exception Has Occurred
But you can also specify that the container should return a specific error page for a given exception. Review the deployment descriptor file included with the example to learn how to map the exceptions exception.BookNotFound, exception.BooksNotFound, and exception.OrderException returned by the Duke's Bookstore application to errorpage.html. See Mapping Errors to Error Screens (page 51) for instructions on how to specify error pages using NetBeans 5.5.
Sharing Information Web components, like most objects, usually work with other objects to accomplish their tasks. There are several ways they can do this. They can use private helper objects (for example, JavaBeans components), they can share objects that are attributes of a public scope, they can use a database, and they can invoke other web resources. The Java servlet technology mechanisms that allow a web component to invoke other web resources are described in Invoking Other Web Resources (page 84).
Using Scope Objects Collaborating web components share information via objects that are maintained as attributes of four scope objects. You access these attributes using the [get|set]Attribute methods of the class representing the scope. Table 33 lists the scope objects. Table 33. Scope Objects Scope Object
Class
Accessible From
Web context
javax.servlet.ServletContext
Web components within a web context. See Accessing the Web Context (page 88).
Session
javax.servlet.http.HttpSession
Web components handling a request that belongs to the session. See Maintaining Client State (page 89).
Request
Page
subtype of javax.servlet.ServletRequest
javax.servlet.jsp.JspContext
Web components handling the request.
The JSP page that creates the object. See Using Implicit Objects (page 111).
Figure 31 shows the scoped attributes maintained by the Duke's Bookstore application.
Figure 31. Duke's Bookstore Scoped Attributes
[View full size image]
Controlling Concurrent Access to Shared Resources In a multithreaded server, it is possible for shared resources to be accessed concurrently. In addition to scope object attributes, shared resources include in-memory data (such as instance or class variables) and external objects such as files, database connections, and network connections. Concurrent access can arise in several situations: Multiple web components accessing objects stored in the web context. Multiple web components accessing objects stored in a session. Multiple threads within a web component accessing instance variables. A web container will typically create a thread to handle each request. If you want to ensure that a servlet instance handles only one request at a time, a servlet can implement the SingleThreadModel interface. If a servlet implements this interface, you are guaranteed that no two threads will execute concurrently in the servlet's service method. A web container can implement this guarantee by synchronizing access to a single instance of the servlet, or by maintaining a pool of web component instances and dispatching each new request to a free instance. This interface does not prevent synchronization problems that result from web components accessing shared resources such as static class variables or external objects. In addition, the Servlet 2.4 specification deprecates the SingleThreadModel interface. When resources can be accessed concurrently, they can be used in an inconsistent fashion. To prevent this, you must control the access using the synchronization techniques described in the Threads lesson in The Java Tutorial, Fourth Edition, by Sharon Zakhour et al. (Addison-Wesley, 2006). In the preceding section we show five scoped attributes shared by more than one servlet: bookDB, cart, currency, hitCounter, and orderCounter. The bookDB attribute is discussed in the next section. The cart, currency, and counters can be set and read by multiple multithreaded servlets. To prevent these objects from being used inconsistently, access is controlled by synchronized methods. For example, here is the util.Counter class: public class Counter { private int counter; public Counter() { counter = 0; } public synchronized int getCounter() { return counter; } public synchronized int setCounter(int c) { counter = c; return counter; } public synchronized int incCounter() { return(++counter); } }
Accessing Databases Data that is shared between web components and is persistent between invocations of a web application is usually maintained by a database. Web components use the Java Persistence API to access relational databases. The data for Duke's Bookstore is maintained in a database and is accessed through the database access class database.BookDBAO. For example, ReceiptServlet invokes the BookDBAO.buyBooks method to update the book inventory when a user makes a purchase. The buyBooks method invokes buyBook for each book contained in the shopping cart, as shown in the following code. public void buyBooks(ShoppingCart cart) throws OrderException{ Collection items = cart.getItems(); Iterator i = items.iterator(); try { while (i.hasNext()) { ShoppingCartItem sci = (ShoppingCartItem)i.next(); Book bd = (Book)sci.getItem(); String id = bd.getBookId(); int quantity = sci.getQuantity(); buyBook(id, quantity); } } catch (Exception ex) { throw new OrderException("Commit failed: " + ex.getMessage()); } } public void buyBook(String bookId, int quantity) throws OrderException { try { Book requestedBook = em.find(Book.class, bookId); if (requestedBook != null) { int inventory = requestedBook.getInventory(); if ((inventory - quantity) >= 0) { int newInventory = inventory - quantity; requestedBook.setInventory(newInventory); } else{ throw new OrderException("Not enough of " + bookId + " in stock to complete order."); } } } catch (Exception ex) { throw new OrderException("Couldn't purchase book: " + bookId + ex.getMessage()); } }
To ensure that the order is processed in its entirety, the call to buyBooks is wrapped in a single transaction. In the following code, the calls to the begin and commit methods of UserTransaction mark the boundaries of the transaction. The call to the rollback method of UserTransaction undoes the effects of all statements in the transaction so as to protect the integrity of the data. try { utx.begin(); bookDB.buyBooks(cart); utx.commit(); } catch (Exception ex) { try { utx.rollback(); } catch(Exception e) { System.out.println("Rollback failed: "+e.getMessage()); } System.err.println(ex.getMessage()); orderCompleted = false;} }
Initializing a Servlet After the web container loads and instantiates the servlet class and before it delivers requests from clients, the web container initializes the servlet. To customize this process to allow the servlet to read persistent configuration data, initialize resources, and perform any other one-time activities, you override the init method of the Servlet interface. A servlet that cannot complete its initialization process should throw UnavailableException. All the servlets that access the bookstore database (BookStoreServlet, CatalogServlet, BookDetailsServlet, and ShowCartServlet) initialize a variable in their init method that points to the database access object created by the web context listener: public class CatalogServlet extends HttpServlet { private BookDBAO bookDB; public void init() throws ServletException { bookDB = (BookDBAO)getServletContext(). getAttribute("bookDB"); if (bookDB == null) throw new UnavailableException("Couldn't get database."); } }
Writing Service Methods The service provided by a servlet is implemented in the service method of a GenericServlet, in the doMethod methods (where Method can take the value Get, Delete, Options, Post, Put, or TRace) of an HttpServlet object, or in any other protocol-specific methods defined by a class that implements the Servlet interface. In the rest of this chapter, the term service method is used for any method in a servlet class that provides a service to a client. The general pattern for a service method is to extract information from the request, access external resources, and then populate the response based on that information. For HTTP servlets, the correct procedure for populating the response is to first retrieve an output stream from the response, then fill in the response headers, and finally write any body content to the output stream. Response headers must always be set before the response has been committed. Any attempt to set or add headers after the response has been committed will be ignored by the web container. The next two sections describe how to get information from requests and generate responses.
Getting Information from Requests A request contains data passed between a client and the servlet. All requests implement the ServletRequest interface. This interface defines methods for accessing the following information: Parameters, which are typically used to convey information between clients and servlets Object-valued attributes, which are typically used to pass information between the servlet container and a servlet or between collaborating servlets Information about the protocol used to communicate the request and about the client and server involved in the request Information relevant to localization For example, in CatalogServlet the identifier of the book that a customer wishes to purchase is included as a parameter to the request. The following code fragment illustrates how to use the getParameter method to extract the identifier: String bookId = request.getParameter("Add"); if (bookId != null) { Book book = bookDB.getBook(bookId);
You can also retrieve an input stream from the request and manually parse the data. To read character data, use the BufferedReader object returned by the request's getreader method. To read binary data, use the ServletInputStream returned by getInputStream. HTTP servlets are passed an HTTP request object, URL, HTTP headers, query string, and so on.
HttpServletRequest,
which contains the request
An HTTP request URL contains the following parts: http://[host]:[port][request path]?[query string]
The request path is further composed of the following elements: Context path: A concatenation of a forward slash (/) with the context root of the servlet's web application. Servlet path: The path section that corresponds to the component alias that activated this request. This path starts with a forward slash (/). Path info: The part of the request path that is not part of the context path or the servlet path. If the context path is /catalog and for the aliases listed in Table 34, Table 35 gives some examples of how the URL will be parsed. Table 34. Aliases Pattern
Servlet
/lawn/*
LawnServlet
/*.jsp
JSPServlet
Table 35. Request Path Elements Request Path
Servlet Path
Path Info
/catalog/lawn/index.html
/lawn
/index.html
/catalog/help/feedback.jsp /help/feedback.jsp
null
Query strings are composed of a set of parameters and values. Individual parameters are retrieved from a request by using the getParameter method. There are two ways to generate query strings: A query string can explicitly appear in a web page. For example, an HTML page generated by the CatalogServlet could contain the link Add To Cart. CatalogServlet exTRacts the parameter named Add as follows: String bookId = request.getParameter("Add"); A query string is appended to a URL when a form with a GET HTTP method is submitted. In the Duke's Bookstore application, CashierServlet generates a form, then a user name input to the form is appended to the URL that maps to ReceiptServlet, and finally ReceiptServlet exTRacts the
user name using the
getParameter
method.
Constructing Responses A response contains data passed between a server and the client. All responses implement the ServletResponse interface. This interface defines methods that allow you to: Retrieve an output stream to use to send data to the client. To send character data, use the PrintWriter returned by the response's getWriter method. To send binary data in a MIME body response, use the ServletOutputStream returned by getOutputStream. To mix binary and text data, for exampleto create a multipart responseuse a ServletOutputStream and manage the character sections manually. Indicate the content type (for example, text/html) being returned by the response with the setContentType(String) method. This method must be called before the response is committed. A registry of content type names is kept by the Internet Assigned Numbers Authority (IANA) at: http://www.iana.org/assignments/media-types/ Indicate whether to buffer output with the setBufferSize(int) method. By default, any content written to the output stream is immediately sent to the client. Buffering allows content to be written before anything is actually sent back to the client, thus providing the servlet with more time to set appropriate status codes and headers or forward to another web resource. The method must be called before any content is written or before the response is committed. Set localization information such as locale and character encoding. See Chapter 14 for details. HTTP response objects, following:
HttpServletResponse,
have fields representing HTTP headers such as the
Status codes, which are used to indicate the reason a request is not satisfied or that a request has been redirected. Cookies, which are used to store application-specific information at the client. Sometimes cookies are used to maintain an identifier for tracking a user's session (see Session Tracking, page 91). In Duke's Bookstore, BookDetailsServlet generates an HTML page that displays information about a book that the servlet retrieves from a database. The servlet first sets response headers: the content type of the response and the buffer size. The servlet buffers the page content because the database access can generate an exception that would cause forwarding to an error page. By buffering the response, the servlet prevents the client from seeing a concatenation of part of a Duke's Bookstore page with the error page should an error occur. The doGet method then retrieves a PrintWriter from the response. To fill in the response, the servlet first dispatches the request to BannerServlet, which generates a common banner for all the servlets in the application. This process is discussed in Including Other Resources in the Response (page 85). Then the servlet retrieves the book identifier from a request parameter and uses the identifier to retrieve information about the book from the bookstore database. Finally, the servlet generates HTML markup that describes the book information and
then commits the response to the client by calling the
close
method on the
public class BookDetailsServlet extends HttpServlet { ... public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... // set headers before accessing the Writer response.setContentType("text/html"); response.setBufferSize(8192); PrintWriter out = response.getWriter(); // then write the response out.println("" + "+ messages.getString("TitleBookDescription") +"); // Get the dispatcher; it gets the banner to the user RequestDispatcher dispatcher = getServletContext(). getRequestDispatcher("/banner"); if (dispatcher != null) dispatcher.include(request, response); // Get the identifier of the book to display String bookId = request.getParameter("bookId"); if (bookId != null) { // and the information about the book try { Book bd = bookDB.getBook(bookId); ... // Print the information obtained out.println("" + bd.getTitle() + "
" + ... } catch (BookNotFoundException ex) { response.resetBuffer(); throw new ServletException(ex); } } out.println("