blob: de6095bf4e3b091693a68add06647349ca88e7e9 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="author" content="troy.giunipero@sun.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="description" content="The NetBeans E-commerce Tutorial (Complete Version)">
<meta name="keywords" content="NetBeans, IDE, integrated development environment,
Java, Java EE, open source, web technology, e-commerce">
<link rel="stylesheet" type="text/css" href="../../../../netbeans.css">
<link rel="stylesheet" type="text/css" href="../../../../print.css" media="print">
<link rel="stylesheet" type="text/css" href="../../../../lytebox.css" media="screen">
<script type="text/javascript" src="../../../../images_www/js/lytebox-compressed.js"></script>
<script src="../../../../images_www/js/listCollapse.js" type="text/javascript"></script>
<title>The NetBeans E-commerce Tutorial</title>
</head>
<body>
<!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. -->
<h1 id="intro">The NetBeans E-commerce Tutorial - Introduction</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Tutorial Contents</h4>
<ol>
<li><strong>Introduction</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#about">About this Tutorial</a></li>
<li><a href="#whatEcommerce">What is an E-commerce Application?</a></li>
<li><a href="#whatJava">What is Java?</a></li>
<li><a href="#jcp">What is the Java Community Process?</a></li>
<li><a href="#ide">Why use an IDE?</a></li>
<li><a href="#netBeans">Why use NetBeans?</a></li>
<li><a href="#seeAlsoIntro">See Also</a></li>
</ul></li>
<li><a href="#design">Designing the Application</a></li>
<li><a href="#setup-dev-environ">Setting up the Development Environment</a></li>
<li><a href="#data-model">Designing the Data Model</a></li>
<li><a href="#page-views-controller">Preparing the Page Views and Controller Servlet</a></li>
<li><a href="#connect-db">Connecting the Application to the Database</a></li>
<li><a href="#entity-session">Adding Entity Classes and Session Beans</a></li>
<li><a href="#manage-sessions">Managing Sessions</a></li>
<li><a href="#transaction">Integrating Transactional Business Logic</a></li>
<li><a href="#language">Adding Language Support</a></li>
<li><a href="#security">Securing the Application</a></li>
<li><a href="#test-profile">Testing and Profiling</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ol>
</div>
</div>
<p><img src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" class="stamp"
alt="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"
title="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"></p>
<p>Welcome to the NetBeans E-commerce Tutorial. In this multi-part tutorial, you
learn how to create a simple yet effective e-commerce application that demonstrates
various important features of Java web and EE development. In doing so, you'll
familiarize yourself with the NetBeans IDE and become capable of applying it to
your own development purposes.</p>
<p>Taking the time to master the IDE will ultimately lead you to become more efficient
and versatile as a developer. While you work through the tutorial units, you'll learn
how to make best use of the IDE's facilities and tools. These include:</p>
<ul style="margin-left: 320px" class="toc">
<li><strong>Editor support for different languages:</strong> syntax highlighting,
code completion, API documentation support, keyboard shortcuts, refactoring
capabilities, and code templates</li>
<li><strong>Window system:</strong> Projects, Files and Services windows, the
Tasks window, Javadoc window, HTTP Monitor, Navigator and Palette</li>
<li><strong>Integration with other services: </strong>automatic deployment to
a registered server, database connectivity, browser interoperability</li>
<li><strong>Development tools:</strong> Debugger, Profiler, HTTP Server
Monitor, Local History support, and a graphical Diff Viewer</li>
</ul>
<p>The tutorial is modular in fashion, with each unit focusing on specific concepts,
technologies, and features of the IDE. You can successfully follow a tutorial unit
on its own using the provided setup instructions and application snapshots (from
Unit 5 onward). However, you'll get the most benefit by working through all units
consecutively, from beginning to end. This will also help to illustrate the
development process.</p>
<p>Unit 3, <a href="#setup-dev-environ">Setting up the Development Environment</a>
introduces you to the NetBeans IDE. In it, you create a Java web project which
is the basis for the work you undertake in later tutorial units. In Unit 4,
<a href="#data-model">Designing the Data Model</a>, you primarily work with
<a href="http://wb.mysql.com/" target="_blank">MySQL WorkBench</a>, a visual
database design tool, to create a data model for the application. Each successive
tutorial unit provides you with a <em>project snapshot</em> that corresponds to
the project's beginning state for that given unit. This enables you to work through
a single tutorial unit outside of the E-commerce Tutorial's larger context. To use
these snapshots, download them to your computer and open them in the IDE using the
Open Project wizard (Ctrl-Shift-O; &#8984;-Shift-O on Mac).</p>
<p>You can view a live demo of the application that you build in this tutorial:
<a href="http://services.netbeans.org/AffableBean/" target="_blank">NetBeans
E-commerce Tutorial Demo Application</a>.</p>
<p>The remainder of this unit covers some information relevant to the tutorial, as
well as basic concepts necessary for Java EE development. Make sure you understand
the concepts outlined below before proceeding with development.</p>
<br clear="left">
<br>
<h2 id="about">About this Tutorial</h2>
<div class="indent">
<h3>Who this Tutorial is for</h3>
<p>The content of this tutorial caters to four demographics:</p>
<ul>
<li>Java developers interested in expanding their skill set to include Java
EE technologies</li>
<li>Newcomers to the NetBeans IDE wanting to try out its development
environment</li>
<li>Web developers wanting to see how Java compares to other web-based
technologies</li>
<li>Students wanting to understand the nuts and bolts a simple e-commerce
application, and how its development could apply to a real-world
use-case</li>
</ul>
<p>If you fall into any of these categories, this tutorial will be helpful to
you. Depending on your background, you may find that certain tutorial units
are more difficult to grasp than others. Understanding how technologies
work is key to leveraging the IDE for your purposes. Therefore, if you are
really interested in learning the technologies involved, you may find that
this tutorial works best as a companion to the
<a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/tutorial/doc/" target="_blank">Java
EE Tutorial</a>. For each tutorial unit, make best use of the provided links
to relevant areas in the Java EE Tutorial, as well as to other useful resources.</p>
<h3>What this Tutorial Covers</h3>
<p>The application that you develop in this tutorial involves numerous concepts,
technologies, and tooling components:</p>
<ul class="toc">
<li><strong>Concepts</strong>
<ul style="margin: 5px 0 0 -2em">
<li>Front-end development</li>
<li>Web application project structure</li>
<li>Data modeling</li>
<li>Database connectivity</li>
<li>Object-relational mapping</li>
<li>Session management</li>
<li>Transactional business logic</li>
<li>Client and server-side validation</li>
<li>Localization</li>
<li>Web application security</li>
<li>Design patterns, including <a href="http://java.sun.com/blueprints/patterns/MVC.html" target="_blank">Model-View-Controller</a>
(MVC) and <a href="http://java.sun.com/blueprints/patterns/SessionFacade.html" target="_blank">Session Facade</a></li>
</ul></li>
<li><strong>Technologies</strong>
<ul style="margin: 5px 0 0 -2em">
<li>HTML, CSS, and JavaScript technologies</li>
<li>Servlet and JavaServer Pages (JSP) technologies</li>
<li>Enterprise JavaBeans (EJB) technology</li>
<li>Java Persistence API (JPA)</li>
<li>The JavaServer Pages Standard Tag Library (JSTL)</li>
<li>Java Database Connectivity (JDBC)</li>
</ul></li>
<li><strong>Development Tools</strong>
<ul style="margin: 5px 0 0 -2em">
<li>NetBeans IDE</li>
<li>GlassFish, a Java EE application server</li>
<li>MySQL, a relational database management server (RDBMS)</li>
<li>MySQL WorkBench, a visual database design tool</li>
</ul>
</li>
</ul>
</div>
<br>
<h2 id="whatEcommerce">What is an E-commerce Application?</h2>
<p>The term <em>e-commerce</em>, as we think of it today, refers to the buying and
selling of goods or services over the Internet. For example, you may think of
<a href="http://www.amazon.com/" target="_blank">Amazon</a>, which provides online
shopping for various product categories, such as books, music, and electronics.
This form of e-commerce is known as electronic retailing, or <em>e-tailing</em>,
and usually involves the transportation of physical items. It is also referred
to as <em>business-to-customer</em>, or B2C. Other well-known forms include:</p>
<ul>
<li><strong>Consumer-to-consumer (C2C): </strong>Transactions taking place
between individuals, usually through a third-party site such as an online
auction. A typical example of C2C commerce is <a href="http://www.ebay.com/" target="_blank">eBay</a>.</li>
<li><strong>Business-to-business (B2B): </strong>Trade occurring between
businesses, e.g., between a retailer and wholesaler, or between a wholesaler
and manufacturer.</li>
<li><strong>Business-to-government (B2G): </strong>Trade occurring between
businesses and government agencies.</li>
</ul>
<p>This tutorial focuses on business-to-customer (B2C) e-commerce, and applies the
typical scenario of a small retail store seeking to create a website enabling
customers to shop online. Software that accommodates a B2C scenario generally
consists of two components:</p>
<ol>
<li><strong>Store Front:</strong> The website that is accessed by customers,
enabling them to purchase goods over the Internet. Data from the store catalog
is typically maintained in a database, and pages requiring this data are
generated dynamically.</li>
<li><strong>Administration Console:</strong> A password-protected area that is
accessed over a secure connection by store staff for purposes of online management.
This typically involves CRUD (create read update delete) access to the store
catalog, management of discounts, shipping and payment options, and review
of customer orders.</li>
</ol>
<br>
<h2 id="whatJava">What is Java?</h2>
<p>In the computer software industry, the term &quot;Java&quot; refers to the
<em>Java Platform</em> as well as the <em>Java Programming Language</em>.</p>
<div class="feedback-box margin-around">
<img src="../../../../images_www/articles/73/javaee/ecommerce/intro/duke.png"
class="margin-around" alt="Image of Duke" title="Duke, the Java mascot">
<p>Duke, the Java mascot</p>
</div>
<div class="indent">
<h3>Java as a Programming Language</h3>
<p>The Java language was conceptualized by
<a href="http://en.wikipedia.org/wiki/James_Gosling" target="_blank">James Gosling</a>,
who began work on the project in 1991. The language was created with the following
5 design principles<sup><a href="#footnote1Intro" id="1Intro" style="text-decoration:none">[1]</a></sup>
in mind:</p>
<ol>
<li><strong>Simple, Object-Oriented, and Familiar:</strong> Java contains
a small, consistent core of fundamental concepts that can be grasped
quickly. It was originally modeled after the then popular C++ language,
so that programmers could easily migrate to Java. Also, it adheres to
an <em>object-oriented</em> paradigm; systems are comprised of
encapsulated objects that communicate by passing messages to one another.</li>
<li><strong>Robust and Secure:</strong> The language includes compile-time
and run-time checking to ensure that errors are identified quickly. It
also contains network and file-access security features so that distributed
applications are not compromised by intrusion or corruption.</li>
<li><strong>Architecture Neutral and Portable:</strong> One of Java's primary
advantages is its <em>portability</em>. Applications can be easily
transferred from one platform to another with minimum or no modifications.
The slogan &quot;Write once, run anywhere&quot; accompanied the Java 1.0
release in 1995, and refers to the cross-platform benefits of the language.</li>
<li><strong>High Performance:</strong> Applications run quickly and efficiently
due to various low-level features, such as enabling the Java interpreter
to run independently from the run-time environment, and applying an
automatic garbage collector to free unused memory.</li>
<li><strong>Interpreted, Threaded, and Dynamic:</strong> With Java, a developer's
source code is compiled into an intermediate, interpreted form known as
<em>bytecode</em>. The bytecode instructional set refers to the machine
language used by the Java Virtual Machine (JVM). With a suitable interpreter,
this language can then be translated into <em>native code</em> for the
platform it is run on. Multithreading capabilities are supported primarily
by means of the <code>Thread</code> class, enabling numerous tasks to occur
simultaneously. The language and run-time system are dynamic in that
applications can adapt to environment changes during execution.</li>
</ol>
<p>If you'd like to learn more about the Java language, see
the <a href="http://java.sun.com/docs/books/tutorial/" target="_blank">Java Tutorials</a>.</p>
<h3 id="platform">Java as a Platform</h3>
<p>The Java Platform signifies a software-based platform that is comprised of two
parts:</p>
<ul>
<li><strong>The Java Virtual Machine (JVM)</strong>: The JVM is an engine that
executes instructions generated by the Java compiler. The JVM can be thought
of as an instance of the Java Runtime Environment, or JRE, and is embedded
in various products, such as web browsers, servers, and operating systems.</li>
<li><strong>The Java Application Programming Interface (API)</strong>:
Prewritten code, organized into packages of similar topics. For instance,
the Applet and AWT packages include classes for creating fonts, menus,
and buttons.</li>
</ul>
<p>The Java Development Kit, or JDK, refers to the Java SE Edition, while other
kits are referred to as &quot;SDK&quot;, a generic term for &quot;software
development kit.&quot; For example, the <a href="http://java.sun.com/javaee/sdk/" target="_blank">Java
EE SDK</a>.<sup><a href="#footnote2Intro" id="2Intro" style="text-decoration:none">[2]</a></sup></p>
<p>You can see a visual representation of the Java platform by viewing the
conceptual diagram of component technologies provided in the
<a href="http://download.oracle.com/javase/6/docs/index.html" target="_blank">JDK Documentation</a>.
As shown below, the diagram is interactive, enabling you click on components
to learn more about individual technologies.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/intro/jdk-diagram.png"
class="margin-around" alt="Diagram of JDK 6"
title="The Java platform represented by the JDK"></p>
<p>As the diagram indicates, the JDK includes the Java Runtime Environment (JRE).
You require the JRE to run software, and you require the JDK to develop
software. Both can be acquired from
<a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank">Java SE Downloads</a>.</p>
<p>The Java platform comes in several <em>editions</em>, such as
<a href="http://java.sun.com/javase/" target="_blank">Java SE</a> (Standard Edition),
<a href="http://java.sun.com/javame/index.jsp" target="_blank">Java ME</a> (Micro Edition),
and <a href="http://java.sun.com/javaee/" target="_blank">Java EE</a> (Enterprise Edition).</p>
<h3>Java EE</h3>
<p>The Java Platform, Enterprise Edition (Java EE) builds upon the Java SE platform
and provides a set of technologies for developing and running portable, robust,
scalable, reliable and secure server-side applications.</p>
<p>EE technologies are loosely divided into two categories:</p>
<ul>
<li><a href="http://java.sun.com/javaee/technologies/webapps/" target="_blank">Web application technologies</a></li>
<li><a href="http://java.sun.com/javaee/technologies/entapps/" target="_blank">Enterprise application technologies</a></li>
</ul>
<p>Depending on your needs, you may want to use certain technologies from either
category. For example, this tutorial makes use of
<a href="http://java.sun.com/products/servlet/index.jsp" target="_blank">Servlet</a>,
<a href="http://java.sun.com/products/jsp/" target="_blank">JSP/EL</a>, and
<a href="http://java.sun.com/products/jsp/jstl/" target="_blank">JSTL</a> &quot;web&quot;
technologies, as well as
<a href="http://java.sun.com/products/ejb/" target="_blank">EJB</a> and
<a href="http://java.sun.com/javaee/technologies/persistence.jsp" target="_blank">JPA</a>
&quot;enterprise&quot; technologies.</p>
<p>Java EE currently dominates the market, especially in the financial sector. The following
diagram is taken from an
<!-- <a href="http://www.sun.com/aboutsun/media/analyst/european_fsa.pdf"> -->
<a href="http://docs.google.com/viewer?a=v&q=cache:2NNYG8LtVFIJ:www.sun.com/aboutsun/media/analyst/european_fsa.pdf+european_fsa.pdf&hl=en&pid=bl&srcid=ADGEESi3vpbc32J7GzXFiqk__DvMp7_3deYe9td-HP3_QEXh77yBABi35uvL1z7ytj6o17io7_YFPnRFmhju5PQgrpgjVxt-2qXQSUh8xGUbeNP0k00dDsiq1Tl0DWJLOEH3SNubhit5&sig=AHIEtbTKL5tks3AlgEt57h4Aku_H55OXag" target="_blank">
independent survey for European markets</a> performed in 2007.</p>
<div class="indent">
<img src="../../../../images_www/articles/73/javaee/ecommerce/intro/java-ee-vs-net.png"
class="margin-around b-all" alt="Survey Java EE vs .Net"
title="Java EE dominates the financial market">
</div>
<p class="tips">For a recent, informal comparison of Java EE to .NET, see the blog post
<a href="http://www.adam-bien.com/roller/abien/entry/java_ee_or_net_an" target="_blank">Java
EE or .NET - An Almost Unbiased Opinion</a> by a well-known member of the Java EE community.</p>
<h3>What's the Difference Between...?</h3>
<p>There are many abbreviations and acronyms to parse. If you're new to all of this
and find the above explanation somewhat confusing, the following resources can
help explain what the differences are between some of the commonly used terminology.</p>
<ul>
<li><a href="http://www.java.com/en/download/faq/jre_jdk.xml" target="_blank">What's the Difference between the JRE and the JDK?</a></li>
<li><a href="http://www.java.com/en/download/faq/java_diff.xml" target="_blank">What's the Difference between the JRE and the Java SE platform?</a></li>
<li><a href="http://www.oracle.com/technetwork/java/javaee/javaee-faq-jsp-135209.html#diff" target="_blank">What's the Difference between Java EE and J2EE?</a></li>
<li><a href="http://java.sun.com/new2java/programming/learn/unravelingjava.html" target="_blank">Unraveling Java Terminology</a></li>
</ul>
</div>
<br>
<h2 id="jcp">What is the Java Community Process?</h2>
<p>The <a href="http://jcp.org/" target="_blank">Java Community Process</a> (JCP) is a
program that manages the development of standard technical specifications for Java
technology. The JCP catalogs Java Specification Requests (JSRs), which are formal
proposals that document the technologies which are to be added to the Java platform.
JSRs are run by an <em>Expert Group</em>, which typically comprises representatives
of companies that are stakeholders in the industry. The JCP enables Java technology
to grow and adapt according to the needs and trends of the community.</p>
<p>The JSRs of technologies used and referred to in this tutorial include the following:</p>
<ul>
<li><a href="http://jcp.org/en/jsr/summary?id=52" target="_blank">JSR 52: A Standard Tag Library for JavaServer Pages</a></li>
<li><a href="http://jcp.org/en/jsr/summary?id=245" target="_blank">JSR 245: JavaServer Pages 2.1</a></li>
<li><a href="http://jcp.org/en/jsr/summary?id=315" target="_blank">JSR 315: Java Servlet 3.0</a></li>
<li><a href="http://jcp.org/en/jsr/summary?id=316" target="_blank">JSR 316: Java Platform, Enterprise Edition 6</a></li>
<li><a href="http://jcp.org/en/jsr/summary?id=317" target="_blank">JSR 317: Java Persistence 2.0</a></li>
<li><a href="http://jcp.org/en/jsr/summary?id=318" target="_blank">JSR 318: Enterprise JavaBeans 3.1</a></li>
</ul>
<p>You can use the <a href="http://jcp.org/" target="_blank">JCP website</a> to search for individual JSRs.
You can also view all current EE technologies (Java EE 6) at:</p>
<ul>
<li><a href="http://java.sun.com/javaee/technologies/index.jsp" target="_blank">http://java.sun.com/javaee/technologies/index.jsp</a></li>
</ul>
<p>Java EE 5 technologies are listed at:</p>
<ul>
<li><a href="http://java.sun.com/javaee/technologies/javaee5.jsp" target="_blank">http://java.sun.com/javaee/technologies/javaee5.jsp</a></li>
</ul>
<p>A JSR's final release provides a <em>reference implementation</em>, which is a free
implementation of the technology. In this tutorial, you utilize these implementations
to develop the sample e-commerce application. For example, the GlassFish v3 application
server, which is included in the standard Java download bundle for
<a href="https://netbeans.org/downloads/6.8/index.html" target="_blank">NetBeans
6.8</a>, is the reference implementation of the Java EE 6 platform specification
(<a href="http://jcp.org/en/jsr/summary?id=316" target="_blank">JSR 316</a>). As a
reference implementation for the Java EE platform, it includes reference implementations
for the technologies included in the platform, such as Servlet, EJB and JPA technologies.</p>
<br>
<h2 id="ide">Why use an IDE?</h2>
<p>Firstly, the term <em>IDE</em> stands for <em>integrated development environment</em>.
The purpose of an IDE has traditionally been to maximize a developer's productivity
by providing tools and support such as:</p>
<ul class="toc">
<li>a source code editor</li>
<li>a compiler and build automation tools</li>
<li>a window system for viewing projects and project artifacts</li>
<li>integration with other commonly-used services</li>
<li>debugging support</li>
<li>profiling support</li>
</ul>
<p>Consider what would be necessary if you wanted to create a Java-based web application
manually. After installing the <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank">Java
Development Kit (JDK)</a>, you would need to set up your development environment by
performing the following steps.<sup><a href="#footnote3Intro" id="3Intro" style="text-decoration:none">[3]</a></sup></p>
<ol>
<li>Set your <code>PATH</code> environment variable to point to the JDK installation.</li>
<li>Download and configure a server that implements the technologies you plan to use.</li>
<li>Create a development directory where you plan to create and work on the web application(s).
Furthermore, you are responsible for setting up the application directory structure so
that it can be understood by the server. (For example, see
<a href="http://java.sun.com/blueprints/code/projectconventions.html#99632" target="_blank">Java
BluePrints: Strategy for Web Applications</a> for a recommended structure.)</li>
<li>Set your <code>CLASSPATH</code> environment variable to include the development
directory, as well as any required JAR files.</li>
<li>Establish a deployment method, i.e., a way to copy resources from your development
directory to the server's deployment area.</li>
<li>Bookmark or install relevant API documentation.</li>
</ol>
<p>For educative purposes, it is worthwhile to create and run a Java web project manually
so that you are aware the necessary steps involved. But eventually, you'll want to
consider using tools that reduce or eliminate the need to perform tedious or repetitious
tasks, thereby enabling you to focus on developing code that solves specific business
needs. An IDE streamlines the process outlined above. As demonstrated in Unit 3,
<a href="#setup-dev-environ">Setting up the Development Environment</a>, you'll
install NetBeans IDE with the GlassFish application server, and be able to set up
a web application project with a conventional directory structure using a simple
3-step wizard. Furthermore, the IDE provides provides built-in API documentation which
you can either call up as you code in the editor, or maintain open in an external
window.</p>
<p>An IDE also typically handles project compilation and deployment in a way that is
transparent to you as a developer. For example, the web project that you create in
NetBeans includes an Ant build script that is used to compile, clean, package and
deploy the project. This means that you can run your project from the IDE, and it
will automatically be compiled and deployed, then open in your default browser.
Taking this a step further, many IDEs support a Deploy on on Save feature. In other
words, whenever you save changes to your project, the deployed version on your
server is automatically updated. You can simply switch to the browser and refresh
the page to view changes.</p>
<p>IDEs also provide templates for various file types, and often enable you to add them
to your project by suggesting common locations and including default configuration
information where necessary.</p>
<p>Aside from the &quot;basic support&quot; described above, IDEs typically provide
interfaces to external tools and services (e.g., application and database servers,
web services, debugging and profiling facilities, and collaboration tools) which
are indispensable to your work if Java development is your profession.</p>
<p>Finally, IDEs usually provide enhanced editor support. The editor is where you likely
spend most of your time working, and IDE editors typically include syntax highlighting,
refactoring capabilites, keyboard shortcuts, code completion, hints and error messages,
all aiming to help you work more efficiently and intelligently.</p>
<br>
<h2 id="netBeans">Why use NetBeans?</h2>
<p>The NetBeans IDE is a free, open-source integrated development environment written
entirely in Java. It offers a range of tools for create professional desktop,
enterprise, web, and mobile applications with the Java language, C/C++,
and even scripting languages such as PHP, JavaScript, Groovy, and Ruby.</p>
<p>People are saying great things about NetBeans. For a list of testimonials, see
<a href="../../../../features/ide/testimonials.html" target="_blank">NetBeans IDE
Testimonials</a>. Many developers are migrating their applications to NetBeans
from other IDEs. For reasons why, read <a href="../../../../switch/realstories.html" target="_blank">Real
Stories From People Switching to NetBeans IDE</a>.</p>
<p>The IDE provides many <a href="../../../../features/web/index.html" target="_blank">features
for web development</a>, and several advantages over other IDEs. Here are several
noteworthy points:</p>
<ul>
<li><strong>Works Out of the Box:</strong> Simply download, install, and run the
IDE. With its small download size, installation is a breeze. The IDE runs on
many platforms including Windows, Linux, Mac OS X and Solaris. All IDE tools
and features are fully integrated - no need to hunt for plug-ins - and they
work together when you launch the IDE.</li>
<li><strong>Free and Open Source:</strong> When you use the NetBeans IDE, you join
a vibrant, <a href="../../../../community/index.html" target="_blank">open source
community</a> with thousands of users ready to help and contribute. There are
discussions on the <a href="../../../../community/lists/index.html" target="_blank">NetBeans
project mailing lists</a>, blogs on <a href="http://www.planetnetbeans.org/" target="_blank">Planet
NetBeans</a>, and helpful FAQs and tutorials on the <a href="http://wiki.netbeans.org/" target="_blank">community
wiki</a>.</li>
<li><strong>Profiling and Debugging Tools:</strong> With NetBeans IDE
<a href="../../../../features/java/profiler.html">profiler</a>, you get real time
insight into memory usage and potential performance bottlenecks. Furthermore, you can
instrument specific parts of code to avoid performance degradation during profiling.
The <a href="http://profiler.netbeans.org/docs/help/6.0/heapwalker.html" target="_blank">HeapWalker</a>
tool helps you evaluate Java heap contents and find memory leaks.</li>
<li><strong>Customizable Projects:</strong> Through the NetBeans IDE build process, which
relies on industry standards such as <a href="http://ant.apache.org/" target="_blank">Apache
Ant</a>, <a href="http://www.gnu.org/software/make/" target="_blank">make</a>,
<a href="http://maven.apache.org/" target="_blank">Maven</a>, and
<a href="http://rake.rubyforge.org/" target="_blank">rake</a> - rather than a
proprietary build process - you can easily customize projects and add functionality.
You can build, run, and deploy projects to servers outside of the IDE.</li>
<li><strong>Collaboration Tools:</strong> The IDE provides built-in support for version
control systems such as CVS, Subversion, and Mercurial.</li>
<li><strong>Extensive Documentation:</strong> There's a wealth of tips and instructions
contained in the IDE's built-in help set. Simply press F1 (fn-F1 on Mac) on a component
in the IDE to invoke the help set. Also, the IDE's <a href="../../../index.html" target="_blank">official
knowledge base</a> provides hundreds of online tutorials, articles and
<a href="../../intro-screencasts.html" target="_blank">screencasts</a> that are
continuously being updated.</li>
</ul>
<p>For a more extensive list of reasons why you should consider choosing NetBeans, see
<a href="../../../../switch/why.html" target="_blank">NetBeans IDE Connects Developers</a>.</p>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans E-commerce Tutorial - Introduction">Send
Us Your Feedback</a></div>
<br style="clear:both;">
<h2 id="seeAlsoIntro">See Also</h2>
<div class="indent">
<h3>Online Resources</h3>
<ul>
<li><a href="http://java.sun.com/docs/books/tutorial/" target="_blank">The Java Tutorials</a></li>
<li><a href="http://www.oracle.com/technetwork/java/javaee/javaee-faq-jsp-135209.html" target="_blank">Java EE FAQ</a></li>
<li><a href="http://java.sun.com/javaee/reference/apis/" target="_blank">Java EE APIs & Docs</a></li>
<li><a href="http://java.sun.com/new2java/programming/learn/unravelingjava.html" target="_blank">Unraveling Java Terminology</a></li>
<li><a href="http://www.java.com/en/javahistory/index.jsp" target="_blank">The History of Java Technology</a></li>
<li><a href="http://java.sun.com/new2java/gettingstarted.jsp" target="_blank">New to Java Programming Center</a></li>
</ul>
<h3>Books</h3>
<ul>
<li><a href="http://www.apress.com/book/view/1590598954" target="_blank">Pro NetBeans
IDE 6 Rich Client Platform Edition</a></li>
<li><a href="http://www.informit.com/store/product.aspx?isbn=0130092290" target="_blank">Core
Servlets and JavaServer Pages, Volume 1: Core Technologies, 2nd Edition</a></li>
<li><a href="http://www.informit.com/store/product.aspx?isbn=0131482602" target="_blank">Core
Servlets and JavaServer Pages, Volume 2: Advanced Technologies, 2nd Edition</a></li>
<li><a href="http://java.sun.com/docs/books/faq/" target="_blank">The Java FAQ</a></li>
</ul>
</div>
<br>
<h2 id="referencesIntro">References</h2>
<ol>
<li id="footnote1Intro"><a href="#1Intro" style="text-decoration:none">^</a> The white paper,
<a href="http://java.sun.com/docs/white/langenv/Intro.doc2.html" target="_blank">The Java
Language Environment</a>, outlines the 5 design principles.</li>
<li id="footnote2Intro"><a href="#2Intro" style="text-decoration:none">^</a> Current version names and
numbers are defined in
<a href="http://download.oracle.com/javase/6/webnotes/version-6.html" target="_blank">Java SE
6, Platform Name and Version Numbers</a>.</li>
<li id="footnote3Intro"><a href="#3Intro" style="text-decoration:none">^</a> These steps are loosely
based on those outlined in Chapter 2: Server Setup and Configuration, from
<a href="http://pdf.coreservlets.com/" target="_blank">Core Servlets and JavaServer Pages</a>,
by Marty Hall and Larry Brown. This book is freely available in PDF format from:
<a href="http://pdf.coreservlets.com/" target="_blank">http://pdf.coreservlets.com/</a></li>
</ol>
<br><br><br><br>
<h1 id="design">The NetBeans E-commerce Tutorial - Designing the Application</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Tutorial Contents</h4>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><strong>Designing the Application</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#scenario">The Scenario</a></li>
<li><a href="#requirements">Gathering Customer Requirements</a></li>
<li><a href="#mockups">Preparing Mockups</a></li>
<li><a href="#architecture">Determining the Architecture</a></li>
<li><a href="#planning">Planning the Project</a></li>
<li><a href="#seeAlsoDesign">See Also</a></li>
</ul></li>
<li><a href="#setup-dev-environ">Setting up the Development Environment</a></li>
<li><a href="#data-model">Designing the Data Model</a></li>
<li><a href="#page-views-controller">Preparing the Page Views and Controller Servlet</a></li>
<li><a href="#connect-db">Connecting the Application to the Database</a></li>
<li><a href="#entity-session">Adding Entity Classes and Session Beans</a></li>
<li><a href="#manage-sessions">Managing Sessions</a></li>
<li><a href="#transaction">Integrating Transactional Business Logic</a></li>
<li><a href="#language">Adding Language Support</a></li>
<li><a href="#security">Securing the Application</a></li>
<li><a href="#test-profile">Testing and Profiling</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ol>
</div>
</div>
<p><img src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" class="stamp"
alt="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"
title="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"></p>
<p>The application that you design in this tutorial is based on a real-world scenario. After
being introduced to the tutorial scenario, you consolidate a high-level list of customer
requirements. You then prepare a diagram of the application's business process flow,
and a series of <em>mockups</em> which help both you and your customer get a clearer
picture of how the final application will look to an end-user. Finally, you break down
the customer requirements into a set of implementation tasks, and structure your application
so that the responsibilities and interactions among functional components are clearly
defined.</p>
<p>This tutorial unit discusses the MVC (Model-View-Controller) design pattern. After
investigating the benefits that this pattern offers, you set about mapping JSP, Servlet,
and other technologies to the MVC architecture, and draft a diagram that illustrates
the components of the application in terms of MVC.</p>
<p>This unit makes various references to <a href="http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/" target="_blank">Designing
Enterprise Applications with the J2EE Platform, Second Edition</a>. This book contains
guidelines promoted by <a href="http://java.sun.com/reference/blueprints/index.jsp" target="_blank">Java
BluePrints</a>.</p>
<p>Although this tutorial unit does not require use of the NetBeans IDE, it is essential
because it lays the groundwork for tasks that will be covered in the following units.</p>
<p>You can view a live demo of the application that you build in this tutorial:
<a href="http://services.netbeans.org/AffableBean/" target="_blank">NetBeans E-commerce
Tutorial Demo Application</a>.</p>
<br style="clear:left">
<br>
<h2 id="scenario">The Scenario</h2>
<p>This tutorial is based on the following scenario. Although this is a fictitious
scenario, it demonstrates how the software you are about to develop can be applied
to real-world business needs. It also serves as a platform from which you can derive
customer requirements. Customer requirements should be established as clearly as possible
before any design or implementation begins.</p>
<div class="indent">
<div class="feedback-box margin-around float-left" style="width:700px">
<h4>The Scenario</h4>
<p>A small grocery store, the Affable Bean, collaborates with several local farms to
supply a community with organic produce and foods. Due to a long-standing customer
base and increasing affluence to the area, the store has decided to investigate
the possibility of providing an online delivery service to customers. A recent
survey has indicated that 90% of its regular clientele has continuous Internet
access, and 65% percent would be interested in using this service.</p>
<p>The grocery store staff have asked you, the Java web developer, to create a website
that will enable their customers to shop online. They have also asked that you
create an administration console alongside the website, which will allow staff
members to keep track of orders.</p>
<p>The store's location is in Prague, in the Czech Republic. Because regular clientele
are both English and Czech-speaking, staff have requested that the website support
both languages.</p>
<p>The grocery store has already purchased a domain and web hosting plan that provides
a Java EE 6-compliant server and MySQL database server. Staff have indicated that
one technically-oriented member is able to deploy the application to the production
server once it is ready.</p>
</div>
</div>
<br style="clear:both">
<br>
<h2 id="requirements">Gathering Customer Requirements</h2>
<p>The initial phase of any project involves gathering information before making any design
or implementation decisions. In its most common form, this involves direct and frequent
communication with a customer. Based on the provided scenario, the Affable Bean staff
have communicated to you that the application you are to create should fulfill the
following requirements:</p>
<ol>
<li>An online representation of the products that are sold in the physical store.
There are four categories (dairy, meats, bakery, fruit & veg), and four products
for each category, which online shoppers can browse. Details are provided for each
product (i.e., name, image, description, price).</li>
<li>Shopping cart functionality, which includes the ability to:
<ul style="margin: 5px 0 0 -2em">
<li>add items to a virtual shopping cart.</li>
<li>remove items from the shopping cart.</li>
<li>update item quantities in the shopping cart.</li>
<li>view a summary of all items and quantities in the shopping cart.</li>
<li>place an order and make payment through a secure checkout process.</li>
</ul></li>
<li>An administration console, enabling staff to view customer orders.</li>
<li>Security, in the form of protecting sensitive customer data while it is
transferred over the Internet, and preventing unauthorized access to the
administration console.</li>
<li>Language support for both English and Czech. (Website only)</li>
</ol>
<p>The company staff are able to provide you with product and category images,
descriptions and price details, as well as any website graphics that are to
be used. The staff are also able to provide all text and language translations
for the website.</p>
<p class="tips">There are many practices and methods devoted to software
development management. <a href="http://en.wikipedia.org/wiki/Agile_software_development" target="_blank">Agile
software development</a> is one methodology that encourages frequent customer
inspection, and places importance on adaptation during the development cycle.
Although this is outside the scope of this tutorial, each tutorial unit concludes
with a functional piece of software that could be presented to a customer for
further communication and feedback.</p>
<br>
<h2 id="mockups">Preparing Mockups</h2>
<p>After gathering customer requirements, you work with the Affable Bean staff
to gain a clearer picture of how they expect the website to look and behave.
You create a use-case that describes how the application will be used and
encapsulates its behavior:</p>
<div class="indent">
<div class="feedback-box margin-around float-left" style="width:700px">
<h3 id="useCase">Use-Case</h3>
<p>Customer visits the welcome page and selects a product category. Customer browses
products within the selected category page, then adds a product to his or her
shopping cart. Customer continues shopping and selects a different category.
Customer adds several products from this category to shopping cart. Customer
selects 'view cart' option and updates quantities for cart products in the cart
page. Customer verifies shopping cart contents and proceeds to checkout. In the
checkout page, customer views the cost of the order and other information, fills
in personal data, then submits his or her details. The order is processed and
customer is taken to a confirmation page. The confirmation page provides a unique
reference number for tracking the customer order, as well as a summary of the order.</p>
</div>
</div>
<br style="clear:both">
<br>
<p>You also begin creating mockups. There are numerous ways to go about this task. For
example, you could use storyboard software, or create a set of wireframes to relay
the relationships between pages. Another common method is known as
<a href="http://en.wikipedia.org/wiki/Paper_prototyping" target="_blank">paper
prototyping</a>, where you collaborate with the customer by sketching ideas on paper.</p>
<p>In this scenario, we've produced <em>mockups</em> of the primary pages the user expects
see when navigating through the website. When we later discuss the MVC design pattern,
you'll note that these pages map to the <em>views</em> used by the application.</p>
<table>
<tr style="vertical-align:top">
<td style="width:420px; padding:10px">
<a href="../../../../images_www/articles/73/javaee/ecommerce/design/mockup-index.png"
rel="lytebox" title="Mockup of welcome page" id="index">
<img src="../../../../images_www/articles/73/javaee/ecommerce/design/mockup-index-small.png"
style="width:400px" alt="Mockup of welcome page" class="b-all margin-around"></a>
</td>
<td style="width:350px; padding:10px">
<br>
<h4>welcome page</h4>
<p>The welcome page is the website's home page, and entry point for the
application. It introduces the business and service to the user, and
enables the user to navigate to any of the four product categories.</p>
</td>
</tr>
<tr style="vertical-align:top">
<td style="width:420px; padding:10px">
<a href="../../../../images_www/articles/73/javaee/ecommerce/design/mockup-category.png"
rel="lytebox" title="Mockup of category page" id="category">
<img src="../../../../images_www/articles/73/javaee/ecommerce/design/mockup-category-small.png"
alt="Mockup of category page" class="b-all margin-around"></a>
</td>
<td style="width:350px; padding:10px">
<br>
<h4>category page</h4>
<p>The category page provides a listing of all products within the
selected category. From this page, a user is able to view all
product information, and add any of the listed products to his
or her shopping cart. A user can also navigate to any of the
provided categories.</p>
</td>
</tr>
<tr style="vertical-align:top">
<td style="width:420px; padding:10px">
<a href="../../../../images_www/articles/73/javaee/ecommerce/design/mockup-cart.png"
rel="lytebox" title="Mockup of cart page" id="cart">
<img src="../../../../images_www/articles/73/javaee/ecommerce/design/mockup-cart-small.png"
alt="Mockup of cart page" class="b-all margin-around"></a>
</td>
<td style="width:350px; padding:10px">
<br>
<h4>cart page</h4>
<p>The cart page lists all items held in the user's shopping cart.
It displays product details for each item, and tallies the subtotal
for the items in the cart. From this page, a user can:</p>
<ul>
<li>Clear all items in his or her cart
<br>
(Clicking 'clear cart' causes the 'proceed to checkout' buttons
and shopping cart table to disappear.)</li>
<li>Update the quantity for any listed item
<br>
(The price and quantity are updated; the subtotal is recalculated.
If user sets quantity to '0', the product table row is removed.)</li>
<li>Return to the previous category by clicking 'continue shopping'</li>
<li>Proceed to checkout</li>
</ul>
</td>
</tr>
<tr style="vertical-align:top">
<td style="width:420px; padding:10px">
<a href="../../../../images_www/articles/73/javaee/ecommerce/design/mockup-checkout.png"
rel="lytebox" title="Mockup of checkout page" id="checkout">
<img src="../../../../images_www/articles/73/javaee/ecommerce/design/mockup-checkout-small.png"
alt="Mockup of checkout page" class="b-all margin-around"></a>
</td>
<td style="width:350px; padding:10px">
<br>
<h4>checkout page</h4>
<p>The checkout page collects information from the customer using a
form. This page also displays purchase conditions, and summarizes
the order by providing calculations for the total cost.</p>
<p>The user is able to send personal details over a secure channel.</p>
</td>
</tr>
<tr style="vertical-align:top">
<td style="width:420px; padding:10px">
<a href="../../../../images_www/articles/73/javaee/ecommerce/design/mockup-confirmation.png"
rel="lytebox" title="Mockup of confirmation page" id="confirmation">
<img src="../../../../images_www/articles/73/javaee/ecommerce/design/mockup-confirmation-small.png"
alt="Mockup of confirmation page" class="b-all margin-around"></a>
</td>
<td style="width:350px; padding:10px">
<br>
<h4>confirmation page</h4>
<p>The confirmation page returns a message to the customer confirming
that the order was successfully recorded. An order reference number
is provided to the customer, as well as a summary listing order
details.</p>
<p>Order summary and customer personal details are returned over a secure channel.</p>
</td>
</tr>
</table>
<p>Also, you agree with staff on the following rules, which apply to multiple pages:</p>
<ul>
<li>The user is able to proceed to checkout from any page, provided that:
<ul style="margin: 5px 0 0 -2em">
<li>The shopping cart is not empty</li>
<li>The user is not already on the checkout page</li>
<li>The user has not already checked out (i.e., is on the confirmation page)</li>
</ul></li>
<li>From all pages, the user is able to:
<ul style="margin: 5px 0 0 -2em">
<li>View the status of his or her shopping cart (if it is not empty)</li>
<li>Return to the welcome page by clicking the logo image</li>
</ul></li>
<li>The user is able to select the language (English or Czech) to view the page
in for all pages except the confirmation page.</li>
</ul>
<p class="notes"><strong>Note:</strong> Although not presented here, you would equally
need to work with the client to produce use-cases and mockups, and establish rules
for the administration console. The NetBeans E-commerce Tutorial focuses on developing
the store front (i.e., the website). However, Unit 11, <a href="#security">Securing the
Application</a> demonstrates how to create a login mechanism to access the administration
console. Also, you can examine the provided implementation of the administration console by
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_complete.zip">downloading
the completed application</a>.</p>
<div class="indent">
<h3 id="business">The Business Process Flow</h3>
<p>To help consolidate the relationships between the proposed mockups and better
illustrate the functionality that each page should provide, you prepare a
diagram that demonstrates the process flow of the application.</p>
<p>The diagram displays the visual and functional components of each page, and
highlights the primary actions available to the user in order to navigate
through the site to complete a purchase.</p>
<div class="indent">
<img src="../../../../images_www/articles/73/javaee/ecommerce/design/process-flow.png"
class="margin-around" alt="Process-flow diagram of the AffableBean application"
title="The process flow of the AffableBean application"
id="processFlowDiagram">
</div>
</div>
<br>
<h2 id="architecture">Determining the Architecture</h2>
<p>Before you start coding, let's examine the ways in which you can architect
the project. Specifically, you need to outline the responsibilities among
functional components, and determine how they will interact with each other.</p>
<p>When you work with JSP technologies, you can code all of your business logic
into JSP pages using scriptlets. Scriptlets are snippets of Java code enclosed
in <code>&lt;% %&gt;</code> tags. As you may already be aware, JSP pages are
compiled into servlets before they are run, so Java code is perfectly valid in
JSP pages. However, there are several reasons why this practice should be avoided,
especially when working in large projects. Some reasons are outlined in
<a href="http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/" target="_blank">Designing
Enterprise Applications with the J2EE Platform, Second Edition</a> as
follows:<sup><a href="#footnote1Design" id="1Design" style="text-decoration:none">[1]</a></sup></p>
<ul>
<li><strong>Scriptlet code is not reusable: </strong>Scriptlet code appears
in exactly one place: the JSP page that defines it. If the same logic is
needed elsewhere, it must be either included (decreasing readability) or
copied and pasted into the new context.</li>
<li><strong>Scriptlets mix logic with presentation: </strong>Scriptlets are
islands of program code in a sea of presentation code. Changing either
requires some understanding of what the other is doing to avoid breaking
the relationship between the two. Scriptlets can easily confuse the intent
of a JSP page by expressing program logic within the presentation.</li>
<li><strong>Scriptlets break developer role separation:</strong> Because scriptlets
mingle programming and Web content, Web page designers need to know either
how to program or which parts of their pages to avoid modifying.</li>
<li><strong>Scriptlets make JSP pages difficult to read and to maintain: </strong>
JSP pages with scriptlets mix structured tags with JSP page delimiters and
Java language code.</li>
<li><strong>Scriptlet code is difficult to test: </strong>Unit testing of scriptlet
code is virtually impossible. Because scriptlets are embedded in JSP pages,
the only way to execute them is to execute the page and test the
results.</li>
</ul>
<p>There are various design patterns already in existence which provide considerable
benefits when applied. One such pattern is the MVC (Model-View-Controller)
paradigm, which divides your application into three interoperable
components:<sup><a href="#footnote2Design" id="2Design" style="text-decoration:none">[2]</a></sup></p>
<ul>
<li><strong>Model:</strong> Represents the business data and any business logic
that govern access to and modification of the data. The model notifies views
when it changes and lets the view query the model about its state. It also
lets the controller access application functionality encapsulated by the model.</li>
<li><strong>View:</strong> The view renders the contents of a model. It gets data
from the model and specifies how that data should be presented. It updates
data presentation when the model changes. A view also forwards user input to
a controller.</li>
<li><strong>Controller:</strong> The controller defines application behavior. It
dispatches user requests and selects views for presentation. It interprets user
inputs and maps them into actions to be performed by the model. In a web
application, user inputs are HTTP GET and POST requests. A controller selects
the next view to display based on the user interactions and the outcome of the
model operations.</li>
</ul>
<div class="indent">
<img src="../../../../images_www/articles/73/javaee/ecommerce/design/mvc-model.png"
class="margin-around" alt="Diagram of the MVC pattern"
title="The Model View Controller pattern"
id="mvcModel">
</div>
<br>
<p>Adhering to the MVC design pattern provides you with numerous benefits:</p>
<ul>
<li><strong>Separation of design concerns:</strong> Because of the decoupling
of presentation, control, and data persistence and behavior, the application
becomes more flexible; modifications to one component have minimal impact on
other components. You can, for example, create new views without needing to
rewrite the model.</li>
<li><strong>More easily maintainable and extensible:</strong> Good structure can
reduce code complexity. As such, code duplication is minimized.</li>
<li><strong>Promotes division of labor:</strong> Developers with different skill
sets are able to focus on their core skills and collaborate through clearly
defined interfaces.</li>
</ul>
<p class="notes"><strong>Note:</strong> When JSP technology was first introduced in
1999, the early specifications included a description of two model architectures:
Model 1 and Model 2. Model 1 involves implementing business logic directly within
JSP pages, whereas Model 2 applies the MVC pattern. For more information on Model
1 and Model 2 architectures, see
<a href="http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/web-tier/web-tier5.html#1078527" target="_blank">Designing
Enterprise Applications with the J2EE Platform, section 4.4.1: Structuring the Web
Tier</a>.</p>
<p>You can apply the MVC pattern to the application that you develop for the Affable
Bean company. You can use a servlet as a <em>controller</em> to handle incoming
requests. The pages from the <a href="#processFlowDiagram">business process flow
diagram</a> can be mapped to <em>views</em>. Finally, the business data, which will
be maintained in a database, can be accessed and modified in the application using
<a href="http://java.sun.com/products/ejb/" target="_blank">EJB</a> session beans with
<a href="http://java.sun.com/javaee/technologies/persistence.jsp" target="_blank">JPA</a>
entity classes. These components represent the <em>model</em>.</p>
<div class="indent" id="mvcDiagram">
<img src="../../../../images_www/articles/73/javaee/ecommerce/design/mvc-diagram.png"
class="margin-around" alt="MVC diagram of the AffableBean application"
title="MVC diagram of the AffableBean application">
</div>
<br>
<br>
<h2 id="planning">Planning the Project</h2>
<p>In order to plan the project, you need to extrapolate functional tasks from the customer
requirements. The tasks that we produce will structure the implementation plan for the
project, and form the outline for tutorial units that follow. In practice, the more capable
you are of identifying tasks and the work they entail, the better you'll be able to stick
to the schedule that you and your customer agree upon. Therefore, begin with a high-level
task list, then try to drill down from these tasks dividing each task into multiple sub-tasks,
and possibly dividing sub-tasks further until each list item represents a single unit of work.</p>
<ul id="collapsableList">
<li>Set up the development environment
<ul>
<li>Register the development server in the IDE</li>
<li>Create a web project in the IDE</li>
<li>Run the web project from the IDE (test compilation, deployment, run
capabilities, and ensure interoperability between IDE, server and browser)</li>
<li>Register the database server in the IDE</li>
<li>Establish a connection to the database server from the IDE</li>
<li>Create a database instance on the database server</li>
</ul>
</li>
<li>Prepare the data model for the application
<ul>
<li>Create an entity-relationship diagram (use a visual database design tool)
<ul>
<li>Identify objects</li>
<li>Create a schema</li>
<li>Create entities</li>
<li>Add entity properties</li>
<li>Identify relationships between entities
<ul>
<li>One-to-Many relationships</li>
<li>Many-to-Many relationships</li>
</ul>
</li>
</ul></li>
<li>Forward-engineer the entity-relationship diagram into an SQL script</li>
<li>Run the script on the database server to generate the schema</li>
</ul>
</li>
<li>Create front-end project files
<ul>
<li>Stylesheet</li>
<li>Placeholders for JSP pages (requires implementing HTML and CSS
content to get pages to display like mockups)
<ul>
<li>welcome page</li>
<li>category page</li>
<li>cart page</li>
<li>checkout page</li>
<li>confirmation page</li>
</ul>
</li>
</ul></li>
<li>Organize the application front-end
<ul>
<li>Place JSP pages in the application's <code>WEB-INF</code> directory</li>
<li>Create page header and footer</li>
<li>Remove instances of code duplication (header and footer code from JSP pages)</li>
<li>Register header and footer includes with the web deployment descriptor</li>
</ul></li>
<li>Create a controller servlet
<ul>
<li>Create mappings for views in deployment descriptor</li>
<li>Create skeleton code in servlet to handle client requests</li>
</ul></li>
<li>Connect the application to the database
<ul>
<li>Add sample data to the database</li>
<li>Create data source and connection pool on server</li>
<li>Test data source (ping connection pool)</li>
<li>Ensure that views can access data from the database
<ul>
<li>Add database driver JAR to server</li>
<li>Create a resource reference to the data source in the application</li>
<li>Query the database from a JSP page</li>
</ul></li>
<li>Set any necessary application-wide parameters</li>
<li>Code database-access and conditional logic in views that do not require user session (welcome, category)</li>
</ul></li>
<li>Develop the business logic
<ul>
<li>Set up the model
<ul>
<li>Create JPA entity classes from database tables</li>
<li>Create and configure persistence unit</li>
<li>Create EJB stateless bean facades for entity classes</li>
</ul></li>
<li>Integrate EJB model with views
<ul>
<li>Integrate EJB facades in controller servlet</li>
<li>Modify views to use data from scoped variables (instead of any JSTL <code>&lt;sql&gt;</code> queries)</li>
</ul></li>
<li>Create shopping cart functionality
<ul>
<li>Create Java classes to hold temporary data (<code>ShoppingCart</code>, <code>ShoppingCartItem</code>)</li>
<li>Integrate code for <code>HttpSession</code> object into controller servlet</li>
<li>Add session-related actions to controller servlet</li>
<li>Create shopping cart widget in page header</li>
<li>Integrate session-related data into views (cart, checkout)</li>
<li>Apply JSTL <code>&lt;c:url&gt;</code> tags to enable url-rewriting in the event that user has disabled cookies</li>
<li>Configure session time-out in web deployment descriptor</li>
<li>Add logic to controller servlet handle requests in the event of session time-out</li>
</ul></li>
<li>Integrate transactional logic
<ul>
<li>Create code to extract and validate user data from checkout form</li>
<li>Create an EJB stateless session bean to handle inserting orders and customers into database</li>
<li>Implement logic to query the database on newly-created orders</li>
<li>Implement order and customer details display in confirmation page</li>
</ul>
</li>
</ul></li>
<li>Add language support
<ul>
<li>Create a properties file containing messages for all text in
the application
<ul>
<li>default language (English)</li>
<li>English</li>
<li>Czech</li>
</ul></li>
<li>Register a localization context parameter in deployment descriptor</li>
<li>Add logic to view that sets page language based on language value
saved in user's session</li>
<li>Apply <code>&lt;fmt:message&gt;</code> tags to all text contained in view</li>
<li>Factor out English description from database (<em>optional</em>), use resource bundles instead</li>
</ul></li>
<li>Create administration console
<ul>
<li>Create new artifacts
<ul>
<li>Views
<ul>
<li>login</li>
<li>welcome</li>
<li>error</li>
</ul></li>
<li>Controller servlet</li>
</ul></li>
<li>Create login functionality
<ul>
<li>Create interface</li>
<li>Add actions to controller servlet</li>
<li>Configure login functionality in deployment descriptor</li>
</ul></li>
<li>Implement admin functionality (in welcome page)
<ul>
<li>For viewing order details</li>
<li>For viewing customer details</li>
</ul>
</li>
</ul></li>
<li>Secure the application
<ul>
<li>Configure SSL connection for checkout, confirmation views, and administration console
<ul>
<li>Enable SSL on server</li>
<li>Register security settings in deployment descriptor</li>
</ul></li>
<li>Create user roles and permissions for administration console
<ul>
<li>Create security roles on server</li>
<li>Declare security roles, constraints in deployment descriptor</li>
</ul>
</li>
</ul>
</li>
</ul>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans E-commerce Tutorial - Designing the Application">Send
Us Your Feedback</a></div>
<br style="clear:both;">
<h2 id="seeAlsoDesign">See Also</h2>
<div class="indent">
<h3>Online Resources</h3>
<ul>
<li><a href="http://java.sun.com/reference/blueprints/index.jsp" target="_blank">Java BluePrints</a></li>
<li><a href="http://java.sun.com/blueprints/patterns/catalog.html" target="_blank">J2EE Patterns Catalog</a></li>
<li><a href="http://bpcatalog.dev.java.net/nonav/solutions.html" target="_blank">Java BluePrints Solutions Catalog</a></li>
<li><a href="http://java.sun.com/blueprints/patterns/MVC-detailed.html" target="_blank">Java BluePrints: Model-View-Controller</a></li>
<li><a href="http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/web-tier/web-tier5.html" target="_blank">Web-Tier Application Framework Design</a></li>
<li><a href="http://download.oracle.com/docs/cd/E17477_01/javaee/5/tutorial/doc/bnadr.html" target="_blank">The Java EE 5 Tutorial - Chapter 3: Getting Started with Web Applications</a></li>
</ul>
<h3>Technical Articles</h3>
<ul>
<li><a href="http://java.sun.com/developer/technicalArticles/javaserverpages/servlets_jsp/" target="_blank">Servlets and JSP Pages Best Practices</a></li>
<li><a href="http://java.sun.com/developer/technicalArticles/J2EE/despat/" target="_blank">Design Patterns for Building Flexible and Maintainable J2EE Applications</a></li>
</ul>
<h3>Books</h3>
<ul>
<li><a href="http://volume1.coreservlets.com/" target="_blank">Core Servlets and JavaServer Pages, Volume 1:
Core Technologies, 2nd Edition</a></li>
<li><a href="http://volume2.coreservlets.com/" target="_blank">Core Servlets and JavaServer Pages, Volume 2:
Advanced Technologies, 2nd Edition</a></li>
</ul>
</div>
<br>
<h2>References</h2>
<ol>
<li id="footnote1Design"><a href="#1Design" style="text-decoration:none">^</a> For a more extensive
list, see <a href="http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/web-tier/web-tier3.html#1097966" target="_blank">Designing
Enterprise Applications with the J2EE Platform, section 4.2.6.8: Using Custom Tags
to Avoid Scriptlets</a>.</li>
<li id="footnote2Design"><a href="#2Design" style="text-decoration:none">^</a> For more information
on the MVC pattern, see
<a href="http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/app-arch/app-arch2.html#1105854" target="_blank">Designing
Enterprise Applications with the J2EE Platform, section 11.1.1: Model-View-Controller
Architecture</a>.</li>
</ol>
<script type="text/javascript">
<!--
compactMenu('collapsableList', true, '&plusmn; ');
-->
</script>
<br><br><br><br>
<h1 id="setup-dev-environ">The NetBeans E-commerce Tutorial - Setting up the Development Environment</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Tutorial Contents</h4>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#design">Designing the Application</a></li>
<li><strong>Setting up the Development Environment</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#create">Creating a Web Project</a></li>
<li><a href="#run">Running the Web Project</a></li>
<li><a href="#communicate">Communicating with the Database Server</a></li>
<li><a href="#seeAlsoSetupDevEnviron">See Also</a></li>
</ul></li>
<li><a href="#data-model">Designing the Data Model</a></li>
<li><a href="#page-views-controller">Preparing the Page Views and Controller Servlet</a></li>
<li><a href="#connect-db">Connecting the Application to the Database</a></li>
<li><a href="#entity-session">Adding Entity Classes and Session Beans</a></li>
<li><a href="#manage-sessions">Managing Sessions</a></li>
<li><a href="#transaction">Integrating Transactional Business Logic</a></li>
<li><a href="#language">Adding Language Support</a></li>
<li><a href="#security">Securing the Application</a></li>
<li><a href="#test-profile">Testing and Profiling</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ol>
</div>
</div>
<p><img src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" class="stamp"
alt="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"
title="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"></p>
<p>The following steps describe how to set up your development environment. In the process,
you'll learn about some of the primary windows of the IDE and understand how the IDE
uses an <a href="http://ant.apache.org/" target="_blank">Ant</a> build script to perform
common actions on your project. By the end of this tutorial unit, you'll have created
a web application project, and confirmed that you can successfully build the project,
deploy it to your development server, and run it from the IDE.</p>
<p>You also learn how to connect the IDE to a MySQL database server, create database
instances, and connect to database instances from the IDE's Services window. In
this unit, you create a new database named <code>affablebean</code>, which you
will use throughout the tutorial.</p>
<p>You can view a live demo of the application that you build in this tutorial:
<a href="http://services.netbeans.org/AffableBean/" target="_blank">NetBeans
E-commerce Tutorial Demo Application</a>.</p>
<br style="clear:left">
<br>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html" target="_blank">NetBeans IDE</a></td>
<td class="tbltd1">Java bundle, 6.8 or 6.9</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank">Java Development Kit (JDK)</a></td>
<td class="tbltd1">version 6</td>
</tr>
<tr>
<td class="tbltd1"><a href="#glassFishSetupDevEnviron">GlassFish server</a></td>
<td class="tbltd1">v3 or Open Source Edition 3.0.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://dev.mysql.com/downloads/mysql/" target="_blank">MySQL database server</a></td>
<td class="tbltd1">version 5.1</td>
</tr>
</tbody>
</table>
<p class="notes"><strong>Notes:</strong></p>
<ul>
<li>The NetBeans IDE requires the Java Development Kit (JDK) to run properly.
If you do not have any of the resources listed above, the JDK should be
the first item that you download and install.</li>
<li>The NetBeans IDE Java Bundle includes Java Web and EE technologies, which are
required for the application you build in this tutorial.</li>
<li id="glassFishSetupDevEnviron">The NetBeans IDE Java Bundle also includes the GlassFish server,
which you require for this tutorial. You could
<a href="http://glassfish.dev.java.net/public/downloadsindex.html" target="_blank">download
the GlassFish server independently</a>, but the version provided with the
NetBeans download has the added benefit of being automatically registered with
the IDE.</li>
</ul>
<br>
<h2 id="create">Creating a Web Project</h2>
<ol>
<li>Start the NetBeans IDE. If you are running the IDE for the first time, you
will see the IDE's Start Page.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/ide-start-page.png"
class="margin-around b-all" alt="NetBeans IDE Start Page" title="The NetBeans IDE Start Page"></li>
<li>Click the New Project ( <img src="../../../../images_www/articles/73/javaee/ecommerce/common/new-project-btn.png"
alt="New Project icon"> ) button (Ctrl-Shift-N; &#8984;-Shift-N on Mac) to create
a new Java web project. The New Project wizard opens to guide you through the
process. Under Categories choose Java Web, then under Projects choose Web
Application.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/new-project-wzd.png"
class="margin-around b-all" alt="New Project wizard" width="688px"
title="Create a project using the New Project wizard"></li>
<li>Click Next.</li>
<li>In Step 2: Name and Location, name the project <code>AffableBean</code>. In
this step, you can also designate the location on your computer where the project
will reside. By default, the IDE creates a <code>NetBeansProjects</code> folder
in your home directory. If you'd like to change the location, enter the path in
the Project Location text field.</li>
<li>Click Next.</li>
<li>In Step 3: Server and Settings, specify GlassFish v3 as the server to which
your project will be deployed during development. Since you've included GlassFish
v3 in your NetBeans installation, you'll see that GlassFish v3 is listed in the
Server drop-down field.
<br><br>
<p class="tips">If you wanted to deploy to a server that isn't yet registered
with the IDE, you would click the Add button, and step through the Add Server
Instance wizard. You can view all servers registered with the IDE from the
Servers window (Choose Tools &gt; Servers from the main menu).</p></li>
<li>For Java EE Version, select Java EE 6 Web.
<br><br>
The application that you create makes use of various Java EE 6 features, namely
servlet annotations (new in the <a href="http://jcp.org/en/jsr/summary?id=315" target="_blank">Servlet
3.0 Specification</a>), and EJBs used directly in servlet containers (new in the
<a href="http://jcp.org/en/jsr/summary?id=318" target="_blank">EJB 3.1 Specification</a>).
Both Servlet 3.0 and EJB 3.1 are part of the Java EE 6 platform, therefore you
require an EE-6 compliant server such as GlassFish v3 to work through this tutorial.
For more information, see <a href="entity-session.html#specification">About Specifications
and Implementations</a>.</li>
<li>Make sure that the 'Enable Contexts and Dependency Injection' option is deselected.
This option is specific to the Contexts and Dependency Injection (CDI) technology,
specified by <a href="http://jcp.org/en/jsr/detail?id=299" target="_blank">JSR-299</a>,
and is not used in this tutorial. For more information, see <a href="../cdi-intro.html">Getting
Started with Contexts and Dependency Injection and JSF 2.0</a>.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/new-project-wzd2.png"
class="margin-around b-all" alt="New Web Application wizard, Step 3: Server and Settings" width="688px"
title="Specify development server, EE version, and whether to include CDI support">
<br><br>
Note that by default the context path for the application is the name of the
project. This is the path at which your application can be accessed after it
is deployed to the server. For example, GlassFish uses 8080 as its default port
number, so during development you'll be able to access the project in a browser
window from:
<pre class="examplecode">http://localhost:8080/AffableBean/</pre></li>
<li>Click Finish. The IDE generates a skeleton project named <code>AffableBean</code>
that adheres to the <a href="http://java.sun.com/blueprints/code/projectconventions.html#99632" target="_blank">J2EE
Blueprints conventions for web application structure</a>.
The IDE displays various windows in its default layout.
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/ide-default-layout.png"
rel="lytebox" title="Default layout for a Java Web project">
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/ide-default-layout.png"
alt="NetBeans IDE - default layout" class="b-all margin-around" width="688px"></a></li>
<li>Examine the IDE's default layout. Here's a brief overview of the displayed windows and tabs:
<ul style="margin: 5px 0 0 -1.5em">
<li><strong>The Editor:</strong> The editor (Ctrl-0; &#8984;-0 on Mac) is the
central component of the IDE, and is likely where you'll spend most of your
time. The editor automatically adapts to the language you are working in,
providing documentation support, code-completion, hints and error messages
specific to the technology you are coding in.</li>
<li><strong>Projects window:</strong> The Projects window (Ctrl-1; &#8984;-1 on Mac)
is the entry point to your project sources. It provides a <em>logical view</em>
of important project contents, and groups files together based on their function
(e.g., <code>Configuration Files</code>). When right-clicking file nodes within
the Projects window, you can call actions common to your development tasks (i.e.,
<code>Build</code>, <code>Clean</code>, <code>Deploy</code>, <code>Run</code>).</li>
<li><strong>Files window:</strong> The Files window (Ctrl-2; &#8984;-2 on Mac)
provides a directory-based view of your project. That is, it enables you to
view the structure of your project, as it exists in your computer's file system.
From this window, you can view all files pertaining to your project, including
the Ant build script, (<code>build.xml</code>), and files required by the IDE
to handle the project (contained in the <code>nbproject</code> folder). If you've
run your project, you can see the location of compiled Java files (<code>build</code>
folder). If you've explicitly built your project (by choosing Build, or Clean and
Build, from the project node's right-click menu in the Projects window), you can
view the project's distributable WAR file (contained in the <code>dist</code>
folder).</li>
<li><strong>Navigator:</strong> The Navigator (Ctrl-7; &#8984;-7 on Mac) provides
a structural overview of the file opened in the editor. For example, if an HTML
web page is displayed, the Navigator lists tag nodes in a way that corresponds to
the page's Document Object Model (DOM). If a Java class is opened in the editor,
the Navigator displays the properties and methods pertaining to that class. You
can use the Navigator to navigate to items within the editor. For example, when
you double-click a node in the Navigator, your cursor is taken directly to that
element in the editor.</li>
<li><strong>Tasks window:</strong> The Tasks window (Ctrl-6; &#8984;-6 on Mac)
automatically scans your code and lists lines with compile errors, quick fixes,
and style warnings. For Java classes, it also lists commented lines containing
words such as '<code>TODO</code>' or '<code>FIXME</code>'.</li>
<li><strong>Services window:</strong> The Services window (Ctrl-5; &#8984;-5 on Mac)
provides an interface for managing servers, web services, databases and
database connections, as well as other services relating to team development.</li>
<li><strong>Output window:</strong> <em>(Not displayed)</em> The Output window (Ctrl-4;
&#8984;-4 on Mac) automatically displays when you call an action that invokes a
service, generally from an outside resource such as a server, and can mirror
server log files. With web projects, it also enables you to view information
related to Ant tasks (e.g., <code>Build</code>, <code>Clean and Build</code>,
<code>Clean</code>).</li>
<li><strong>Palette:</strong> <em>(Not displayed)</em> The Palette (Ctrl-Shift-8;
&#8984;-Shift-8 on Mac) provides various handy code snippets that you can drag
and drop into the editor. Many of the snippets included in the Palette are also
accessible by invoking code completion in the editor, as will later be demonstrated.</li>
</ul>
<p class="notes"><strong>Note:</strong> All of the IDE's windows can be accessed from the
Window menu item.</p>
</li>
</ol>
<h2 id="run">Running the Web Project</h2>
<ol>
<li>Run the new <code>AffableBean</code> project. In the Projects window, you can do
this by right-clicking the project node and choosing Run, otherwise, click the
Run Project ( <img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project icon"> ) button (F6; fn-F6 on Mac) in the IDE's main toolbar.
<br><br>
A browser window opens to display the project's welcome page.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/hello-world.png"
class="margin-around b-all" alt="Project welcome page displayed in browser"
title="Project automatically deploys to server and displays in browser">
<br>
So what just happened? When you run a web project, the IDE invokes the <code>run</code>
Ant target in your project's build script. You can investigate by opening your project's
<code>build.xml</code> file in the editor.</li>
<li>Switch to the Files window (Ctrl-2; &#8984;-2 on Mac), expand the project node and
double-click the <code>build.xml</code> file contained in your project. When the
<code>build.xml</code> file opens in the editor, the Navigator lists all Ant targets
available to the script.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/navigator-ant-targets.png"
class="margin-around b-all" alt="Navigator displaying Ant targets for build.xml"
title="The Navigator lists all available Ant targets for the build.xml script">
<p class="tips">Normal Ant targets are displayed using the general target (
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/ant-normal-icon.png"
alt="Normal Ant target icon"> ) icon. The <em>emphasized</em> Ant target (
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/ant-emphasized-icon.png"
alt="Emphasized Ant target icon"> ) icon merely indicates that the target
includes a description, which is displayed as a tooltip (as shown in the above
image). For more information, see
<a href="http://www.oracle.com/pls/topic/lookup?ctx=nb8000&id=NBDAG366">Creating Java Projects</a> in <em>Developing Applications with NetBeans IDE</em>.</p></li>
<li>Double-click the <code>run</code> target. The <code>build-impl.xml</code> file
opens in the editor and displays the target definition.
<pre class="examplecode">&lt;target depends=&quot;run-deploy,run-display-browser&quot; description=&quot;Deploy to server and show in browser.&quot; name=&quot;run&quot;/&gt;</pre>
Why did the <code>build-impl.xml</code> file open when we clicked on a target from
<code>build.xml</code>? If you switch back to <code>build.xml</code> (press Ctrl-Tab)
and examine the file contents, you'll see the following line:
<pre class="examplecode">&lt;import file=&quot;nbproject/build-impl.xml&quot;/&gt;</pre>
<p>The project's build script is basically an empty file that imports NetBeans-defined
targets from <code>nbproject/build-impl.xml</code>.</p>
<p class="alert">You can freely edit your project's standard <code>build.xml</code>
script by adding new targets or overriding existing NetBeans-defined targets.
However, you should not edit the <code>build-impl.xml</code> file.</p>
You can see from the <code>run</code> target's definition that it depends on the
following targets:
<ul style="margin: 5px 0 0 -1.5em">
<li><code>run-deploy</code></li>
<li><code>run-display-browser</code></li>
</ul>
Both of these targets in turn depend on other targets, which you can examine
elsewhere in the <code>build-impl.xml</code> file. But essentially, the following
actions take place when the <code>run</code> target is invoked:
<ol style="margin: 5px 0 0 -1em">
<li>The project gets compiled.</li>
<li>A WAR file is created.</li>
<li>The server starts (if it is not already running).</li>
<li>The WAR file gets deployed to the designated server.</li>
<li>The browser opens to display the server's URL and application's
context path.</li>
</ol>
<p class="tips">Consult the official <a href="http://ant.apache.org/manual/index.html" target="_blank">Ant
Manual</a> for more information on using Ant.</p>
</li>
<li>To generate a distributable WAR file for your project, choose Clean and Build Project
(or Clean and Build Main Project) from the IDE's Run menu.</li>
<li>In the Files window (Ctrl-2; &#8984;-2 on Mac) expand the project
node. The <code>dist</code> folder contains the project WAR file.
The <code>build</code> folder contains your compiled project.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/files-window.png"
class="margin-around b-all" alt="Files window"
title="Files window provides a directory-based view of your project">
<p class="notes"><strong>Note:</strong> If you <em>clean</em> the project (In the
Projects window, choose Clean from the project node's right-click menu), both
of these folders are removed.</p></li>
<li>Switch to the Services window (Ctrl-5; &#8984;-5 on Mac) and expand the Servers
&gt; GlassFish Server 3 &gt; Applications node.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/services-win-deployed-app.png"
class="margin-around b-all" alt="Services window - GlassFish v3"
title="Services window displays server status, deployed applications and resources">
<p class="notes"><strong>Note:</strong> &quot;GlassFish v3&quot; is the default server name for NetBeans 6.8 users.</p>
The green arrow icon on the GlassFish server node (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/gf-server-running-node.png"
alt="GlassFish server node in Services window"> ) indicates that the server is
running. The Applications folder lists all deployed applications; you can see
that the <code>AffableBean</code> application has been successfully deployed.</li>
</ol>
<p>At this stage, you've created a Java web project in the IDE, and have confirmed
that it can be successfully built and deployed to your development server, and
opened in a browser when run.</p>
<br>
<h2 id="communicate">Communicating with the Database Server</h2>
<p>Once you've downloaded and installed the MySQL database server, you can connect to
it from the IDE. A default installation uses '<code>root</code>' and '' (an empty
string) as the user account and password to connect to the database server. However,
due to connectivity issues with GlassFish, it is recommended that you use an account
with a non-empty password.<sup><a href="#footnote1SetupDevEnviron" id="1SetupDevEnviron" style="text-decoration:none">[1]</a></sup>
The following instructions demonstrate how to run the database server
and change the password for the <code>root</code> account to '<code>nbuser</code>'
from the MySQL command-line. The '<code>root</code>' / '<code>nbuser</code>'
combination is used throughout the NetBeans E-commerce Tutorial. With the database
server running and properly configured, you register it in the IDE and create a
database instance.</p>
<p class="notes"><strong>Note:</strong> The command-line instructions below assume that
you have added the <code>mysql</code> command to your <code>PATH</code> environment
variable. (If you haven't, you'll receive a '<code>mysql: command not found</code>'
error when entering <code>mysql</code> commands in your command-line.)
<br><br>
If you haven't added <code>mysql</code> to your <code>PATH</code>, you can instead
call the command by entering the full path to your MySQL installation's <code>bin</code>
directory. For example, if the <code>mysql</code> command is located on your computer
at <code>/usr/local/mysql/bin</code>, you would enter the following:</p>
<pre class="examplecode" style="width: 700px; margin-left:30px">shell&gt; <strong>/usr/local/mysql/bin/</strong>mysql -u root</pre>
<p style="margin-left:30px">For more information, see the offical MySQL Reference Manual:</p>
<ul>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/general-installation-issues.html"
target="_blank">2.1. General Installation Guidance</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/default-privileges.html"
target="_blank">2.13.2. Securing the Initial MySQL Accounts</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/invoking-programs.html"
target="_blank">4.2.1. Invoking MySQL Programs</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/setting-environment-variables.html"
target="_blank">4.2.4. Setting Environment Variables</a></li>
</ul>
<br>
<p>Perform the following steps.</p>
<ul>
<li><a href="#check">Check if the MySQL Server is Running</a></li>
<li><a href="#start">Start the Database Server</a></li>
<li><a href="#password">Change the Password</a></li>
<li><a href="#register">Register the Server in the IDE</a></li>
<li><a href="#database">Create a Database Instance</a></li>
</ul>
<div class="indent">
<h3 id="check">Check if the MySQL Server is Running</h3>
<p>Before connecting to the MySQL server from the IDE, you need to make sure the
server is running. One way to do this is by using the
<a href="http://dev.mysql.com/doc/refman/5.1/en/mysqladmin.html" target="_blank"><code>mysqladmin</code></a>
client's <code>ping</code> command.</p>
<ol>
<li>Open a command-line prompt and type in the following:
<pre class="examplecode" style="width:660px">shell&gt; mysqladmin ping</pre>
If the server is running, you will see output similar to the following:
<pre class="examplecode" style="width:660px">mysqld is alive</pre>
If the server is not running, you'll see output similar to the following:
<pre class="examplecode" style="width:660px">
mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to local MySQL server through socket '/tmp/mysql.sock'
Check that mysqld is running and that the socket: '/tmp/mysql.sock' exists!</pre>
</li>
</ol>
<h3 id="start">Start the Database Server</h3>
<p>In the event that your MySQL server is not running, you can start it from
the command-line. See <a href="http://dev.mysql.com/doc/refman/5.1/en/automatic-start.html"
target="_blank">2.13.1.2. Starting and Stopping MySQL Automatically</a> for a brief,
cross-platform overview. The following steps provide general guidance depending on your
operating system.</p>
<h4>Unix-like systems:</h4>
<p>For Unix-like systems, it is recommended to start the MySQL server by invoking
<a href="http://dev.mysql.com/doc/mysql-startstop-excerpt/5.1/en/mysqld-safe.html" target="_blank"><code>mysqld_safe</code></a>.</p>
<ol>
<li>Open a command-line prompt and run the <code>mysqld_safe</code> command:
<pre class="examplecode" style="width:660px">shell&gt; sudo ./mysqld_safe</pre>
You will see output similar to the following:
<pre class="examplecode" style="width:660px">090906 02:14:37 mysqld_safe Starting mysqld daemon with databases from /usr/local/mysql/data</pre></li>
</ol>
<h4>Windows:</h4>
<p>The MySQL Windows installer enables you to install the database server as a Windows
service, whereby MySQL starts and stops automatically with the operating system.
If you need to start the database manually, run the
<a href="http://dev.mysql.com/doc/mysql-startstop-excerpt/5.1/en/mysqld.html" target="_blank"><code>mysqld</code></a>
command from the installation directory's <code>bin</code> folder.</p>
<ol>
<li>Open a Windows console window (from the Start menu, choose Run and type <code>cmd</code>
in the text field). A command-line window displays.</li>
<li>Enter this command (The indicated path assumes you have installed version 5.1 to
the default install location):
<pre class="examplecode" style="width:660px">C:\&gt; &quot;C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld&quot;</pre></li>
</ol>
<p>For more information, refer to the official MySQL Reference Manual:
<a href="http://dev.mysql.com/doc/refman/5.1/en/windows-start-command-line.html"
target="_blank">2.4.5.5. Starting MySQL from the Windows Command Line</a>.</p>
<h3 id="password">Change the Password</h3>
<p>To set the <code>root</code> account's password to '<code>nbuser</code>', perform
the following steps.</p>
<ol>
<li>Open a command-line prompt and type in the following:
<pre class="examplecode" style="width:660px">
shell> mysql -u root
mysql> UPDATE mysql.user SET Password = PASSWORD('nbuser') WHERE User = 'root';
mysql> FLUSH PRIVILEGES;</pre>
</li>
</ol>
<p>For more information, see the official MySQL Reference Manual:
<a href="http://dev.mysql.com/doc/refman/5.1/en/default-privileges.html"
target="_blank">2.13.2. Securing the Initial MySQL Accounts</a>.</p>
<h3 id="register">Register the Server in the IDE</h3>
<p>The IDE's Services window enables you to connect to the server, start and stop the
server, view database instances and the data they contain, as well as run an external
administration tool on the server.</p>
<ol>
<li>In the Services window, right-click the Databases node and choose Register
MySQL Server.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/register-mysql-server.png"
class="margin-around b-all" alt="Services window - right-click options on Databases node"
title="Register a MySQL server in the IDE's Services window">
<br>
In the MySQL Server Properties dialog, under the Basic Properties tab, you
can see the default settings for the MySQL server installation. These are:
<ul style="margin: 5px 0 0 -2em">
<li><strong>Server Host Name:</strong> <code>localhost</code></li>
<li><strong>Server Port Number:</strong> <code>3306</code></li>
<li><strong>Administrator User Name:</strong> <code>root</code></li>
<li><strong>Administrator Password:</strong> <code>nbuser</code></li>
</ul></li>
<li>Select the Save Password option.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/mysql-server-properties.png"
class="margin-around b-all" alt="MySQL Server Properties dialog"
title="Specify MySQL server settings"></li>
<li>Click OK. The IDE connects to your MySQL database server, and lists database
instances that are maintained by the server. If you expand the Drivers node,
you can also see that the IDE contains the
<a href="http://dev.mysql.com/doc/refman/5.1/en/connector-j.html" target="_blank">Connector/J
JDBC driver</a> for MySQL.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/services-win-mysql.png"
class="margin-around b-all" alt="Services window - MySQL Server"
title="Connect to a MySQL server in the Services window">
<br>
The application server (i.e., GlassFish) requires the driver to enable communication
between your Java code and the the MySQL database. Because the IDE already contains
the Connector/J driver, you do not need to download it. Furthermore, as will later
be demonstrated, you can specify in your server settings to enable JDBC driver
deployment so that the driver will be automatically deployed to GlassFish if it
is missing on the server.
<br><br>
Steps 4-7 below are optional. You can configure the IDE to start and stop the
MySQL server, as well as run an external administration tool on the server.</li>
<li>Right-click the MySQL server node and choose Properties. In the MySQL Server
Properties dialog, select the Admin Properties tab.</li>
<li>In the 'Path/URL to admin tool' field, enter the path on your computer to the
executable file of a database administration tool, such as
<a href="http://dev.mysql.com/doc/administrator/en/mysql-administrator-introduction.html" target="_blank">MySQL
Administrator</a>. The MySQL Administrator is included in the
<a href="http://dev.mysql.com/downloads/gui-tools/" target="_blank">MySQL GUI
Tools</a> bundle.</li>
<li>In the 'Path to start command' field, type in the path to the MySQL start command
(i.e., <code>mysqld</code> or <code>mysqld_safe</code>, depending on your operating
system. (See <a href="#start">Start the Database Server</a> above.)
<br><br>
<p class="notes"><strong>Note:</strong> For Unix-like systems, you may find
that you can only invoke the start command with root or administrative
privileges. To overcome this, you can create a script (using
<a href="http://www.nongnu.org/gksu/" target="_blank">GKSu</a> for Linux and Solaris,
<a href="http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man1/osascript.1.html" target="_blank">osascript</a>
for Mac) that will accomplish this task. For more information, see
<a href="http://davidvancouvering.blogspot.com/2008/09/starting-mysql-in-netbeans-as.html" target="_blank">this
blog post</a>.</li>
<li>In the 'Path to stop command' field, enter the path to the MySQL stop command
(i.e., <code>mysqladmin shutdown</code>). Because the command requires a user account
with shutdown privileges, you must enter username/password credentials in the Arguments
field. For example:
<ul style="margin: 5px 0 0 -2em">
<li><strong>Arguments:</strong> <code>-u root -pnbuser shutdown</code></li>
</ul>
</li>
</ol>
<p>After you have set the fields listed under the Advanced Properties tab, you can:</p>
<ul>
<li><strong>Start the MySQL server:</strong> Right-click the MySQL server node and choose Start.</li>
<li><strong>Stop the MySQL server:</strong> Right-click the MySQL server node and choose Stop.</li>
<li><strong>Run the external administration tool:</strong> Right-click the MySQL server node and
choose Run Administration Tool.</li>
</ul>
<h3 id="database">Create a Database Instance</h3>
<ol>
<li>Create the database instance which you will use in this tutorial. To do so,
right-click the MySQL Server node and choose Create Database.</li>
<li>In the dialog that displays, type in <code>affablebean</code>. Select the
'Grant Full Access to' option, then select <code>root@localhost</code> from
the drop-down field. This enables the <code>root</code> account on the
<code>localhost</code> host access to the database. Later, when you create
a connection pool on the server, you'll need to provide the <code>root</code>
account and <code>nbuser</code> password as username/password credentials
in order to grant the server access to the database.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/create-mysql-db-dialog.png"
class="margin-around b-all" alt="Create MySQL Database dialog"
title="Right-click the server node and choose Create Database to create a new database instance"></li>
<li>Click OK. When you do so, the database named <code>affablebean</code> is created,
and a connection to the database is automatically established. Connections are
displayed in the Services window using a connection node (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/db-connection-node.png"
alt="Database connection node"> ).
<p class="notes"><strong>Note:</strong> Connection nodes are persisted in the
Services window. If you restart the IDE, the connection node displays with
a jagged line ( <img src="../../../../images_www/articles/73/javaee/ecommerce/common/connection-broken.png"
alt="Database connection node - disconnected"> ), indicating that the connection
is broken. To reconnect to a database, make sure that the database server
is running, then right-click the node and choose Connect.</p></li>
<li>Expand the connection node for the <code>affablebean</code> database. The
connection contains the database's default schema (<code>affablebean</code>),
and within that are nodes for tables, views, and procedures. Currently these
are empty since we haven't created anything yet.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup-dev-environ/db-conn-affable-bean.png"
class="margin-around b-all" alt="Services window - Database connection for 'affablebean'"
title="Database connections contain the database's default schema and nodes for tables, views and procedures"></li>
</ol>
</div>
<p>At this stage, you've connected to the MySQL server from the IDE and have created
a new database named <code>affablebean</code> which you'll use throughout the tutorial.
Also, you've created a Java web project in the IDE, and have confirmed that it can be
successfully built and deployed to your development server, and opened in a browser
when run. Now that your development environment is ready, you can begin drafting the
application's data model.</p>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans E-commerce Tutorial - Setting up the Development Environment">Send
Us Your Feedback</a></div>
<br style="clear:both;">
<h2 id="seeAlsoSetupDevEnviron">See Also</h2>
<div class="indent">
<h3>NetBeans Resources</h3>
<ul>
<li><a href="../../java/project-setup.html" target="_blank">Creating, Importing, and Configuring Java Projects</a></li>
<li><a href="../../../articles/mysql.html" target="_blank">MySQL and NetBeans IDE</a></li>
<li><a href="../../ide/mysql.html" target="_blank">Connecting to a MySQL Database</a></li>
<li><a href="../../web/mysql-webapp.html" target="_blank">Creating a Simple Web Application Using a MySQL Database</a></li>
</ul>
<h3>External Resources</h3>
<ul>
<li><a href="http://ant.apache.org/manual/index.html" target="_blank">Apache Ant User Manual</a></li>
<li><a href="http://ant.apache.org/manual/tutorial-HelloWorldWithAnt.html" target="_blank">Hello World with Ant</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/" target="_blank">MySQL 5.1 Reference Manual</a></li>
<li><a href="http://dev.mysql.com/doc/administrator/en/index.html" target="_blank">MySQL Administrator Reference Manual</a></li>
</ul>
<h3>Books</h3>
<ul>
<li><a href="https://netbeans.org/kb/articles/books.html" target="_blank">NetBeans Books</a></li>
<li><a href="http://www.apress.com/book/view/1590598954" target="_blank">Pro NetBeans IDE 6 Rich Client Platform Edition</a></li>
<li><a href="http://apress.com/book/view/1430219548" target="_blank">Beginning Java EE 6 Platform with GlassFish 3: From Novice to Professional</a></li>
</ul>
</div>
<br>
<h2>References</h2>
<ol>
<li id="footnote1SetupDevEnviron"><a href="#1SetupDevEnviron" style="text-decoration:none">^</a> Using GlassFish v3, you can create
a connection pool to a MySQL database server using an empty password. GlassFish Open Source Edition
3.0.1, included with NetBeans IDE 6.9, does not enable a connection using an empty password. See
<a href="http://glassfish.dev.java.net/issues/show_bug.cgi?id=12221" target="_blank">GlassFish
Issue 12221</a>.</li>
</ol>
<br><br><br><br>
<h1 id="data-model">The NetBeans E-commerce Tutorial - Designing the Data Model</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Tutorial Contents</h4>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#design">Designing the Application</a></li>
<li><a href="#setup-dev-environ">Setting up the Development Environment</a></li>
<li><strong>Designing the Data Model</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#idEntities">Identifying Entities for the Data Model</a></li>
<li><a href="#createERDiagram">Creating an Entity-Relationship Diagram</a></li>
<li><a href="#forwardEngineer">Forward-Engineering to the Database</a></li>
<li><a href="#connectDB">Connecting to the Database from the IDE</a></li>
<li><a href="#seeAlsoDataModel">See Also</a></li>
</ul></li>
<li><a href="#page-views-controller">Preparing the Page Views and Controller Servlet</a></li>
<li><a href="#connect-db">Connecting the Application to the Database</a></li>
<li><a href="#entity-session">Adding Entity Classes and Session Beans</a></li>
<li><a href="#manage-sessions">Managing Sessions</a></li>
<li><a href="#transaction">Integrating Transactional Business Logic</a></li>
<li><a href="#language">Adding Language Support</a></li>
<li><a href="#security">Securing the Application</a></li>
<li><a href="#test-profile">Testing and Profiling</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ol>
</div>
</div>
<p><img src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" class="stamp"
alt="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"
title="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"></p>
<p>This tutorial unit focuses on data modeling, or the process of creating a conceptual
model of your storage system by identifying and defining the entities that your system
requires, and their relationships to one another. The data model should contain all
the logical and physical design parameters required to generate a script using the Data
Definition Language (DDL), which can then be used to create a database.<sup><a href="#footnote1DataModel"
id="1DataModel" style="text-decoration:none">[1]</a></sup></p>
<p>In this unit, you work primarily with <a href="http://wb.mysql.com/" target="_blank">MySQL
Workbench</a>, a graphical tool that enables you to create data models, reverse-engineer
SQL scripts into visual representations, forward-engineer data models into database
schemata, and synchronize models with a running MySQL database server.</p>
<p>You begin by creating an entity-relationship diagram to represent the data model for
the <code>AffableBean</code> application. When you have completed identifying and
defining all entities and the relationships that bind them, you use Workbench to
forward-engineer and run a DDL script that converts the data model into a database
schema. Finally, you connect to the new schema from the NetBeans IDE.</p>
<p>You can view a live demo of the application that you build in this tutorial:
<a href="http://services.netbeans.org/AffableBean/" target="_blank">NetBeans E-commerce
Tutorial Demo Application</a>.</p>
<br style="clear:both;">
<br>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html" target="_blank">NetBeans
IDE</a></td>
<td class="tbltd1">Java bundle, 6.8 or 6.9</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank">Java Development Kit (JDK)</a></td>
<td class="tbltd1">version 6</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://dev.mysql.com/downloads/mysql/" target="_blank">MySQL database server</a></td>
<td class="tbltd1">version 5.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://dev.mysql.com/downloads/workbench/" target="_blank">MySQL Workbench</a></td>
<td class="tbltd1">version 5.1 or 5.2</td>
</tr>
</tbody>
</table>
<p><strong class="notes">Notes:</strong></p>
<ul>
<li>The NetBeans IDE requires the Java Development Kit (JDK) to run properly.
If you do not have any of the resources listed above, the JDK should be
the first item that you download and install.</li>
<li>The NetBeans IDE Java Bundle includes Java Web and EE technologies, which are
required for the application you build in this tutorial.</li>
<li>You can download the complete DDL script that MySQL Workbench generates from
the entity-relationship diagram you create in this tutorial:
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252Faffablebean_schema_creation.sql">affablebean_schema_creation.sql</a>.</li>
</ul>
<br>
<h2 id="idEntities">Identifying Entities for the Data Model</h2>
<p>In the real world, you may not have the luxury of designing the data model for your
application. For example, your task may be to develop an application on top of an
existing database system. Provided you do not have a data model to base your application
on, creating one should be one of the first design steps you take before embarking on
development. Creating a data model involves identifying the objects, or <em>entities</em>,
required by your system and defining the relationships between them.</p>
<p id="nounList">To begin identifying the entities we need for the data model,
re-examine the use-case presented in <a href="design.html#mockups">Designing
the Application</a>. Search for commonly-occurring nouns. For example:</p>
<div class="indent">
<div class="feedback-box margin-around float-left" style="width:723px">
<h3>Use-Case</h3>
<p><strong>Customer</strong> visits the welcome page and selects a product
<strong>category</strong>. <strong>Customer</strong> browses <strong>products</strong>
within the selected category page, then adds a <strong>product</strong> to
his or her <strong>shopping cart</strong>. <strong>Customer</strong> continues
shopping and selects a different <strong>category</strong>. <strong>Customer</strong>
adds several <strong>products</strong> from this <strong>category</strong> to
<strong>shopping cart</strong>. <strong>Customer</strong> selects 'view cart'
option and updates quantities for cart <strong>products</strong> in the cart
page. <strong>Customer</strong> verifies shopping cart contents and proceeds
to checkout. In the checkout page, <strong>customer</strong> views the cost of
the <strong>order</strong> and other information, fills in personal data, then
submits his or her details. The <strong>order</strong> is processed and
<strong>customer</strong> is taken to a confirmation page. The confirmation
page provides a unique reference number for tracking the customer <strong>order</strong>,
as well as a summary of the <strong>order</strong>.</p>
</div>
</div>
<br style="clear:both">
<br>
<p>The text highlighted above in <strong>bold</strong> indicates the candidates that we
can consider for the data model. Upon closer inspection, you may deduce that the
shopping cart does not need to be included, since the data it provides (i.e., products
and their quantities) is equally offered by a customer order once it is processed. In
fact, as will be demonstrated in Unit 8, <a href="#manage-sessions">Managing Sessions</a>,
the shopping cart merely serves as a mechanism that retains a user session temporarily
while the customer shops online. We can therefore settle on the following list:</p>
<ul class="toc">
<li><strong>customer</strong></li>
<li><strong>category</strong></li>
<li><strong>product</strong></li>
<li><strong>order</strong></li>
</ul>
<p>With these four entities, we can begin constructing an entity-relationship diagram (ERD).</p>
<p class="notes"><strong>Note:</strong> In this tutorial, we create a database schema from
the ERD, then use the IDE's EclipseLink support to generate JPA entity classes from the
existing database. (EclipseLink and the Java Persistence API (JPA) are covered in Unit
7, <a href="#entity-session">Adding Entity Classes and Session Beans</a>.) This
approach is described as <em>bottom up</em> development. An equally viable alternative
is the <em>top down</em> approach.</p>
<ul>
<li><strong>Top down:</strong> In <em>top down</em> development, you start with
an existing Java implementation of the domain model, and have complete freedom
with respect to the design of the database schema. You must create mapping
metadata (i.e., annotations used in JPA entity classes), and can optionally
use a persistence tool to automatically generate the schema.</li>
<li><strong>Bottom up:</strong> <em>Bottom up</em> development begins with an
existing database schema. In this case, the easiest way to proceed is to use
forward-engineering tools to extract metadata from the schema and generate
annotated Java source code (JPA entity classes).</li>
</ul>
<p>For more information on top down and bottom up design strategies, see
<a href="http://en.wikipedia.org/wiki/Data_modeling#Modeling_methodologies" target="_blank">Data
modeling: Modeling methodologies</a> [Wikipedia].</p>
<br>
<h2 id="createERDiagram">Creating an Entity-Relationship Diagram</h2>
<p>Start by running MySQL Workbench. In this exercise, you use Workbench to design an
entity-relationship diagram for the <code>AffableBean</code> application.</p>
<p class="notes"><strong>Note:</strong> The following instructions work for MySQL Workbench
versions 5.1 <em>and</em> 5.2. The images used in this tutorial are taken from version 5.2.
There are slight differences in the graphical interface between versions, however the
functionality remains consistent. Because version 5.2 incorporates a query editor (previously
MySQL Query Browser), as well as a server administration interface (previously MySQL
Administrator), you are presented with the Home screen when opening the application
(shown below).</p>
<div class="indent">
<a href="../../../../images_www/articles/73/javaee/ecommerce/data-model/workbench-home.png"
rel="lytebox" title="In Workbench 5.2, the Home screen serves as a central interface to
the data modeling tool, an SQL editor, and an administration tool">
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/workbench-home.png"
class="margin-around b-all" style="width: 728px" alt="MySQL Workbench 5.2 - Home screen"
title="Click to enlarge"></a>
</div>
<p>If you are working in Workbench 5.2, click <strong>Create New EER Model</strong> beneath
the Data Modeling heading in the Home screen.</p>
<ul>
<li><a href="#createSchema">Creating the <code>affablebean</code> Schema</a></li>
<li><a href="#createEntities">Creating Entities</a></li>
<li><a href="#addProperties">Adding Entity Properties</a></li>
<li><a href="#identifyRelationships">Identifying Relationships</a></li>
</ul>
<div class="indent">
<h3 id="createSchema">Creating the <code>affablebean</code> Schema</h3>
<ol>
<li>In the default interface, begin by creating a new schema which will be used with
the <code>AffableBean</code> application. Click the plus (
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/plus-icon.png"
class="b-all" alt="Plus icon"> ) icon located to the right of the <strong>Physical
Schemata</strong> heading.
<br><br>
A new panel opens in the bottom region of the interface, enabling you
to specify settings for the new schema.
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/data-model/workbench.png"
rel="lytebox" title="Use Workbench to create a new database schema">
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/workbench.png"
class="margin-around b-all" style="width: 688px" alt="New schema panel displays in bottom region of interface"
title="Click to enlarge"></a></li>
<li>Enter the following settings for the new schema:
<ul style="margin: 5px 0 0 -.7em">
<li><strong>Schema Name:</strong> <code>affablebean</code></li>
<li><strong>Default Collation:</strong> <code>utf8 - utf8_unicode_ci</code></li>
<li><strong>Comments:</strong> <code>Schema used with the AffableBean application</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/affablebean-schema.png"
class="margin-around b-all" style="width: 688px" alt="Settings for 'affablebean' schema"
title="Enter settings for 'affablebean' schema">
<br>
The new schema is created, and becomes listed under the Catalog tab in the right region
of the Workbench interface.
<br><br>
<p class="tips">For an explanation of character sets and collations, see the MySQL
Server Manual: <a href="http://dev.mysql.com/doc/refman/5.1/en/charset-general.html" target="_blank">9.1.1.
Character Sets and Collations in General</a>.</p></li>
</ol>
<h3 id="createEntities">Creating Entities</h3>
<p>Start by creating a new entity-relationship diagram in MySQL Workbench. You can
drag-and-drop entity tables onto the canvas.</p>
<ol>
<li>Under the EER Diagrams heading in WorkBench, double-click the Add
Diagram ( <img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/add-diagram-btn.png"
alt="Add Diagram icon"> ) icon. A new EER Diagram opens displaying an empty canvas.
<br><br>
<span class="tips">'EER' stands for Enhanced Entity-Relationship.</span>
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/data-model/workbench-empty-canvas.png"
rel="lytebox" title="Use Workbench to create a new database schema">
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/workbench-empty-canvas.png"
class="margin-around b-all" style="width: 688px" alt="New EER Diagram displayed an empty canvas"
title="Click Add Diagram to create a new, empty canvas"></a></li>
<li>Click the New Table ( <img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/wb-new-table-icon.png"
alt="New Table icon"> ) icon located in the left margin, then hover your mouse onto the canvas
and click again. A new table displays on the canvas.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/wb-new-entity-table.png"
class="margin-around b-all" alt="New entity table displayed on canvas"
title="Click the New Table icon to drag empty tables (entities) onto the canvas"></li>
<li>Double-click the table. The Table editor opens in the bottom region of the interface, allowing
you to configure settings for the table.
<br><br>
<p class="notes"><strong>Note:</strong> The terms 'table' and 'entity' are nearly synonymous in this tutorial
unit. From the point of view of a database schema, you are creating tables. From a data modeling
perspective, you are creating entities. Likewise, the columns that you later create for each
table correspond to entity <em>properties</em>.</p></li>
<li>In the Table editor, rename the table to one of the nouns you identified from the use-case above.
Optionally add a comment describing the purpose of the table. For example:
<ul style="margin: 5px 0 0 -.7em">
<li><strong>Name:</strong> <code>customer</code></li>
<li><strong>Engine:</strong> <code>InnoDB</code></li>
<li><strong>Comments:</strong> <code>maintains customer details</code></li>
</ul>
<a href="../../../../images_www/articles/73/javaee/ecommerce/data-model/wb-customer-table.png" rel="lytebox"
title="Changes made in the Table editor are immediately updated elsewhere in the Workbench interface">
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/wb-customer-table.png"
class="margin-around b-all" alt="Customer table displayed on canvas" style="width:688px"
title="Click to enlarge"></a>
<p class="tips">The <a href="http://www.innodb.com/" target="_blank">InnoDB</a> engine
provides foreign key support, which is utilized in this tutorial. Later, under
<a href="#forwardEngineer">Forward-Engineering to the Database</a>, you set the
default storage engine used in Workbench to InnoDB.</p></li>
<li>Under the <strong>Catalog</strong> tab in the left region of WorkBench (right region for
version 5.1), expand the <code>affablebean</code> &gt; <code>Tables</code> node. The
<strong>customer</strong> table now displays.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/wb-catalog-tab.png"
class="margin-around b-all" alt="Catalog tab displaying new customer table"
title="Catalog tab automatically refreshes to display any changes to the schema">
<p>More importantly, note that the new <code>customer</code> table is now included in the
<code>affablebean</code> schema. Because the <code>affablebean</code> schema was selected
when you created the new EER diagram, any changes you make to the diagram are automatically
bound to the schema.</p></li>
<li>Repeat steps 2 - 4 above to add tables to the canvas for the remaining <a href="#nounList">nouns
you identified in the use-case above</a>. Before naming your tables however, there is one important
consideration which you should take into account. Certain keywords hold special meaning for the
SQL dialect used by the MySQL server. Unfortunately, '<code>order</code>' is one of them. (For
example, '<code>order</code>' can be used in an <code>ORDER BY</code> statement.) Therefore,
instead of naming your table '<code>order</code>', name it '<code>customer_order</code>' instead.
At this stage, don't worry about arranging the tables on the canvas in any special order.
<br><br>
<p class="tips">For a list of reserved words used by the MySQL server, refer to the official manual:
<a href="http://dev.mysql.com/doc/mysqld-version-reference/en/mysqld-version-reference-reservedwords-5-1.html" target="_blank">2.2.
Reserved Words in MySQL 5.1</a>.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/wb-entity-tables.png"
class="margin-around b-all" alt="All tables displayed on canvas"
title="Create all tables for affablebean schema"></li>
</ol>
<h3 id="addProperties">Adding Entity Properties</h3>
<p>Now that you've added entities to the canvas, you need to specify their properties.
Entity properties correspond to the columns defined in a database table. For example,
consider the <code>customer</code> entity. In regard to the <code>AffableBean</code>
application, what aspects of a customer would need to be persisted to the database?
These would likely be all of the information gathered in the <a href="design.html#checkout">checkout
page</a>'s customer details form, as well as some association to the processed order.</p>
<p>When adding properties, you need to determine the most appropriate data type for each
property. MySQL supports a number of data types in several categories: numeric types,
date and time types, and string (character) types. Refer to the official manual for
a summary of data types within each category:
<a href="http://dev.mysql.com/doc/refman/5.1/en/data-type-overview.html" target="_blank">10.1.
Data Type Overview</a>. In this tutorial, the data types have been chosen for you.
Choosing the appropriate data type plays a significant role in optimizing storage
on your database server. For more information see:</p>
<ul style="margin: 0 0 0 -.7em">
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/storage-requirements.html" target="_blank">10.5. Data Type Storage Requirements</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/choosing-types.html" target="_blank">10.6. Choosing the Right Type for a Column</a></li>
</ul>
<p>The following steps describe how you can use MySQL Workbench to add properties to an
existing entity in your ERD. As with most of the initial design steps, determining
the entity properties would call for careful consideration of the business problem
that needs to be solved, and could require hours of analysis as well as numerous
consultations with the client.</p>
<ol>
<li>Double-click the <code>customer</code> table heading to bring up the Table editor
in WorkBench.</li>
<li>In the Table editor click the Columns tab, then click inside the displayed table
to edit the first column. Enter the following details:
<table class="margin-around">
<tbody>
<tr>
<th class="tblheader" scope="col">Column</th>
<th class="tblheader" scope="col">Datatype</th>
<th class="tblheader" scope="col">PK (Primary Key)</th>
<th class="tblheader" scope="col">NN (Not Null)</th>
<th class="tblheader" scope="col">UN (Unsigned)</th>
<th class="tblheader" scope="col">AI (Autoincrement)</th>
</tr>
<tr>
<td class="tbltd1"><code>id</code></td>
<td class="tbltd1"><code>INT</code></td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&#10003;</td>
</tr>
</tbody>
</table>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/customer-id-column.png"
class="margin-around b-all" style="width:688px" alt="Customer entity's id column specified"
title="Click to edit table columns in the Table editor"></li>
<li>Continue working in the <code>customer</code> table by adding the following
<code>VARCHAR</code> columns. These columns should be self-explanatory, and
represent data that would need to be captured for the Affable Bean business
to process a customer order and send a shipment of groceries to the customer
address.
<br>
<table class="margin-around">
<tbody>
<tr>
<th class="tblheader" scope="col">Column</th>
<th class="tblheader" scope="col">Datatype</th>
<th class="tblheader" scope="col">NN (Not Null)</th>
</tr>
<tr>
<td class="tbltd1"><code>name</code></td>
<td class="tbltd1"><code>VARCHAR(45)</code></td>
<td class="tbltd1">&#10003;</td>
</tr>
<tr>
<td class="tbltd1"><code>email</code></td>
<td class="tbltd1"><code>VARCHAR(45)</code></td>
<td class="tbltd1">&#10003;</td>
</tr>
<tr>
<td class="tbltd1"><code>phone</code></td>
<td class="tbltd1"><code>VARCHAR(45)</code></td>
<td class="tbltd1">&#10003;</td>
</tr>
<tr>
<td class="tbltd1"><code>address</code></td>
<td class="tbltd1"><code>VARCHAR(45)</code></td>
<td class="tbltd1">&#10003;</td>
</tr>
<tr>
<td class="tbltd1"><code>city_region</code></td>
<td class="tbltd1"><code>VARCHAR(2)</code></td>
<td class="tbltd1">&#10003;</td>
</tr>
<tr>
<td class="tbltd1"><code>cc_number</code></td>
<td class="tbltd1"><code>VARCHAR(19)</code></td>
<td class="tbltd1">&#10003;</td>
</tr>
</tbody>
</table>
<br>
<span class="tips">For an explanation of the <code>VARCHAR</code>
data type, see the MySQL Reference Manual:
<a href="http://dev.mysql.com/doc/refman/5.1/en/char.html" target="_blank">10.4.1.
The CHAR and VARCHAR Types</a>.</span>
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/customer-varchar-columns.png"
class="margin-around b-all" alt="Customer entity's varchar columns specified"
title="Edit inline to add columns to customer table"></li>
<li>With the <code>customer</code> table selected on the canvas, choose
Arrange &gt; Reset Object Size to resize the table so that all columns
are visible on the canvas. Also click the Indexes row so that any table
indexes are also visible. (This includes primary and foreign keys, which
becomes useful when you begin creating relationships between tables later
in the exercise.)
<br><br>
When you finish, the <code>customer</code> entity looks as follows.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/customer-table.png"
class="margin-around" alt="'customer' table displayed on EER canvas with columns"
title="'customer' table on EER canvas displays columns"></li>
<li>Follow the steps outlined above to create columns for the remaining
tables.
<h4>category</h4>
<table class="margin-around">
<tbody>
<tr>
<th class="tblheader" scope="col">Column</th>
<th class="tblheader" scope="col">Datatype</th>
<th class="tblheader" scope="col">PK</th>
<th class="tblheader" scope="col">NN</th>
<th class="tblheader" scope="col">UN</th>
<th class="tblheader" scope="col">AI</th>
</tr>
<tr>
<td class="tbltd1"><code>id</code></td>
<td class="tbltd1"><code>TINYINT</code></td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&#10003;</td>
</tr>
<tr>
<td class="tbltd1"><code>name</code></td>
<td class="tbltd1"><code>VARCHAR(45)</code></td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&nbsp;</td>
</tr>
</tbody>
</table>
<h4>customer_order</h4>
<table class="margin-around">
<tbody>
<tr>
<th class="tblheader" scope="col">Column</th>
<th class="tblheader" scope="col">Datatype</th>
<th class="tblheader" scope="col">PK</th>
<th class="tblheader" scope="col">NN</th>
<th class="tblheader" scope="col">UN</th>
<th class="tblheader" scope="col">AI</th>
<th class="tblheader" scope="col">Default</th>
</tr>
<tr>
<td class="tbltd1"><code>id</code></td>
<td class="tbltd1"><code>INT</code></td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&nbsp;</td>
</tr>
<tr>
<td class="tbltd1"><code>amount</code></td>
<td class="tbltd1"><code>DECIMAL(6,2)</code></td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&nbsp;</td>
</tr>
<tr>
<td class="tbltd1"><code>date_created</code></td>
<td class="tbltd1"><code>TIMESTAMP</code></td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1"><code>CURRENT_TIMESTAMP</code></td>
</tr>
<tr>
<td class="tbltd1"><code>confirmation_number</code></td>
<td class="tbltd1"><code>INT</code></td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1"><code>&nbsp;</code></td>
</tr>
</tbody>
</table>
<h4>product</h4>
<table class="margin-around">
<tbody>
<tr>
<th class="tblheader" scope="col">Column</th>
<th class="tblheader" scope="col">Datatype</th>
<th class="tblheader" scope="col">PK</th>
<th class="tblheader" scope="col">NN</th>
<th class="tblheader" scope="col">UN</th>
<th class="tblheader" scope="col">AI</th>
<th class="tblheader" scope="col">Default</th>
</tr>
<tr>
<td class="tbltd1"><code>id</code></td>
<td class="tbltd1"><code>INT</code></td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&nbsp;</td>
</tr>
<tr>
<td class="tbltd1"><code>name</code></td>
<td class="tbltd1"><code>VARCHAR(45)</code></td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&nbsp;</td>
</tr>
<tr>
<td class="tbltd1"><code>price</code></td>
<td class="tbltd1"><code>DECIMAL(5,2)</code></td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&nbsp;</td>
</tr>
<tr>
<td class="tbltd1"><code>description</code></td>
<td class="tbltd1"><code>TINYTEXT</code></td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&nbsp;</td>
</tr>
<tr>
<td class="tbltd1"><code>last_update</code></td>
<td class="tbltd1"><code>TIMESTAMP</code></td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1">&nbsp;</td>
<td class="tbltd1"><code>CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP</code></td>
</tr>
</tbody>
</table>
<p class="tips">For details on the <code>TIMESTAMP</code> data type, see the MySQL Reference Manual:
<a href="http://dev.mysql.com/doc/refman/5.1/en/timestamp.html" target="_blank">10.3.1.1. TIMESTAMP Properties</a>.</p>
<br>
When you finish, your canvas will look similar to the following.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/affablebean-tables.png"
class="margin-around b-all" alt="'customer', 'category', 'product', and 'order' tables displayed on EER canvas"
title="Use the Table editor to add columns to all tables on canvas"></li>
</ol>
<h3 id="identifyRelationships">Identifying Relationships</h3>
<p>So far, the entity-relationship diagram contains several entities, but lacks
any relationships between them. The data model that we are creating must
also indicate whether objects are aware of (i.e., contain references to) one
another. If one object contains a reference to another object, this is known
as a <em>unidirectional</em> relationship. Likewise, if both objects refer to
each other, this is called a <em>bidirectional</em> relationship.</p>
<p>References correlate to foreign keys in the database schema. You will note
that, as you begin linking tables together, foreign keys are added as new
columns in the tables being linked.</p>
<p>Two other pieces of information are also commonly relayed in an ERD:
<em>cardinality</em> (i.e., multiplicity) and <em>ordinality</em> (i.e.,
optionality). These are discussed below, as you begin adding relationships
to entities on the canvas. In order to complete the ERD, you essentially
need to create two <em>one-to-many</em> relationships, and one
<em>many-to-many</em> relationship. Details follow.</p>
<ul>
<li><a href="#oneToMany">Creating One-To-Many Relationships</a></li>
<li><a href="#manyToMany">Creating Many-To-Many Relationships</a></li>
</ul>
<h4 id="oneToMany">Creating One-To-Many Relationships</h4>
<p>Examine the four objects currently on the canvas while considering the
business problem. You can deduce the following two <em>one-to-many</em>
relationships:</p>
<ul>
<li>A category must contain one or more products</li>
<li>A customer must have placed one or more orders</li>
</ul>
<p>Incorporate these two relationships into the ERD. You can download a copy
of the MySQL Workbench project that contains the four entities required
for the following steps:
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252Faffablebean.mwb">affablebean.mwb</a>.</p>
<ol>
<li>In the left margin, click the 1:n Non-Identifying Relationship (
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/one-many-btn.png"
class="b-all" alt="1:n Non-Identifying Relationship button"> ) button.
This enables you to create a <em>one-to-many</em> relationship.</li>
<li>Click the <code>product</code> table, then click the <code>category</code>
table. The first table you click will contain the foreign key reference
to the second table. Here, we want the <code>product</code> table to
contain a reference to <code>category</code>. In the image below, you
see that a new column, <code>category_id</code>, has been added to the
<code>product</code> table, and that a foreign key index,
<code>fk_product_category</code> has been added to the table's indexes.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/product-category-relationship.png"
class="margin-around b-all" alt="'Product-category relationship displayed on EER canvas"
title="A one-to-many relationship is defined between the category and product objects">
<br><br>
Since foreign keys must be of the same data type as the columns they reference,
notice that <code>category_id</code> is of type <code>TINYINT</code>, similar to
the <code>category</code> table's primary key.
<br><br>
<span class="tips">The entity-relationship diagram in this tutorial uses
<a href="http://en.wikipedia.org/wiki/Entity-relationship_model#Crow.27s_Foot_Notation" target="_blank">Crow's
Foot</a> notation. You can alter the relationship notation in WorkBench by
choosing Model &gt; Relationship Notation.</span></li>
<li>Double-click the relationship (i.e., click the dashed line between the two
entities). The Relationship editor opens in the bottom region of the interface.</li>
<li>Change the default caption to '<code>belongs to</code>'. In other words,
&quot;product x belongs to category y.&quot; Note that this is a <em>unidirectional</em>
relationship: A <code>product</code> object contains a reference to the
category it belongs to, but the related <code>category</code> object does
not contain any references to the products it contains.</li>
<li>Click the Foreign Key tab in the Relationship editor. You see the following display.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/foreign-key-tab.png"
class="margin-around b-all" alt="'Relationship editor - Foreign Key tab"
title="Use the Foreign Key tab to modify a relationship's ordinality and cardinality">
<br>
Under the Foreign key tab, you can modify a relationship's:
<ul style="margin: 5px 0 0 -.7em">
<li><strong>cardinality:</strong> whether the relationship between two objects
is <em>one-to-one</em> or <em>one-to-many</em>.</li>
<li><strong>ordinality:</strong> whether a reference between entities must
exist in order to maintain the integrity of the model. (Toggle the Mandatory
checkbox for either side.)</li>
<li><strong>type:</strong> (i.e., <em>identifying</em> or <em>non-identifying</em>).
A non-identifying relationship, such as this one, refers to the fact
that the child object (<code>product</code>) can be identified independently
of the parent (<code>category</code>). An identifying relationship
means that the child cannot be uniquely identified without the parent.
An example of this is demonstrated later, when you create a many-to-many
relationship between the <code>product</code> and <code>order</code> tables.</li>
</ul></li>
<li>Click the 1:n Non-Identifying Relationship (
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/one-many-btn.png"
class="b-all" alt="1:n Non-Identifying Relationship button"> ) button. In the following
steps, you create a <em>one-to-many</em> relationship between the <code>customer</code>
and <code>customer_order</code> objects.</li>
<li>Click the <code>order</code> table first (this table will contain the foreign key),
then click the <code>customer</code> table. A relationship is formed between the two
tables.</li>
<li>Click the link between the two tables, and in the Relationship editor that displays,
change the default caption to '<code>is placed by</code>'. The relationship now
reads, &quot;customer order x is placed by customer y.&quot;
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/order-customer-relationship.png"
class="margin-around b-all" alt="'Order-customer relationship displayed on EER canvas"
title="A one-to-many relationship is defined between the customer and order objects">
<br><br>
<p class="tips">You can click and drag tables on the canvas into whatever position
makes the most sense for your model. In the image above, the <code>order</code>
table has been moved to the left of <code>customer</code>.</p>
</li>
</ol>
<h4 id="manyToMany">Creating Many-To-Many Relationships</h4>
<p><em>Many-to-many</em> relationships occur when both sides of a relationship can have
numerous references to related objects. For example, imagine the Affable Bean business
offered products that could be listed under multiple categories, such as cherry ice
cream, sausage rolls, or avocado souffl&eacute;. The data model would have to account
for this by including a <em>many-to-many</em> relationship between <code>product</code>
and <code>category</code>, since a category contains multiple products, and a product
can belong to multiple categories.</p>
<p>In order to implement a <em>many-to-many</em> relationship in a database, it is necessary
to break the relationship down into two <em>one-to-many</em> relationships. In doing so,
a third table is created containing the primary keys of the two original tables. The
<code>product</code> - <code>category</code> relationship described above might look as
follows in the data model.</p>
<div class="indent">
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/many-to-many.png"
class="margin-around b-all" alt="'Product-category many-to-many relationship displayed on EER canvas"
title="A many-to-many relationship is depicted as two one-to-many relationships">
</div>
<p>Now, consider how the application will persist customer orders. The <code>customer_order</code>
entity already contains necessary properties, such as the date it is created, its confirmation
number, amount, and a reference to the customer who placed it. However, there currently is no
indication of the products contained in the order, nor their quantities. You can resolve this
by creating a <em>many-to-many</em> relationship between <code>customer_order</code> and
<code>product</code>. This way, to determine which products are contained in a given order,
the application's business logic can query the new table that arises from the many-to-many
relationship, and search for all records that match an <code>order_id</code>. Because customers
can specify quantities for products in their shopping carts, we can also add a <code>quantity</code>
column to the table.</p>
<ol>
<li>In the left margin, click the n:m Identifying Relationship (
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/many-many-btn.png"
class="b-all" alt="n:m Identifying Relationship button"> ) button.
This enables you to create a <em>many-to-many</em> relationship.</li>
<li>Click the <code>customer_order</code> table, then click the <code>product</code>
table. A new table appears, named <code>customer_order_has_product</code>.
<br><br>
<p class="tips">Recall that an <em>identifying relationship</em> means that
the child cannot be uniquely identified without the parent. Identifying
relationships are indicated on the Workbench canvas by a solid line linking
two tables. Here, the <code>customer_order_has_product</code> table forms
an identifying relationship with its two parent tables, <code>customer_order</code>
and <code>product</code>. A record contained in the <code>customer_order_has_product</code>
table requires references from both tables in order to exist.</p></li>
<li>Arrange the tables according to the following image. The <em>many-to-many</em>
relationship is highlighted below.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/many-to-many-order-product.png"
class="margin-around b-all" alt="ERD containing a many-to-many relationship"
title="The 'customer_order_has_product' table contains two foreign keys to the order and product tables">
<br>
The new <code>customer_order_has_product</code> table contains two foreign
keys, <code>fk_customer_order_has_product_customer_order</code> and
<code>fk_customer_order_has_product_product</code>, which reference the
primary keys of the <code>customer_order</code> and <code>product</code>
tables, respectively. These two foreign keys form a composite primary key
for the <code>customer_order_has_product</code> table.</li>
<li>Change the name of the new <code>customer_order_has_product</code> table to
'<code>ordered_product</code>'. Double-click the <code>customer_order_has_product</code>
table to open the Table editor. Enter <code>ordered_product</code> into the Name
field.</li>
<li>Rename the foreign key indexes to correspond to the new table name. In the
<code>ordered_product</code>'s Table editor, click the Foreign Keys tab. Then,
click into both foreign key entries and replace '<code>customer_order_has_product</code>'
with '<code>ordered_product</code>'. When you finish, the two entries should read:
<ul style="margin: 5px 0 0 -.7em">
<li><code>fk_<strong>ordered_product</strong>_customer_order</code></li>
<li><code>fk_<strong>ordered_product</strong>_product</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/ordered-product-foreign-key.png"
title="Rename the foreign key indexes under the Foreign Keys tab in the Table editor"
class="margin-around b-all" alt="Foreign Keys tab in Table editor"></li>
<li>Double-click the lines between the two objects and delete the default captions
in the Relationship editor.</li>
<li>Create a <code>quantity</code> column in the <code>ordered_product</code>
table. To do so, click the Columns tab in the <code>ordered_product</code>'s
Table editor. Enter the following details.
<table class="margin-around">
<tbody>
<tr>
<th class="tblheader" scope="col">Column</th>
<th class="tblheader" scope="col">Datatype</th>
<th class="tblheader" scope="col">NN (Not Null)</th>
<th class="tblheader" scope="col">UN (Unsigned)</th>
<th class="tblheader" scope="col">Default</th>
</tr>
<tr>
<td class="tbltd1"><code>quantity</code></td>
<td class="tbltd1"><code>SMALLINT</code></td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1">&#10003;</td>
<td class="tbltd1"><code>1</code></td>
</tr>
</tbody>
</table>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/quantity-column.png"
class="margin-around b-all" alt="Table editor - 'order_has_product' table"
title="Add a 'quantity' column to the 'order_has_product' table">
</li>
</ol>
<p>You have now completed the ERD (entity-relationship diagram). This diagram
represents the data model for the <code>AffableBean</code> application.
As will later be demonstrated, the JPA entity classes that you create will
be derived from the entities existing in the data model.</p>
<div class="indent">
<div class="indent">
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/affablebean-erd.png"
class="margin-around b-all" alt="Complete AffableBean ERD"
title="ERD for the AffableBean application">
</div>
</div>
<p class="tips">Choose View &gt; Toggle Grid to disable the canvas grid.
You can also create notes for your diagram using the New Text Object (
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/text-object-btn.png"
alt="New Text Object button"> ) button in the left margin.</p>
</div>
<br>
<h2 id="forwardEngineer">Forward-Engineering to the Database</h2>
<p>To incorporate the data model you created into the MySQL database, you can employ
WorkBench to forward-engineer the diagram into an SQL script (more precisely,
a DDL script) to generate the schema. The wizard that you use also enables you
to immediately run the script on your database server.</p>
<p><strong>Important:</strong> Make sure your MySQL database server is running.
Steps describing how to setup and run the database are provided in
<a href="setup-dev-environ.html#communicate">Setting up the Development
Environment: Communicating with the Database Server</a>.</p>
<ol>
<li>Set the default storage engine used in Workbench to InnoDB. Choose Tools &gt;
Options (MySQLWorkbench &gt; Preferences on Mac) to open the Workbench
Preferences window. Click the MySQL tab, then select InnoDB as the default
storage engine.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/inno-db.png"
class="margin-around b-all" alt="Workbench Preferences window - MySQL tab"
title="Set the default storage engine to InnoDB" style="width:688px">
<br>
The <a href="http://www.innodb.com/" target="_blank">InnoDB</a> engine provides
foreign key support, which is utilized in this tutorial.</li>
<li>Click OK to exit the Preferences window.</li>
<li>Choose Database &gt; Forward Engineer from the main menu.</li>
<li>In the first panel of the Forward Engineer to Database wizard, select
'<code>DROP Objects Before Each CREATE Object</code>', and '<code>Generate
DROP SCHEMA</code>'.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/forward-engineer-wzd.png"
class="margin-around b-all" style="width:688px" alt="Forward Engineer wizard"
title="Enable DROP options to be generated in the SQL script">
<br>
These <code>DROP</code> options are convenient for prototyping - if you need
to make changes to the schema or schema tables, the script will first delete
(i.e., <em>drop</em>) these items before recreating them. (If you attempt to
create items on the MySQL server that already exist, the server will flag an
error.)</li>
<li>Click Continue. In Select Objects to Forward Engineer panel, note that the
Export MySQL Table Objects option is selected by default. Click the Show
Filter button and note that all five tables in the <code>affablebean</code>
schema are included.</li>
<li>Click Continue. In the Review SQL Script panel, you can examine the SQL script
that has been generated based on the data model. Optionally, click Save to
File to save the script to a location on your computer.
<br><br>
<p class="notes"><strong>Note:</strong> In examining the script, you may notice
that the following variables are set at the top of the file:</p>
<div class="indent">
<pre class="examplecode" style="width:660px">
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';</pre>
<p>For an explanation of what these variables are, and their purpose in the script,
see the official Workbench manual:
<a href="http://dev.mysql.com/doc/workbench/en/workbench-faq.html" target="_blank">Chapter
11. MySQL Workbench FAQ</a>.</p></div></li>
<li>Click Continue. In the Connection Options panel, set the parameters for
connecting to the running MySQL server.
<ul style="margin: 5px 0 0 -.7em">
<li><strong>Hostname:</strong> <code>127.0.0.1</code> (<em>or <code>localhost</code></em>)</li>
<li><strong>Port:</strong> <code>3306</code></li>
<li><strong>Username:</strong> <code>root</code></li>
<li><strong>Password:</strong> <code>nbuser</code></li>
</ul>
(The parameters you set should correspond to those from <a href="setup-dev-environ.html#communicate">Setting up the Development Environment:
Communicating with the Database Server</a>.)</li>
<li>Click Execute. In the final panel of the wizard, you receive confirmation
that the wizard was able to connect to and execute the script successfully.</li>
<li>Click Close to exit the wizard.</li>
</ol>
<p>The <code>affablebean</code> schema is now created and exists on your MySQL server.
In the next step, you connect to the schema, or <em>database</em>, from the IDE. At
this stage you may ask, &quot;What's the difference between a schema and a database?&quot;
In fact, the MySQL command <code>CREATE SCHEMA</code> is a synonym for <code>CREATE
DATABASE</code>. (See <a href="http://dev.mysql.com/doc/refman/5.1/en/create-database.html" target="_blank">12.1.10.
CREATE DATABASE Syntax</a>.) Think of a schema as a blueprint that defines the contents
of the database, including tables, relationships, views, etc. A database implements the
schema by containing data in a way that adheres to the structure of the schema. This is
similar to the object-oriented world of Java classes and objects. A class defines an object.
When a program runs however, objects (i.e., class instances) are created, managed, and
eventually destroyed as the program runs its course.</p>
<br>
<h2 id="connectDB">Connecting to the Database from the IDE</h2>
<p>Now that the <code>affablebean</code> schema exists on your MySQL server, ensure
that you can view the tables you created in the ERD from the IDE's Services window.</p>
<p><strong>Important:</strong> Make sure that you have followed the steps outlined in
<a href="setup-dev-environ.html#communicate">Setting up the Development Environment:
Communicating with the Database Server</a>. This heading describes how to run the
MySQL database server, register it with the IDE, create a database instance, and
form a connection to the instance from the IDE.</p>
<ol>
<li>In the IDE, open the Services window (Ctrl-5; &#8984;-5 on Mac) and locate
the database connection node (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/db-connection-node.png"
alt="Database connection node"> ) for the <code>affablebean</code> database
instance you created in the <a href="setup-dev-environ.html#communicate">previous
tutorial unit</a>.</li>
<li>Refresh the connection to the <code>affablebean</code> database. To do so,
right-click the connection node and choose Refresh.</li>
<li>Expand the Tables node. You can now see the five tables defined by the schema.</li>
<li>Expand any of the table nodes. Each table contains the columns and indexes
that you created when working in MySQL Workbench.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/data-model/services-window-schema.png"
class="margin-around b-all" alt="Forward Engineer wizard"
title="Update the database connection to view schema tables"></li>
</ol>
<p>The IDE is now connected to a database that uses the schema you created for the
<code>AffableBean</code> application. From the IDE, you can now view any table
data you create in the database, as well as directly modify, add and delete data.
You will explore some of these options later, in <a href="#connect-db">Connecting
the Application to the Database</a>, after you've added sample data to the database.</p>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans E-commerce Tutorial - Designing the Data Model">Send
Us Your Feedback</a></div>
<br style="clear:both;">
<h2 id="seeAlsoDataModel">See Also</h2>
<div class="indent">
<h3>NetBeans Resources</h3>
<ul>
<li><a href="../../../articles/mysql.html" target="_blank">MySQL and NetBeans IDE</a></li>
<li><a href="../../ide/mysql.html" target="_blank">Connecting to a MySQL Database</a></li>
<li><a href="../../web/mysql-webapp.html" target="_blank">Creating a Simple Web Application Using a MySQL Database</a></li>
<li><a href="../../ide/database-improvements-screencast.html" target="_blank">Screencast: Database Support in NetBeans IDE</a></li>
</ul>
<h3>MySQL & Data Modeling Resources</h3>
<ul>
<li><a href="http://wb.mysql.com/" target="_blank">MySQL Workbench Blog</a></li>
<li><a href="http://forums.mysql.com/index.php?151" target="_blank">MySQL Workbench Forum</a></li>
<li><a href="http://dev.mysql.com/librarian/" target="_blank">The MySQL Community Librarian</a></li>
<li><a href="http://dev.mysql.com/doc/workbench/en/index.html" target="_blank">MySQL Workbench Reference Manual</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/" target="_blank">MySQL 5.1 Reference Manual</a></li>
<li><a href="http://en.wikipedia.org/wiki/Innodb" target="_blank">InnoDB</a> [Wikipedia]</li>
<li><a href="http://en.wikipedia.org/wiki/Database_model" target="_blank">Database Model</a> [Wikipedia]</li>
<li><a href="http://en.wikipedia.org/wiki/Data_modeling" target="_blank">Data Modeling</a> [Wikipedia]</li>
</ul>
</div>
<br>
<h2>References</h2>
<ol>
<li id="footnote1DataModel"><a href="#1DataModel" style="text-decoration:none">^</a> Data Definition
Language (DDL) is a subset of the SQL language and includes statements such as
<code>CREATE TABLE</code>, <code>DROP</code>, and <code>ALTER</code>. Other subsets
include Data Manipulation Language (DML), and Data Control Language (DCL). For
more information, see <a href="http://en.wikipedia.org/wiki/Data_Definition_Language" target="_blank">Data
Definition Language</a> [Wikipedia].</li>
</ol>
<br><br><br><br>
<h1 id="page-views-controller">The NetBeans E-commerce Tutorial - Preparing the Page Views and Controller Servlet</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Tutorial Contents</h4>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#design">Designing the Application</a></li>
<li><a href="#setup-dev-environ">Setting up the Development Environment</a></li>
<li><a href="#data-model">Designing the Data Model</a></li>
<li><strong>Preparing the Page Views and Controller Servlet</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#createProjectFiles">Creating Project Files</a></li>
<li><a href="#implementHTML">Implementing HTML and CSS content</a></li>
<li><a href="#view">Placing JSP Pages in WEB-INF</a></li>
<li><a href="#jspf">Creating a Header and Footer</a></li>
<li><a href="#dd">Adding a Directive to the Deployment Descriptor</a></li>
<li><a href="#controller">Creating the Controller Servlet</a></li>
<li><a href="#implement">Implementing the Controller Servlet</a></li>
<li><a href="#seeAlsoPageViewsController">See Also</a></li>
</ul></li>
<li><a href="#connect-db">Connecting the Application to the Database</a></li>
<li><a href="#entity-session">Adding Entity Classes and Session Beans</a></li>
<li><a href="#manage-sessions">Managing Sessions</a></li>
<li><a href="#transaction">Integrating Transactional Business Logic</a></li>
<li><a href="#language">Adding Language Support</a></li>
<li><a href="#security">Securing the Application</a></li>
<li><a href="#test-profile">Testing and Profiling</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ol>
</div>
</div>
<p><img src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" class="stamp"
alt="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"
title="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"></p>
<p>This tutorial unit demonstrates how to create project files in the IDE, and
introduces you to some of the facilities available for HTML and CSS development.
After creating necessary project files, you begin organizing the front-end of
the application. That is, you'll place JSP files in their proper locations
within the project structure, create a header and footer which will be applied
to all views, and set up the controller servlet to handle incoming requests.</p>
<p>In this unit, you also create a web deployment descriptor (<code>web.xml</code> file)
for the application. You can use the deployment descriptor to specify configuration
information which is read by the server during deployment. Although the
<a href="http://jcp.org/en/jsr/detail?id=315" target="_blank">Servlet 3.0 Specification</a>,
included in Java EE 6, enables you to use class annotations in place of XML, you may
still require the deployment descriptor to configure certain elements of your application.
Specifically, in this unit you add directives for the header and footer and specify
which files they will be applied to.</p>
<p>One of the goals of this tutorial unit is to create JSP pages that correspond to the
views specified in the application design. Referring back to the <a href="design.html#mockups">page
mockups</a> and <a href="design.html#business">process flow diagram</a>, you begin
implementing page layouts according to the mockups by creating <em>placeholders</em>
for all visual and functional components. This unit provides a guide for implementing
the layout of the welcome page. You can apply the outlined steps to create the other
pages on your own, or <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot1.zip">download
project snapshot 1</a>, which provides completed layouts for all pages.</p>
<p>You can view a live demo of the application that you build in this tutorial:
<a href="http://services.netbeans.org/AffableBean/" target="_blank">NetBeans E-commerce
Tutorial Demo Application</a>.</p>
<br style="clear:left">
<br>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html" target="_blank">NetBeans IDE</a></td>
<td class="tbltd1">Java bundle, 6.8 or 6.9</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank">Java Development Kit (JDK)</a></td>
<td class="tbltd1">version 6</td>
</tr>
<tr>
<td class="tbltd1"><a href="#glassFishPageViewsController">GlassFish server</a></td>
<td class="tbltd1">v3 or Open Source Edition 3.0.1</td>
</tr>
</tbody>
</table>
<p><strong class="notes">Notes:</strong></p>
<ul>
<li>The NetBeans IDE requires the Java Development Kit (JDK) to run properly.
If you do not have any of the resources listed above, the JDK should be
the first item that you download and install.</li>
<li>The NetBeans IDE Java Bundle includes Java Web and EE technologies, which are
required for the application you build in this tutorial.</li>
<li id="glassFishPageViewsController">The NetBeans IDE Java Bundle also includes the GlassFish
server, which you require for this tutorial. You could
<a href="http://glassfish.dev.java.net/public/downloadsindex.html" target="_blank">download
the GlassFish server independently</a>, but the version provided with the
NetBeans download has the added benefit of being automatically registered with
the IDE.</li>
</ul>
<br>
<h2 id="createProjectFiles">Creating Project Files</h2>
<p>To create new files for your project, access the IDE's File wizard. You can click
the New File (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/new-file-btn.png"
alt="New File button"> ) button, press Ctrl-N (&#8984;-N on Mac), or in the
Projects window, right-click the folder node that will contain the new file,
and choose New &gt; [file-type]. In the following sub-sections, create JSP
pages and a stylesheet for the project.</p>
<ul>
<li><a href="#jsp">Creating JSP Pages</a></li>
<li><a href="#css">Creating a Stylesheet</a></li>
</ul>
<div class="indent">
<h3 id="jsp">Creating JSP Pages</h3>
<p>Begin working in the project by creating JSP pages that correspond to the views
displayed in the <a href="design.html#business">process flow diagram</a>.</p>
<p>The <code>index.jsp</code> page that was generated by the IDE will become the
project's welcome page. Create JSP pages for the four remaining views and, for
now, place them in the project's webroot with <code>index.jsp</code>.</p>
<ol>
<li>Click the New File (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/new-file-btn.png"
alt="New File button"> ) button to open the File wizard.</li>
<li>Select the Web category, then select JSP and click Next.</li>
<li>Name the file '<code>category</code>'. Note that the Location field
is set to <code>Web Pages</code>, indicating that the file will be created
in the project's webroot. This corresponds to the project's <code>web</code>
folder, which you can later verify in the IDE's Files window.</li>
<li>Click Finish. The IDE generates the new JSP page and opens it in the editor.</li>
<li>Repeat steps 1 - 4 above to create the remaining <code>cart.jsp</code>,
<code>checkout.jsp</code>, <code>confirmation.jsp</code> pages.
<br><br>
When you finish, your Projects window will look as follows:
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/projects-win-views.png"
class="margin-around b-all" alt="Projects window displaying 'view' folder and JSP pages"
title="Views are contained in the 'WEB-INF/view/' folder">
</li>
</ol>
<h3 id="css">Creating a Stylesheet</h3>
<p>Create a CSS file to contain all styles specific to the application.</p>
<ol>
<li>In the Projects window, right-click the Web Pages node and choose New &gt; Folder.</li>
<li>In the New Folder wizard, name the folder '<code>css</code>' and click Finish.</li>
<li>Right-click the new <code>css</code> folder and choose New &gt; Cascading
Style Sheet. (If the Cascading Style Sheet item is not listed, choose Other.
In the File wizard, select the Web category, then select Cascading Style Sheet
and choose Next.)</li>
<li>Name the stylesheet <code>affablebean</code>, then click Finish.
<br><br>
When you finish, you'll see the <code>affablebean.css</code> file displayed
in your Projects window.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/projects-win-css.png"
class="margin-around b-all" alt="Projects window displaying 'affablebean.css' stylesheet"
title="Projects window displays new 'css' folder and stylesheet"></li>
</ol>
</div>
<br>
<h2 id="implementHTML">Implementing HTML and CSS content</h2>
<p>The purpose of this section is to design the page views so that they begin to
mirror the provided <a href="design.html#mockups">page mockups</a>. As such,
they'll serve as a scaffolding which you can use to insert dynamic content during
later stages of project development. To do so, you'll utilize the IDE's HTML
and CSS editors, along with several CSS support windows.</p>
<p class="notes"><strong>Browser compatibility note:</strong> This tutorial uses
Firefox 3 and <em>does not</em> guarantee that page view markup is compatible
with other modern browsers. Naturally, when working with front-end web technologies
(HTML, CSS, JavaScript) you would need take measures to ensure that your web
pages render properly in the browsers and browser versions that you expect visitors
to your site will be using (typically Internet Explorer, Firefox, Safari, Chrome,
and Opera). When working in the IDE, you can set the browser you want your application
to open in. Choose Tools &gt; Options (NetBeans &gt; Preferences on Mac), and under
the General tab in the Options window, select the browser you want to use from
the Web Browser drop-down. The IDE detects browsers installed to their default
locations. If a browser installed on your computer is not displayed, click the
Edit button and register the browser manually.</p>
<p>Preparing the display of your web pages is usually an iterative process which
you would fine-tune with regular feedback from the customer. The following steps
are designed to introduce you to the facilities provided by the IDE, and
demonstrate how to get started using the <a href="design.html#index">welcome
page mockup</a> as an example.</p>
<ol>
<li>In the Projects window, double-click <code>index.jsp</code> to open it in the
editor.</li>
<li>Begin by creating <code>&lt;div&gt;</code> tags for the main areas of the page.
You can create five tags altogether: four for main areas (header, footer,
left column, and right column), and the fifth to contain the others. Remove
any content within the <code>&lt;body&gt;</code> tags and replace with the
following. (New code is shown in <strong>bold</strong>.)
<pre class="examplecode">
&lt;body&gt;
<strong>&lt;div id=&quot;main&quot;&gt;
&lt;div id=&quot;header&quot;&gt;
header
&lt;/div&gt;
&lt;div id=&quot;indexLeftColumn&quot;&gt;
left column
&lt;/div&gt;
&lt;div id=&quot;indexRightColumn&quot;&gt;
right column
&lt;/div&gt;
&lt;div id=&quot;footer&quot;&gt;
footer
&lt;/div&gt;
&lt;/div&gt;</strong>
&lt;/body&gt;</pre></li>
<li>Add a reference to the stylesheet in the page's head, and change the title text.
<pre class="examplecode">
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
<strong>&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/affablebean.css&quot;&gt;</strong>
&lt;title&gt;<strong>The Affable Bean</strong>&lt;/title&gt;
&lt;/head&gt;</pre></li>
<li>Open the <code>affablebean.css</code> stylesheet in the editor. Begin creating
style rules for the <code>&lt;div&gt;</code> IDs you just created.
<ul style="margin: 5px 0 0 -.7em">
<li>Use the <code>width</code> and <code>height</code> properties to create
space for each area.</li>
<li>Use the <code>background</code> property to discern the areas when you
view the page.</li>
<li>In order to horizontally center the four areas in the page, you can include
<code>margin: 20px auto</code> to the <code>body</code> rule. (<code>20px</code>
applies to the top and bottom; <code>auto</code> creates equal spacing to
the left and right.) Then include <code>float: left</code> to the left and
right columns.</li>
<li>The footer requires <code>clear: left</code> so that its top border displays
after the bottom borders of any left-floating areas above it (i.e., the left
and right columns).</li>
</ul>
<pre class="examplecode">
body {
font-family: Arial, Helvetica, sans-serif;
width: 850px;
text-align: center;
margin: 20px auto;
}
#main { background: #eee }
#header {
height: 250px;
background: #aaa;
}
#footer {
height: 60px;
clear: left;
background: #aaa;
}
#indexLeftColumn {
height: 400px;
width: 350px;
float: left;
background: #ccc;
}
#indexRightColumn {
height: 400px;
width: 500px;
float: left;
background: #eee;
}</pre></li>
<li>Click the Run Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) button in the IDE's main toolbar. Project files that contain
changes are automatically saved, any Java code in the project compiles, the project is
packaged and deployed to GlassFish, and your browser opens to display the current state
of the welcome page.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/index-page.png"
class="margin-around b-all" alt="Welcome page displayed in browser" style="width:688px"
title="Run the project to view the current state of pages"></li>
<li>Now, begin creating placeholders for page components within each of the four visible areas.
Start with the header. Reviewing the <a href="design.html#index">welcome page mockup</a>, the
header should contain the following components:
<ul style="margin: 5px 0 0 -.7em">
<li>logo</li>
<li>logo text</li>
<li>shopping cart widget</li>
<li>language toggle</li>
</ul>
Make the following changes to the <code>index.jsp</code> file. (New code shown
in <strong>bold</strong>.)
<pre class="examplecode">
&lt;div id=&quot;header&quot;&gt;
<strong>&lt;div id=&quot;widgetBar&quot;&gt;
&lt;div class=&quot;headerWidget&quot;&gt;
[ language toggle ]
&lt;/div&gt;
&lt;div class=&quot;headerWidget&quot;&gt;
[ shopping cart widget ]
&lt;/div&gt;
&lt;/div&gt;
&lt;a href=&quot;#&quot;&gt;
&lt;img src=&quot;#&quot; id=&quot;logo&quot; alt=&quot;Affable Bean logo&quot;&gt;
&lt;/a&gt;
&lt;img src=&quot;#&quot; id=&quot;logoText&quot; alt=&quot;the affable bean&quot;&gt;</strong>
&lt;/div&gt;</pre>
In the above code, you use a <code>&lt;div id=&quot;widgetBar&quot;&gt;</code>
element to contain the the language toggle and shopping cart widget.
<br><br>
<div class="feedback-box float-left" style="width: 683px;">
<h3>NetBeans HTML Editor Support</h3>
<p>When you work in the editor, take advantage of the IDE's HTML support.
Aside from typical syntax highlighting that lets you differentiate
between tags, attributes, attribute values, and text, there are plenty
of other features.</p>
<p>When typing tags and attributes in the editor, you can invoke code-completion
and documentation support by pressing Ctrl-Space. The IDE presents a list
of suggestions which you can choose from, as well as a documentation window
that defines the selected item and provides code examples.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/documentation-popup.png"
class="margin-around b-all" title="Press Ctrl-Space to view code completion and documentation windows"
alt="Code completion and documentation windows displayed in editor"/>
<p>The IDE detects errors in your code and provides you with warnings, error
messages, and in some cases, suggestions. Warning messages are displayed
in yellow, while errors are shown in red. You can hover your pointer over
a designated area to view the message in a tooltip.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/html-hint.png"
class="margin-around b-all" title="Hover your pointer to view a tooltip warning"
alt="HTML warning displayed in editor"/>
<p>You can also take advantage of numerous keyboard shortcuts. Choose Help &gt;
Keyboard Shortcuts Card from the main menu.</p>
</div>
<br style="clear: both;"/></li>
<li>In the stylesheet, create rules for the new IDs and classes. Add the following rules
beneath the <code>header</code> rule. (New code shown in <strong>bold</strong>.)
<pre class="examplecode">
#header {
height: 250px;
background: #aaa;
}
<strong>#logo {
height: 155px;
width: 155px;
float: left;
margin-left: 30px;
margin-top: -20px;
}
#logoText {
float: left;
margin: 20px 0 0 70px;
/* font styles apply to text within alt tags */
font-family: 'American Typewriter', Courier, monospace;
font-size: 50px;
color: #333;
}
#widgetBar {
height: 50px;
width: 850px;
float: right;
background: #ccc;
}
.headerWidget {
width: 194px;
margin: 20px 2px;
font-size: small;
float: right;
line-height: 25px;
background: #aaa;
}</strong></pre>
For the <code>logo</code> rule, you apply <code>margin-left</code> and
<code>margin-top</code> properties to position the component on the page.
<br><br>
If there are properties in the above code that you are unfamiliar with,
position your cursor on the given property and press Ctrl-Space to invoke
a pop-up window that provides documentation support.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/css-doc-support.png"
class="margin-around b-all" alt="Documentation window for CSS support"
title="Press Ctrl-Space on a CSS property to invoke documentation support">
<br>
<p class="tips">To see how a property is affecting your page, you can comment
it out, then refresh the page in the browser. To comment out code, position
your cursor on a line, or highlight a block of code, then press Ctrl-/
(&#8984;-/ on Mac).</p></li>
<li>Save (Ctrl-S; &#8984;-S on Mac) the <code>index.jsp</code> and <code>affablebean.css</code>
files, then switch to your browser and refresh the page to view its current state.
<br><br>
<p class="notes"><strong>Note:</strong> The IDE's 'Deploy on Save' facility is automatically
activated for Java web projects. This means that every time you save a file, the file is
automatically compiled (i.e., if it is a Java class or JSP page) and the project is newly
packaged and deployed to your server. Therefore, when you make HTML or CSS changes, you
don't need to explicitly rerun the project to view the updated version in a browser. Simply
save your file(s), then switch to the browser and refresh the page.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/index-page2.png"
class="margin-around b-all" alt="Welcome page displayed in browser" style="width:688px"
title="Placeholders for header are visible when running project">
<br>
By following the previous steps, you are probably able to see a pattern emerging.
For each area on the page, you perform three steps.
<ol style="list-style:lower-alpha; margin-top:5px">
<li>Create the structure in HTML.</li>
<li>Create a set of styles to define the appearance.</li>
<li>View the page to examine the results of your changes.</li>
</ol>
Following these three steps, let's implement the components in the remaining areas.</li>
<li>Create placeholders for components in the right column. According to the
<a href="design.html#index">welcome page mockup</a>, the right column contains
four evenly-spaced boxes.
<br><br>
Create the structure for the four boxes. Insert the following code between
the <code>&lt;div id=&quot;indexRightColumn&quot;&gt;</code> tags. (New code shown
in <strong>bold</strong>.)
<pre class="examplecode">
&lt;div id=&quot;indexRightColumn&quot;&gt;
<strong>&lt;div class=&quot;categoryBox&quot;&gt;
&lt;a href=&quot;#&quot;&gt;
&lt;span class=&quot;categoryLabelText&quot;&gt;dairy&lt;/span&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;categoryBox&quot;&gt;
&lt;a href=&quot;#&quot;&gt;
&lt;span class=&quot;categoryLabelText&quot;&gt;meats&lt;/span&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;categoryBox&quot;&gt;
&lt;a href=&quot;#&quot;&gt;
&lt;span class=&quot;categoryLabelText&quot;&gt;bakery&lt;/span&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;categoryBox&quot;&gt;
&lt;a href=&quot;#&quot;&gt;
&lt;span class=&quot;categoryLabelText&quot;&gt;fruit & veg&lt;/span&gt;
&lt;/a&gt;
&lt;/div&gt;</strong>
&lt;/div&gt;</pre></li>
<li>Add style rules to <code>affablebean.css</code> for the new <code>categoryBox</code>
and <code>categoryLabelText</code> classes. (New code shown in <strong>bold</strong>.)
<pre class="examplecode">
#indexRightColumn {
height: 400px;
width: 500px;
float: left;
background: #eee;
}
<strong>.categoryBox {
height: 176px;
width: 212px;
margin: 21px 14px 6px;
float: inherit;
background: #ccc;
}
.categoryLabelText {
line-height: 150%;
font-size: x-large;
}</strong></pre>
<div class="feedback-box float-left" style="width: 683px;">
<h3>NetBeans CSS Support</h3>
<p>When working in stylesheets, there are two windows that can be
particularly helpful. The CSS Preview enables you to view style
rules as they are rendered in a browser. To open the CSS Preview,
choose Window &gt; Other &gt; CSS Preview from the main menu.
When you place your cursor within a style rule in the editor,
the CSS Preview automatically refreshes to display sample text
according to the properties defined in the rule.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/css-preview.png"
class="margin-around b-all" alt="CSS Preview"
title="Use the CSS Preview to view rendered style rules">
<p>The CSS Style Builder is useful if you do not like to code style
rules by hand. To open the CSS Style Builder, choose Window &gt;
Other &gt; CSS Style Builder from the main menu. Using this interface,
you can construct rules by choosing properties and values from a
graphical interface.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/style-builder.png"
class="margin-around b-all" alt="CSS Style Builder"
title="Use the CSS Style Builder to construct style rules">
<p>Like the CSS Preview, the Style Builder is synchronized with the editor.
When you make a selection in the Style Builder, the style rule is
automatically updated in the editor. Likewise, when you type changes
into the editor, the selections in the Style Builder are instantly
updated.</p>
</div>
<br style="clear: both;"/></li>
<li>Save (Ctrl-S; &#8984;-S on Mac) the <code>index.jsp</code> and <code>affablebean.css</code>
files, then switch to your browser and refresh the page to view its current state.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/index-page3.png"
class="margin-around b-all" alt="Welcome page displayed in browser" style="width:688px"
title="Placeholders for header and right-column are visible when running project">
<li>The left column and footer only require placeholders for static text, so let's
implement both simultaneously.
<br><br>
Insert the following code between the <code>&lt;div id=&quot;indexLefttColumn&quot;&gt;</code>
and <code>&lt;div id=&quot;footer&quot;&gt;</code> tags. (New code shown in <strong>bold</strong>.)
<pre class="examplecode">
&lt;div id=&quot;indexLeftColumn&quot;&gt;
<strong>&lt;div id=&quot;welcomeText&quot;&gt;
&lt;p&gt;[ welcome text ]&lt;/p&gt;
&lt;/div&gt;</strong>
&lt;/div&gt;
...
&lt;div id=&quot;footer&quot;&gt;
<strong>&lt;hr&gt;
&lt;p id=&quot;footerText&quot;&gt;[ footer text ]&lt;/p&gt;</strong>
&lt;/div&gt;</pre></li>
<li>Make changes to the <code>affablebean.css</code> stylesheet. It's not necessary
to account for all new IDs and classes - you can fine-tune the appearance at a
later point when you receive text and images from the customer.
<br><br>
The horizontal rule (<code>&lt;hr&gt;</code>) tag runs the full length of its
containing element (<code>&lt;div id=&quot;footer&quot;</code>). Therefore,
to shorten it in accordance with the mockup image, you can adjust the width of
<code>&lt;div id=&quot;footer&quot;&gt;</code>. (New code shown in <strong>bold</strong>.)
<pre class="examplecode">
#footer {
height: 60px;
<strong>width: 350px;</strong>
clear: left;
background: #aaa;
}
<strong>hr {
border: 0;
background-color: #333;
height: 1px;
margin: 0 25px;
width: 300px;
}</strong></pre></li>
<li>Save (Ctrl-S; &#8984;-S on Mac) the <code>index.jsp</code> and <code>affablebean.css</code>
files, then switch to your browser and refresh the page to view its current state.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/index-page4.png"
class="margin-around b-all" alt="Welcome page displayed in browser" style="width:688px"
title="Placeholders for left column and footer are visible" id="welcome-page">
<br>
The welcome page is complete. You've created all necessary placeholders for
components that will exist on the page.
</li>
</ol>
<p>You've now completed the initial design of the application's welcome page. All
placeholders for page components exist. Later in the tutorial, when you begin
to apply dynamic logic to the page views, you can simply plug JSTL and EL
expressions into these placeholders.</p>
<p>The task remains for you to implement the initial design for the other pages
based on the <a href="design.html#mockups">mockups</a>. To accomplish this,
follow the pattern outlined above, namely:</p>
<ol style="margin: 5px 0 0 -.7em">
<li>Create <code>&lt;div&gt;</code> tags for the main page areas.</li>
<li>Iterate through each area and perform three steps:
<ol style="margin: 5px 0 0 -1.4em; list-style-type: lower-alpha">
<li>Create the structure in HTML.</li>
<li>Create a set of styles to define the appearance.</li>
<li>View the page to examine the results of your changes.</li>
</ol></li>
</ol>
<p>Be sure to take advantage of the HTML and CSS support that the IDE provides for you.
Some <a href="#tipsTricks">tips and tricks</a> are outlined below. If you just want
to grab the code for the remaining pages and proceed with the tutorial, you can
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot1.zip">download
snapshot 1 of the <code>AffableBean</code> project</a>. Images of initial mockup
implementations for the remaining pages are included here.</p>
<div class="indent">
<h4 id="categoryPage">category page</h4>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/category-page.png"
class="margin-around b-all" alt="Category page displayed in browser" style="width:708px"
title="Placeholders implemented for category page">
<br><br>
<h4 id="cartPage">cart page</h4>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/cart-page.png"
class="margin-around b-all" alt="Cart page displayed in browser" style="width:708px"
title="Placeholders implemented for cart page">
<br><br>
<h4 id="checkoutPage">checkout page</h4>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/checkout-page.png"
class="margin-around b-all" alt="Checkout page displayed in browser" style="width:708px"
title="Placeholders implemented for checkout page">
<br><br>
<h4>confirmation page</h4>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/confirmation-page.png"
class="margin-around b-all" alt="Confirmation page displayed in browser" style="width:708px"
title="Placeholders implemented for checkout page">
<br><br>
<p class="notes"><strong>Note:</strong> The background colors for each page area only
serve to help you position elements while developing the application. Eventually,
you'll want to remove them from the stylesheet and apply a background color more
suitable for the application. You can do this by adjusting the background rule for
the <code>main</code> class:</p>
<div class="indent">
<pre class="examplecode">#main { background: #f7f7e9 }</pre>
</div>
<h3 id="tipsTricks">Tips and Tricks</h3>
<p>The IDE's editor provides many facilities that help you to work more efficiently.
If you familiarize yourself with keyboard shortcuts and buttons in the editor
toolbar, you can increase your productivity. The following list of tips applies
to the editor for HTML and CSS files. To view more keyboard shortcuts, open the
IDE's Keyboard Shortcuts Card by choosing Help &gt; Keyboard Shortcuts Card from
the main menu.</p>
<ul style="margin: 5px 0 0 -.7em">
<li><strong>Code completion:</strong> When you type in tags and attributes, suggestions
for code completion automatically appear in a pop-up box. Pressing Enter completes
the suggested tag.</li>
<li><strong>Format your code:</strong> Right-click in the editor and choose Format.</li>
<li><strong>Toggle line numbers:</strong> Right-click in the left margin and choose
Show Line Numbers.</li>
<li><strong>Find occurrences:</strong> Highlight a block of text, and press Ctrl-F
(&#8984;-F on Mac). All matches become highlighted in the editor. To toggle
highlighting, press the Toggle Highlight Search (
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/toggle-highlight.png"
alt="Toggle Highlight Search button" class="b-all"> ) button (Ctrl-Shift-H)
in the editor's toolbar.</li>
<li><strong>Create a bookmark:</strong> Press the Toggle Bookmark (
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/toggle-bookmark.png"
alt="Toggle Bookmark button" class="b-all"> ) button (Ctrl-Shift-M) to
create a bookmark in the editor's left margin. Wherever you are in the file,
you can then jump to the bookmark by pressing the Previous/Next Bookmark
buttons in the editors's toolbar.</li>
<li><strong>Copy a code snippet up or down:</strong> Highlight a code snippet,
then press Ctrl-Shift-Up/Down.</li>
<li><strong>Highlight opening and closing tags:</strong> Place your cursor on either
the opening or closing tag, and both are highlighted in yellow.</li>
</ul>
</div>
<br>
<h2 id="view">Placing JSP Pages in WEB-INF</h2>
<p>Looking back at the <a href="design.html#mockups">page mockups</a> that were created,
you can see that the <a href="design.html#index">welcome page</a> should look the same
whenever it is requested, for whomever requests it. That is, the content that displays
on the welcome page is not determined by a user's <em>session</em>. (Sessions are
discussed in Unit 8, <a href="#manage-sessions">Managing Sessions</a>.) Notice
however that all other pages do need some form of user-specific information to display
properly. For example, the <a href="design.html#category">category page</a> requires
that the user select a category in order to display, and the <a href="design.html#cart">cart
page</a> needs to know all items currently held in a shopper's cart. These pages will
not render properly if the server isn't able to associate user-specific information with
an incoming request. Therefore, we do not want these pages to be accessed directly from
a browser's address bar. The project's <code>WEB-INF</code> folder can be used for this
purpose: any resources contained in the <code>WEB-INF</code> folder are not directly
accessible from a browser.</p>
<p>Create a new folder named <code>view</code>, and place it in the <code>WEB-INF</code>
folder. Then move all JSP pages other than the welcome page into this new folder.</p>
<ol>
<li>In the Projects window, right-click the WEB-INF node and choose New &gt; Folder.</li>
<li>In the New Folder wizard, name the folder <code>view</code> and click Finish.
Notice that a new folder node appears in the Projects window.</li>
<li>Move the <code>category.jsp</code>, <code>cart.jsp</code>, <code>checkout.jsp</code>,
and <code>confirmation.jsp</code> pages into the <code>view</code> folder.
<br><br>
You can do this by clicking on <code>cart.jsp</code> to select it, then Shift-clicking
on <code>confirmation.jsp</code>. This selects the four files. Then, with the four
files selected, click and drag them into the <code>WEB-INF/view</code> folder.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/view-folder.png"
class="margin-around b-all" alt="Projects window displaying JSP pages being dragged into 'view' folder"
title="Click and drag the JSP pages into the 'WEB-INF/view/' folder"></li>
</ol>
<p>To demonstrate that these pages are no longer accessible from a browser, click the
Run Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) button to run the project. When the application displays in
your browser, enter the full path to any of these files in the address bar. For example,
type in:</p>
<div class="indent">
<pre class="examplecode" style="width:700px">http://localhost:8080/AffableBean/WEB-INF/view/category.jsp</pre>
</div>
<p>You receive an HTTP Status 404 message, indicating that the resource is not available.</p>
<br>
<h2 id="jspf">Creating a Header and Footer</h2>
<p>Looking at the <a href="design.html#mockups">page mockups</a>, it is easy to see
that all of the five views share identical content; at the top, they contain the
company logo, a language toggle, and other widgets associated with shopping cart
functionality. At the bottom, they contain some text with Privacy Policy and
Contact links. Rather than including this code in each page source file, we can
factor it out into two JSP fragments: a header and a footer. We'll then include
the fragment files into page views whenever they need to be rendered.</p>
<p>For these fragments, let's create a new folder named <code>jspf</code>, and place
it within <code>WEB-INF</code>.</p>
<ol>
<li>In the Projects window, right-click the WEB-INF node and choose New &gt; Folder.</li>
<li>In the New Folder wizard, name the folder <code>jspf</code> and click Finish.
<br><br>
<p class="tips">Menu items provided by the IDE are often context-sensitive.
For example, because you right-clicked the WEB-INF node, when the New Folder
wizard displayed, <code>web/WEB-INF</code> was automatically entered in the
Parent Folder field. Likewise, when you right-click a node in the Projects
window and choose New, the list of file types is partially determined by
your previous selections.</p>
</li>
<li>Create two JSP segments: <code>header.jspf</code> and <code>footer.jspf</code>.
To do so, right-click the newly created <code>jspf</code> folder and choose New
&gt; JSP. In the New JSP wizard, enter the file name, and under Options, select
the Create as a JSP Segment option, then click Finish.
<br><br>
When you finish, you'll see <code>header.jspf</code> and <code>footer.jspf</code>
displayed in your Projects window:
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/projects-win-jspf.png"
class="margin-around b-all" alt="Projects window displaying JSP fragments"
title="Header and footer JSP fragments are displayed in the project">
<br><br>
Now, you can copy the header code from any of the JSP pages and paste it into the
<code>header.jspf</code> file. Likewise, you can copy the footer code from any of
the JSP pages and paste it into the <code>footer.jspf</code> file. When you finish
this task, you can remove the header and footer code from all of the JSP pages.</li>
<li>Copy the header code from any of the JSP pages and paste it into the
<code>header.jspf</code> file. The header should include the page doctype
and the opening <code>&lt;html&gt;</code>, <code>&lt;head&gt;</code>, and
<code>&lt;body&gt;</code> tags through to the closing tag for the
<code>&lt;div id=&quot;header&quot&gt;</code> element. Be sure to include
placeholders for the shopping cart widget, language toggle, and 'proceed to
checkout' button used along the top of page views. After you paste code into
<code>header.jspf</code>, the file will look as follows.
<pre class="examplecode">
&lt;%@page contentType=&quot;text/html&quot; pageEncoding=&quot;UTF-8&quot;%&gt;
&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;
&quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/affablebean.css&quot;&gt;
&lt;title&gt;The Affable Bean&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;main&quot;&gt;
&lt;div id=&quot;header&quot;&gt;
&lt;div id=&quot;widgetBar&quot;&gt;
&lt;div class=&quot;headerWidget&quot;&gt;
[ language toggle ]
&lt;/div&gt;
&lt;div class=&quot;headerWidget&quot;&gt;
[ checkout button ]
&lt;/div&gt;
&lt;div class=&quot;headerWidget&quot;&gt;
[ shopping cart widget ]
&lt;/div&gt;
&lt;/div&gt;
&lt;a href=&quot;#&quot;&gt;
&lt;img src=&quot;#&quot; id=&quot;logo&quot; alt=&quot;Affable Bean logo&quot;&gt;
&lt;/a&gt;
&lt;img src=&quot;#&quot; id=&quot;logoText&quot; alt=&quot;the affable bean&quot;&gt;
&lt;/div&gt;</pre></li>
<li>Copy the footer code from any of the JSP pages and paste it into the <code>footer.jspf</code>
file. The footer code should include the <code>&lt;div id=&quot;footer&quot;&gt;</code>
element, through to the closing <code>&lt;html&gt;</code> tag. After you paste code into
<code>footer.jspf</code>, the file will look as follows.
<pre class="examplecode">
&lt;div id=&quot;footer&quot;&gt;
&lt;hr&gt;
&lt;p id=&quot;footerText&quot;&gt;[ footer text ]&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></li>
<li>Remove the header and footer code from all five JSP pages (<code>index.jsp</code>,
<code>category.jsp</code>, <code>cart.jsp</code>, <code>checkout.jsp</code>,
and <code>confirmation.jsp</code>).</li>
</ol>
<br>
<h2 id="dd">Adding a Directive to the Deployment Descriptor</h2>
<p>So far, you've placed views in their proper location and have factored out
common header and footer code into the <code>header.jspf</code> and
<code>footer.jspf</code> files. The application still needs to know which
pages the header and footer files will be applied to. You could add
<code>&lt;jsp:include&gt;</code> tags to each of the page views. Doing so
however would just reintroduce the code repetition which we've just made
efforts to eliminate. An alternative solution would be to create a <code>web.xml</code>
deployment descriptor, and add a JSP Property Group directive to specify
which page views the header and footer fragments should apply to.</p>
<ol>
<li>Press Ctrl-N (&#8984;-N on Mac) to open the New File wizard. Select the Web
category, then under File Types, select Standard Deployment Descriptor (web.xml).</li>
<li>Click Next. Note that the file is named <code>web.xml</code>, and that the
wizard will place it in the project's <code>WEB-INF</code> directory upon completion.</li>
<li>Click Finish. The <code>web.xml</code> file is created and added to the project.
The IDE's graphical interface for the deployment descriptor opens in the editor.
<br><br>
The interface is categorized by the areas that can be configured in a web application.
These areas are displayed as tabs in the editor toolbar, and include topics such
as Servlets, Filters, References, and Security. The XML tab displays the entire
source code for the file. Any changes you make in the graphical interface will
cause immediate updates to the deployment descriptor's source code, which you
can verify by switching to the XML tab. This is demonstrated in the following steps.</li>
<li>Click the Pages tab, then click the Add JSP Property Group button. The
Add JSP Property Group dialog opens.</li>
<li>Type in '<code>header and footer settings</code>' for the Description field.
Leave Display Name blank. Both the Display Name and Description fields are
optional.</li>
<li>For URL Patterns, specify the paths to the five views. Type in
'<code>/index.jsp</code>' and '<code>/WEB-INF/view/*</code>'. Separate the
two paths with a comma. (The '<code>*</code>' is a wildcard that represents
all files within the given folder.)
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/add-jsp-prop-group-dialog.png"
class="margin-around b-all" alt="Add JSP Property Group dialog"
title="Use the Add JSP Property Group dialog to specify &lt;jsp-config&gt; tags in the deployment descriptor"></li>
<li>Click OK. An entry is added to the JSP Properties Groups category in the Pages tab.</li>
<li>Switch back to the XML tab. Notice that the following code has been added to
the deployment descriptor.
<pre class="examplecode">
&lt;jsp-config&gt;
&lt;jsp-property-group&gt;
&lt;description&gt;header and footer settings&lt;/description&gt;
&lt;url-pattern&gt;/index.jsp&lt;/url-pattern&gt;
&lt;url-pattern&gt;/WEB-INF/view/*&lt;/url-pattern&gt;
&lt;/jsp-property-group&gt;
&lt;/jsp-config&gt;</pre>
<p class="notes"><strong>Note:</strong> You may need to add carriage returns
to the code so that it displays on multiple lines. You can right-click in
the editor and choose Format (Alt-Shift-F; Ctrl-Shift-F on Mac) to have the
code properly indented.</p></li>
<li>Switch to the Pages tab again, and in the Include Preludes and Include Codas
fields, enter the paths to the <code>header.jspf</code> and <code>footer.jspf</code>
files, respectively. You can click the Browse button and navigate to the files
in the provided dialog.
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/jsp-prop-groups.png"
title="Enter paths to the header and footer in the JSP Property Group" rel="lytebox">
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/jsp-prop-groups-small.png"
class="margin-around b-all" alt="JSP Property Group shown under Pages tab of web.xml" title="Click to enlarge"></a></li>
<li>Switch back to the XML tab. Note that the following code has been added.
(Changes in <strong>bold</strong>.)
<pre class="examplecode">
&lt;jsp-config&gt;
&lt;jsp-property-group&gt;
&lt;description&gt;header and footer settings&lt;/description&gt;
&lt;url-pattern&gt;/index.jsp&lt;/url-pattern&gt;
&lt;url-pattern&gt;/WEB-INF/view/*&lt;/url-pattern&gt;
<strong>&lt;include-prelude&gt;/WEB-INF/jspf/header.jspf&lt;/include-prelude&gt;
&lt;include-coda&gt;/WEB-INF/jspf/footer.jspf&lt;/include-coda&gt;</strong>
&lt;/jsp-property-group&gt;
&lt;/jsp-config&gt;</pre>
The above directive specifies that for all files found within the
given <code>url-pattern</code>s, the <code>header.jspf</code> file
will be prepended, and the <code>footer.jspf</code> file appended.
<br><br>
<p class="tips">To view the definitions of the above tags, as well as
all tags available to you in the web deployment descriptor, consult the
<a href="http://jcp.org/en/jsr/detail?id=315" target="_blank">Servlet
Specification</a>.</p></li>
<li>Run the application again (press F6; fn-F6 on Mac). You've already removed
the header and footer code from the <code>index.jsp</code> file, so you can
determine whether it is automatically being added when the file is requested.
<br><br>
You will see that the <a href="#welcome-page">welcome page displays as it
did previously</a>, with header and footer content included.</li>
</ol>
<br>
<h2 id="controller">Creating the Controller Servlet</h2>
<p>The controller servlet handles incoming requests by initiating any actions
needed to generate the model for the request, then forwarding the request
to the appropriate view. For a visual representation, refer back to the
<a href="design.html#mvcDiagram">MVC diagram for the AffableBean project</a>.</p>
<p>The IDE provides a Servlet wizard that enables you to define the servlet component
in a web application either by including the <code>@WebServlet</code> annotation
in the generated class, or by adding the necessary directives to the deployment
descriptor. In the following steps, you create the <code>ControllerServlet</code>
and define it in the application context using the
<a href="http://java.sun.com/javaee/6/docs/api/javax/servlet/annotation/WebServlet.html" target="_blank"><code>@WebServlet</code></a>
annotation.</p>
<ol>
<li>In the Projects window, right-click the <code>AffableBean</code> project
node and choose New &gt; Servlet.</li>
<li>In the wizard, type <code>ControllerServlet</code> in the Class Name field.</li>
<li>In the Package field, type <code>controller</code>. (The new package is
automatically created when you complete the wizard.)
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/servlet-wizard.png"
class="margin-around b-all" alt="Servlet wizard"
title="Use the Servlet wizard to create servlets for your project"></li>
<li>Click Next. Step 3 of the wizard lets you configure the servlet. Of primary
importance are the URL patterns that you need to specify. The patterns identify
the URLs that invoke the servlet. For example, if you enter '<code>/category</code>',
you are directing the servlet to handle a request that appears as follows.
<pre class="examplecode">http://localhost/AffableBean<strong>/category</strong></pre>
The URL patterns should correspond to the views and actions that a user can initiate.
Looking at the <a href="design.html#index">welcome page mockup</a>, a user should
be able to select a category. We can therefore associate the <code>/category</code>
URL with the action of clicking on a category image. Likewise, in the
<a href="design.html#category">category page</a>, users should be able to
add an item to the shopping cart. We can therefore specify <code>/addToCart</code>.</li>
<li>In the URL Pattern(s) field, type in '<code>/category, /addToCart, /viewCart</code>'.
Patterns are separated by commas. You can add more patterns directly in the servlet
class once it's created.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/servlet-wizard2.png"
class="margin-around b-all" alt="Servlet wizard, Step 3: Configure Servlet Deployment"
title="Configure servlet deployment directly in the wizard"></li>
<li>Click Finish. The IDE generates the <code>ControllerServlet</code> and opens it
in the editor. The servlet and URL patterns are included in the <code>@WebServlet</code>
annotation that appears above the class signature.
<pre class="examplecode">
<strong>@WebServlet(name=&quot;ControllerServlet&quot;, urlPatterns={&quot;/category&quot;, &quot;/addToCart&quot;, &quot;/viewCart&quot;})</strong>
public class ControllerServlet extends HttpServlet {</pre>
In the previous step, if you had chosen the '<code>Add information to deployment
descriptor (web.xml)</code>' option in the wizard, the following markup would have
been generated in the application's <code>web.xml</code> file instead.
<pre class="examplecode">
&lt;servlet&gt;
&lt;servlet-name&gt;ControllerServlet&lt;/servlet-name&gt;
&lt;servlet-class&gt;controller.ControllerServlet&lt;/servlet-class&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;ControllerServlet&lt;/servlet-name&gt;
&lt;url-pattern&gt;/category&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;ControllerServlet&lt;/servlet-name&gt;
&lt;url-pattern&gt;/addToCart&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;ControllerServlet&lt;/servlet-name&gt;
&lt;url-pattern&gt;/viewCart&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</pre></li>
<li>Add other URL patterns directly to the <code>@WebServlet</code> annotation's
<code>urlPatterns</code> element. The application requires more URL patterns
for other actions and views. You can type in the following patterns:
<ul class="toc" style="margin: 5px 0 0 -1em">
<li><code>/updateCart</code></li>
<li><code>/checkout</code></li>
<li><code>/purchase</code></li>
<li><code>/chooseLanguage</code></li>
</ul>
Be sure to separate each pattern with a comma. You can also reformat the
annotation as follows:
<pre class="examplecode">
@WebServlet(name=&quot;ControllerServlet&quot;,
urlPatterns = {&quot;/category&quot;,
&quot;/addToCart&quot;,
&quot;/viewCart&quot;<strong>,
&quot;/updateCart&quot;,
&quot;/checkout&quot;,
&quot;/purchase&quot;,
&quot;/chooseLanguage&quot;</strong>})</pre></li>
<li>Finally, include the <code>loadOnStartup</code> element so that the servlet
is instantiated and initialized when the application is deployed. A value of <code>0</code>
or greater will cause this to happen (<code>-1</code> is the default).
<pre class="examplecode">
@WebServlet(name=&quot;ControllerServlet&quot;,
<strong>loadOnStartup = 1,</strong>
urlPatterns = {&quot;/category&quot;,
&quot;/addToCart&quot;,
&quot;/viewCart&quot;,
&quot;/updateCart&quot;,
&quot;/checkout&quot;,
&quot;/purchase&quot;,
&quot;/chooseLanguage&quot;})</pre></li>
</ol>
<br>
<h2 id="implement">Implementing the Controller Servlet</h2>
<p>As previously stated, the controller servlet handles incoming requests by initiating
any actions needed to generate the model for the request, then forwarding the request
to the appropriate view. For a visual representation, refer back to the
<a href="design.html#mvcDiagram">MVC diagram for the AffableBean project</a>.</p>
<p>Looking at the generated code for the new <code>ControllerServlet</code>, you
can see that the IDE's servlet template employs a <code>processRequest</code>
method which is called by both <code>doGet</code> and <code>doPost</code>
methods. (You may need to expand the code fold by clicking the plus icon (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/code-fold-icon.png"
alt="Code fold icon"> ) in the editor's left margin to view these methods.) Because
this application differentiates between <code>doGet</code> and <code>doPost</code>,
you'll add code directly to these methods and remove the <code>processRequest</code>
method altogether.</p>
<div class="indent">
<div class="feedback-box float-left" style="width: 703px;">
<h3>Modifying File Templates with the IDE's Template Manager</h3>
<p>The IDE provides you with a basic template for any new file you create.
If the template is not optimal for your work patterns, you can alter it
using the IDE's Template Manager. The IDE provides a template for virtually
any file type.</p>
<p>For example, to modify the servlet template:</p>
<ol>
<li>Open the Template Manager by choosing Tools &gt; Templates from
the main menu.</li>
<li>Expand the Web category, then select the Servlet template.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/template-manager.png"
class="margin-around b-all" title="Access and modify file templates via the Template Manager"
alt="Template Manager"/></li>
<li>Click the Open in Editor button.</li>
<li>Modify the template in the editor. The next time you create a new
servlet (e.g., using the Servlet wizard), the new version will be
applied.</li>
</ol>
</div>
</div>
<br style="clear: both;"/>
<br>
<p>Now that you've mapped URL patterns to the servlet using the <code>@WebServlet</code>
annotation, set up the <code>ControllerServlet</code> to handle these patterns. Also,
instantiate a <code>RequestDispatcher</code> to forward the requested pattern to the
appropriate view.</p>
<ol>
<li>Replace the <code>ControllerServlet</code> class template code with
the following code.
<pre class="examplecode">
public class ControllerServlet extends HttpServlet {
/**
* Handles the HTTP &lt;code&gt;GET&lt;/code&gt; method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userPath = request.getServletPath();
// if category page is requested
if (userPath.equals(&quot;/category&quot;)) {
// TODO: Implement category request
// if cart page is requested
} else if (userPath.equals(&quot;/viewCart&quot;)) {
// TODO: Implement cart page request
userPath = &quot;/cart&quot;;
// if checkout page is requested
} else if (userPath.equals(&quot;/checkout&quot;)) {
// TODO: Implement checkout page request
// if user switches language
} else if (userPath.equals(&quot;/chooseLanguage&quot;)) {
// TODO: Implement language request
}
// use RequestDispatcher to forward request internally
String url = &quot;/WEB-INF/view&quot; + userPath + &quot;.jsp&quot;;
try {
request.getRequestDispatcher(url).forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* Handles the HTTP &lt;code&gt;POST&lt;/code&gt; method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userPath = request.getServletPath();
// if addToCart action is called
if (userPath.equals(&quot;/addToCart&quot;)) {
// TODO: Implement add product to cart action
// if updateCart action is called
} else if (userPath.equals(&quot;/updateCart&quot;)) {
// TODO: Implement update cart action
// if purchase action is called
} else if (userPath.equals(&quot;/purchase&quot;)) {
// TODO: Implement purchase action
userPath = &quot;/confirmation&quot;;
}
// use RequestDispatcher to forward request internally
String url = &quot;/WEB-INF/view&quot; + userPath + &quot;.jsp&quot;;
try {
request.getRequestDispatcher(url).forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}</pre>
As you continue through the tutorial, you'll return to the <code>ControllerServlet</code>
and implement each of the mapped URL patterns individually.</li>
<li>Examine the code above. There are several points to note:
<ul style="margin: 5px 0 0 -2em">
<li>The servlet uses a <code>userPath</code> instance variable to get the
requested URL pattern from the client:
<pre class="examplecode" style="width: 640px">String userPath = request.getServletPath();</pre>
<code>userPath</code> is used by both <code>doGet</code> and <code>doPost</code>
methods.</li>
<li>URL patterns associated primarily with page requests are managed by the
<code>doGet</code> method. For example, <code>/category</code>,
<code>/viewCart</code>, and <code>/checkout</code> result in the display
of the category, cart, and checkout pages.) </li>
<li>URL patterns associated with form submits and the transport of
sensitive user data (e.g., <code>/addToCart</code>, <code>/updateCart</code>,
and <code>/purchase</code>) are managed by the <code>doPost</code>
method.</li>
<li>For both <code>doGet</code> and <code>doPost</code> methods, the path
to the appropriate view is formed using a <code>url</code> string:
<pre class="examplecode" style="width: 640px">String url = &quot;/WEB-INF/view&quot; + userPath + &quot;.jsp&quot;;</pre>
</li>
<li>The <code>RequestDispatcher</code> is obtained from the <code>HttpServletRequest</code>
and applies the <code>url</code> to forward the request:
<pre class="examplecode" style="width: 640px">request.getRequestDispatcher(url).forward(request, response);</pre>
</li>
<li><code>TODO</code> notes have been used to denote work that still needs
to be done. For example:
<pre class="examplecode" style="width: 640px">// if category page is requested
if (userPath.equals(&quot;/category&quot;)) {
// TODO: Implement category request</pre>
Applying <code>TODO</code> notes in your code is a useful way to keep track
of tasks that you need to complete. You can use the IDE's Tasks window
(Ctrl-6; &#8984;-6 on Mac) to view all TODO notes, as well as any syntax or
compile errors contained in your project.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/page-views-controller/tasks-window.png"
class="margin-around b-all" title="Keep track of implementation tasks with the IDE's Tasks window"
alt="Tasks window"/>
<br>
<p class="tips">You can control the keywords that display in the Tasks window.
Open the Options window (Tools &gt; Options; NetBeans &gt; Preferences on Mac),
then choose Miscellaneous &gt; Tasks.</p></li>
</ul>
</li>
<li>Run the project (press F6; fn-F6 on Mac) and test to see whether the <code>ControllerServlet</code>
is forwarding requests to the appropriate views.
<ul style="margin: 5px 0 0 -2em">
<li>Type in <code>http://localhost:8080/AffableBean/category</code> in the browser's
address bar. The application's <a href="#categoryPage">category page</a>
displays.</li>
<li>Type in <code>http://localhost:8080/AffableBean/viewCart</code> in the browser's
address bar. The application's <a href="#cartPage">cart page</a> displays.</li>
<li>Type in <code>http://localhost:8080/AffableBean/checkout</code> in the browser's
address bar. The application's <a href="#checkoutPage">checkout page</a>
displays.</li>
</ul>
<p class="notes"><strong>Note:</strong> Entering <code>http://localhost:8080/AffableBean/purchase</code>
in the browser's address bar does not allow you to view the <a href="#confirmationPage">confirmation
page</a>. Naturally, this is because the <code>/purchase</code> URL pattern is handled
by the servlet's <code>doPost</code> method, and requests sent from the browser's address
bar are typically sent using the HTTP GET method.</p></li>
</ol>
<p>At this stage, you've created JSP pages that contain placeholders for functional components.
You've also set up the front-end structure of the application. JSP pages now reside within
the <code>WEB-INF</code> folder, header and footer code has been factored out into separate
files, your deployment descriptor is properly configured, and you've set up the
<code>ControllerServlet</code> to handle incoming requests. In the next tutorial unit, you
take measures to enable connectivity between the application and the database.</p>
<p>If you'd like to compare your work with the sample solution for this unit, you can
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot2.zip">download
snapshot 2 of the AffableBean project</a>.</p>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans E-commerce Tutorial - Preparing the Page Views and Controller Servlet">Send
Us Your Feedback</a></div>
<br style="clear:both;">
<h2 id="seeAlsoPageViewsController">See Also</h2>
<div class="indent">
<h3>NetBeans Tutorials</h3>
<ul>
<li><a href="../javaee-intro.html" target="_blank">Introduction to Java EE Technology</a></li>
<li><a href="../javaee-gettingstarted.html" target="_blank">Getting Started with Java EE Applications</a></li>
<li><a href="../../web/quickstart-webapps.html" target="_blank">Introduction to Developing Web Applications</a></li>
<li><a href="../../web/mysql-webapp.html" target="_blank">Creating a Simple Web Application Using a MySQL Database</a></li>
<li><a href="../../../../community/media.html" target="_blank">Video Tutorials and Demos for NetBeans IDE</a></li>
<li><a href="https://netbeans.org/projects/www/downloads/download/shortcuts.pdf">Keyboard Shortcuts & Code Templates Card</a></li>
<li><a href="../../../trails/java-ee.html" target="_blank">Java EE & Java Web Learning Trail</a></li>
</ul>
<h3>NetBeans Books</h3>
<ul>
<li><a href="https://netbeans.org/kb/articles/netbeans-tips-and-tricks-book.html" target="_blank">100 NetBeans IDE Tips and Tricks</a></li>
<li><a href="http://www.apress.com/book/view/1590598954" target="_blank">Pro NetBeans IDE 6 Rich Client Platform Edition</a></li>
<li><a href="http://apress.com/book/view/1430219548" target="_blank">Beginning Java EE 6 Platform with GlassFish 3: From Novice to Professional</a></li>
<li><a href="https://netbeans.org/kb/articles/books.html" target="_blank">More books about NetBeans IDE</a></li>
</ul>
<h3>External Resources</h3>
<ul>
<li><a href="http://jcp.org/en/jsr/detail?id=315" target="_blank">Servlet 3.0 Specification</a></li>
<li><a href="https://developer.mozilla.org/en/Common_CSS_Questions" target="_blank">Common CSS Questions</a></li>
<li><a href="http://quirksmode.org/compatibility.html" target="_blank">Browser Compatibility Master Table</a></li>
<li><a href="http://refcardz.dzone.com/refcardz/netbeans-ide-67-update" target="_blank">DZone Refcard for NetBeans Java Editor</a></li>
</ul>
</div>
<br><br><br><br>
<h1 id="connect-db">The NetBeans E-commerce Tutorial - Connecting the Application to the Database</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Tutorial Contents</h4>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#design">Designing the Application</a></li>
<li><a href="#setup-dev-environ">Setting up the Development Environment</a></li>
<li><a href="#data-model">Designing the Data Model</a></li>
<li><a href="#page-views-controller">Preparing the Page Views and Controller Servlet</a></li>
<li><strong>Connecting the Application to the Database</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#sampleData">Adding Sample Data to the Database</a></li>
<li><a href="#createConnPoolDataSource">Creating a Connection Pool and Data Source</a></li>
<li><a href="#testConnPoolDataSource">Testing the Connection Pool and Data Source</a></li>
<li><a href="#param">Setting Context Parameters</a></li>
<li><a href="#jstl">Working with JSTL</a></li>
<li><a href="#troubleshoot">Troubleshooting</a></li>
<li><a href="#seeAlsoConnectDb">See Also</a></li>
</ul></li>
<li><a href="#entity-session">Adding Entity Classes and Session Beans</a></li>
<li><a href="#manage-sessions">Managing Sessions</a></li>
<li><a href="#transaction">Integrating Transactional Business Logic</a></li>
<li><a href="#language">Adding Language Support</a></li>
<li><a href="#security">Securing the Application</a></li>
<li><a href="#test-profile">Testing and Profiling</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ol>
</div>
</div>
<p><img src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" class="stamp"
alt="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"
title="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"></p>
<p>This tutorial unit focuses on communication between the database and the application.
You begin by adding sample data to the database and explore some of the features
provided by the IDE's SQL editor. You set up a data source and connection pool on
the GlassFish server, and proceed by creating a JSP page that tests the data source
by performing a simple query on the database.</p>
<p>This unit also addresses how the application retrieves and displays images necessary
for web presentation, and how to set context parameters and retrieve their values from
web pages. Once you are certain the data source is working correctly, you apply JSTL's
<code>core</code> and <code>sql</code> tag libraries to retrieve and display category
and product images for the <a href="design.html#index">index</a> and
<a href="design.html#category">category</a> pages.</p>
<p>You can view a live demo of the application that you build in this tutorial:
<a href="http://services.netbeans.org/AffableBean/" target="_blank">NetBeans E-commerce
Tutorial Demo Application</a>.</p>
<br style="clear:left;">
<br>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html" target="_blank">NetBeans IDE</a></td>
<td class="tbltd1">Java bundle, 6.8 or 6.9</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank">Java Development Kit (JDK)</a></td>
<td class="tbltd1">version 6</td>
</tr>
<tr>
<td class="tbltd1"><a href="#glassFishConnectDb">GlassFish server</a></td>
<td class="tbltd1">v3 or Open Source Edition 3.0.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://dev.mysql.com/downloads/mysql/" target="_blank">MySQL database server</a></td>
<td class="tbltd1">version 5.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot2.zip">AffableBean
project</a></td>
<td class="tbltd1">snapshot 2</td>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252Fimg.zip">website images</a></td>
<td class="tbltd1">n/a</td>
</tr>
</tbody>
</table>
<p><strong class="notes">Notes:</strong></p>
<ul>
<li>The NetBeans IDE requires the Java Development Kit (JDK) to run properly.
If you do not have any of the resources listed above, the JDK should be
the first item that you download and install.</li>
<li>The NetBeans IDE Java Bundle includes Java Web and EE technologies, which
are required for the application you build in this tutorial.</li>
<li id="glassFishConnectDb">The NetBeans IDE Java Bundle also includes the GlassFish server,
which you require for this tutorial. You could
<a href="http://glassfish.dev.java.net/public/downloadsindex.html" target="_blank">download
the GlassFish server independently</a>, but the version provided with the
NetBeans download has the added benefit of being automatically registered
with the IDE.</li>
<li>You can follow this tutorial unit without having completed previous units. To
do so, perform the following three steps:
<ol style="margin: 5px 0 0 -1.5em">
<li><strong>Set up your MySQL database server.</strong> Follow the steps
outlined in: <a href="setup-dev-environ.html#communicate">Communicating
with the Database Server</a>.</li>
<li><strong>Create the <code>affablebean</code> schema on the database server.</strong>
<ol style="list-style-type: lower-alpha; margin-top: 5px; margin-left: -1.5em">
<li>Click on <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252Faffablebean_schema_creation.sql">affablebean_schema_creation.sql</a>
and copy (Ctrl-C; &#8984;-C on Mac) the entire contents of the file.</li>
<li>Open the IDE's SQL editor. In the Services window (Ctrl-5; &#8984;-5 on Mac),
right-click the <code>affablebean</code> database connection (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/db-connection-node.png"
alt="Database connection node"> ) node and choose Execute Command. The
IDE's SQL editor opens.</li>
<li>Paste (Ctrl-V; &#8984;-V on Mac) the entire contents of the <code>affablebean.sql</code>
file into the editor.</li>
<li>Click the Run SQL ( <img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-sql-btn.png"
alt="Run SQL button"> ) button in the editor's toolbar. The script runs on your
MySQL server. Tables are generated for the <code>affablebean</code> database.</li>
</ol></li>
<li>Open the <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot2.zip">project
snapshot</a> in the IDE. In the IDE, press Ctrl-Shift-O (&#8984;-Shift-O on Mac) and
navigate to the location on your computer where you unzipped the downloaded file.</li>
</ol>
</li>
</ul>
<br>
<h2 id="sampleData">Adding Sample Data to the Database</h2>
<p>Begin by adding sample data to the <code>category</code> and <code>product</code>
tables. You can do this using the IDE's SQL editor, which allows you to interact
directly with the database using native SQL. The IDE's SQL support also includes
a GUI editor that enables you to add, remove, modify and delete table records.</p>
<ul>
<li><a href="#category">category table</a></li>
<li><a href="#product">product table</a></li>
</ul>
<div class="indent">
<h3 id="category">category table</h3>
<ol>
<li>In the Services window (Ctrl-5; &#8984;-5 on Mac), right-click the
<code>category</code> table (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/db-table-node.png"
alt="database table node"> ) node and choose View Data. The SQL
editor opens and displays with a GUI representation of the <code>category</code>
table in the lower region. Note that the table is empty, as no data has
yet been added.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/category-table-empty.png"
class="margin-around b-all" alt="Empty category table displayed in SQL editor"
title="Use the SQL editor to view table data in the IDE">
<br>
Also, note that the native SQL query used to generate the GUI representation
is displayed in the upper region of the editor: '<code>select * from category</code>'.</li>
<li>Delete '<code>select * from category</code>' and enter the following SQL statement:
<pre class="examplecode">INSERT INTO `category` (`name`) VALUES ('dairy'),('meats'),('bakery'),('fruit & veg');</pre>
This statement inserts four new records, each with a unique entry for the
'<code>name</code>' column. Because the <code>id</code> column was specified
as <code>AUTO_INCREMENT</code> when you created the schema, you do not need
to worry about supplying a value.</li>
<li>Click the Run SQL ( <img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-sql-btn.png"
alt="Run SQL button"> ) button in the editor's toolbar. The SQL statement is
executed.</li>
<li>To confirm that the data has been added, run the '<code>select * from category</code>'
query again. To do so, you can use the SQL History window. Click the SQL History (
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/sql-history-btn.png"
alt="SQL History button"> ) button in the editor's toolbar and double-click
the '<code>select * from category</code>' entry. The SQL History window lists
all SQL statements that you recently executed in the IDE.</li>
</ol>
<br>
<p class="tips">Watch the screencast below to see how you can follow the above steps.
When typing in the editor, be sure to take advantage of the IDE's code completion
and suggestion facilities.</p>
<br>
<script src="/images_www/js/mediaplayer-5.9/jwplayer.js" type="text/javascript"></script>
<div id="player" >
<center>
<div id="flashContent"></div>
</center>
</div>
<script type="text/javascript">
$(function(){
var targetFile='http://bits.netbeans.org/media/nb-sql-editor.flv';
jwplayer('flashContent').setup({
'id': 'flashContentId',
'width': '530',
'height': '340',
'autostart': 'false',
'file': targetFile,
'controlbar':{position:'bottom'},
'modes': [
{type: 'html5'},
{type: 'flash', src: '/images_www/js/mediaplayer-5.9/player.swf'},
{type: 'download'}
]
});
});
</script>
<br><br>
<h3 id="product">product table</h3>
<ol>
<li>Right-click the <code>product</code> table (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/db-table-node.png"
alt="database table node"> ) node and choose Execute Command. Choosing the Execute
Command menu option in the Services window opens the SQL editor in the IDE.</li>
<li>Copy and paste the following <code>INSERT</code> statements into the editor.
<pre class="examplecode">
--
-- Sample data for table `product`
--
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('milk', 1.70, 'semi skimmed (1L)', 1);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('cheese', 2.39, 'mild cheddar (330g)', 1);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('butter', 1.09, 'unsalted (250g)', 1);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('free range eggs', 1.76, 'medium-sized (6 eggs)', 1);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('organic meat patties', 2.29, 'rolled in fresh herbs&lt;br&gt;2 patties (250g)', 2);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('parma ham', 3.49, 'matured, organic (70g)', 2);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('chicken leg', 2.59, 'free range (250g)', 2);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('sausages', 3.55, 'reduced fat, pork&lt;br&gt;3 sausages (350g)', 2);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('sunflower seed loaf', 1.89, '600g', 3);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('sesame seed bagel', 1.19, '4 bagels', 3);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('pumpkin seed bun', 1.15, '4 buns', 3);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('chocolate cookies', 2.39, 'contain peanuts&lt;br&gt;(3 cookies)', 3);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('corn on the cob', 1.59, '2 pieces', 4);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('red currants', 2.49, '150g', 4);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('broccoli', 1.29, '500g', 4);
INSERT INTO `product` (`name`, price, description, category_id) VALUES ('seedless watermelon', 1.49, '250g', 4);
</pre>
Examine the above code and note the following points:
<ul style="margin: 5px 0 0 -2em">
<li>By examining the
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252Faffablebean_schema_creation.sql"><code>affablebean</code>
schema generation script</a>, you'll note that the <code>product</code>
table contains a non-nullable, automatically incremental primary key.
Whenever you insert a new record into the table (and don't explicitly
set the value of the primary key), the SQL engine sets it for you.
Also, note that the <code>product</code> table's <code>last_update</code>
column applies <code>CURRENT_TIMESTAMP</code> as its default value.
The SQL engine will therefore provide the current date and time for
this field when a record is created.
<br><br>
Looking at this another way, if you were to create an <code>INSERT</code>
statement that didn't indicate which columns would be affected by the
insertion action, you would need to account for all columns. In this
case, you could enter a <code>NULL</code> value to enable the SQL engine
to automatically handle fields that have default values specified. For
example, the following statement elicits the same result as the first
line of the above code:
<pre class="examplecode" style="width:662px">INSERT INTO `product` VALUES (NULL, 'milk', 1.70, 'semi skimmed (1L)', NULL, 1);</pre>
After running the statement, you'll see that the record contains an
automatically incremented primary key, and the <code>last_update</code>
column lists the current date and time.</li>
<li>The value for the final column, '<code>category_id</code>', must
correspond to a value contained in the <code>category</code> table's
<code>id</code> column. Because you have already added four records
to the <code>category</code> table, the <code>product</code> records
you are inserting reference one of these four records. If you try to
insert a <code>product</code> record that references a <code>category_id</code>
that doesn't exist, a foreign key constraint fails.</li>
</ul></li>
<li>Click the Run SQL ( <img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-sql-btn.png"
alt="Run SQL button"> ) button in the editor's toolbar.
<br><br>
<p class="notes"><strong>Note:</strong> View the Output window (Ctrl-4; &#8984;-4
on Mac) to see a log file containing results of the execution.</p></li>
<li>Right-click the <code>product</code> table (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/db-table-node.png"
alt="database table node"> ) node and choose View Data. You can see 16 new records
listed in the table.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/product-table.png"
class="margin-around b-all" alt="16 new records displayed in SQL editor's 'product' table"
title="Choose View Data from a table node's right-click menu to verify sample data"
style="width:688px">
<br>
<div class="feedback-box float-left" style="width: 683px;">
<h3>NetBeans GUI Support for Database Tables</h3>
<p>In the Services window, when you right-click a table (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/db-table-node.png"
alt="database table node"> ) node and choose View Data, the IDE displays
a visual representation of the table and the data it contains (as depicted
in the image above). You can also use this GUI support to add, modify, and
delete table data.</p>
<ul>
<li><strong>Add new records:</strong> To add new records, click the Insert
Record ( <img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/insert-record-btn.png"
alt="Insert Record button"> ) button. An Insert Records dialog window
displays, enabling you to enter new records. When you click OK, the
new data is committed to the database, and the GUI representation of
the table is automatically updated.
<br><br>
<p class="tips">Click the Show SQL button within the dialog window
to view the SQL statement(s) that will be applied upon initiating the
action.</p></li>
<li><strong>Modify records:</strong> You can make edits to existing records
by double-clicking directly in table cells and modifying field entries.
Modified entries display as <span style="color: #259125">green text</span>.
When you are finished editing data, click the Commit Record
( <img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/commit-record-btn.png"
alt="Commit Record button"> ) button to commit changes to the actual database.
(Similarly, click the Cancel Edits
( <img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/cancel-edits-btn.png"
alt="Cancel Edits button"> ) button to cancel any edits you have made.</li>
<li><strong>Delete individual records:</strong> Click a row in the table,
then click the Delete Selected Record (
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/delete-selected-record-btn.png"
alt="Delete Selected Record button"> ) button. You can also delete
multiple rows simultaneously by holding Ctrl (&#8984; on Mac) while
clicking to select rows.</li>
<li><strong>Delete all records:</strong> Deleting all records within a
table is referred to as '<em>truncating</em>' the table. Click the
Truncate Table ( <img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/truncate-table-btn.png"
alt="Truncate Table button"> ) button to delete all records contained
in the displayed table.</li>
</ul>
<p>If the displayed data needs to be resynchronized with the actual database,
you can click the Refresh Records (
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/refresh-records-btn.png"
alt="Refresh Records button"> ) button. Note that much of the above-described
functionality can also be accessed from the right-click menu within the GUI
editor.</p>
</div>
<div style="clear:left"></div>
</li>
</ol>
</div>
<br>
<h2 id="createConnPoolDataSource">Creating a Connection Pool and Data Source</h2>
<p>From this point onward, you establish connectivity between the MySQL database and the
<code>affablebean</code> application through the GlassFish server which it is deployed
to. This communication is made possible with the Java Database Connectivity
(<a href="http://java.sun.com/products/jdbc/overview.html" target="_blank">JDBC</a>) API.
The JDBC API is an integration library contained in the JDK (refer back to the component
diagram displayed in the tutorial <a href="intro.html#platform">Introduction</a>). Although
this tutorial does not work directly with JDBC programming, the application that we are
building does utilize the JDBC API whenever communication is required between the SQL and
Java languages. For example, you start by creating a <em>connection pool</em> on the
GlassFish server. In order for the server to communicate directly with the the MySQL
database, it requires the <a href="http://www.mysql.com/downloads/connector/j/" target="_blank">Connector/J</a>
JDBC driver which converts JDBC calls directly into a MySQL-specific protocol. Later in
this tutorial unit, when you apply JSTL's
<a href="http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/jstl/1.1/docs/tlddocs/sql/query.html" target="_blank"><code>&lt;sql:query&gt;</code></a>
tags to query the <code>affablebean</code> database, the tags are translated into JDBC
<a href="http://download-llnw.oracle.com/javase/6/docs/api/java/sql/Statement.html" target="_blank"><code>Statement</code></a>s.</p>
<p>A connection pool contains a group of reusable connections for a particular database.
Because creating each new physical connection is time-consuming, the server maintains
a pool of available connections to increase performance. When an application requests
a connection, it obtains one from the pool. When an application closes a connection,
the connection is returned to the pool. Connection pools use a JDBC driver to create
physical database connections.</p>
<p>A data source (a.k.a. a JDBC resource) provides applications with the means of connecting
to a database. Applications get a database connection from a connection pool by looking
up a data source using the Java Naming and Directory Interface
(<a href="http://www.oracle.com/technetwork/java/overview-142035.html" target="_blank">JNDI</a>)
and then requesting a connection. The connection pool associated with the data source
provides the connection for the application.</p>
<p>In order to enable the application access to the <code>affablebean</code> database,
you need to create a connection pool and a data source that uses the connection pool.
Use the NetBeans GlassFish JDBC Resource wizard to accomplish this.</p>
<p class="notes"><strong>Note:</strong> You can also create connection pools and data
sources directly on the GlassFish server using the GlassFish Administration Console.
However, creating these resources in this manner requires that you manually enter
database connection details (i.e., username, password and URL). The benefit of using
the NetBeans wizard is that it extracts any connection details directly from an
existing database connection, thus eliminating potential connectivity problems.</p>
<p class="tips">To access the console from the IDE, in the Services window right-click
the Servers &gt; GlassFish node and choose View Admin Console. The default username / password
is: <code>admin</code> / <code>adminadmin</code>. If you'd like to set up the connection
pool and data source using the GlassFish Administration console, follow steps 3-15 of
the <a href="#setup">NetBeans E-commerce Tutorial Setup Instructions</a>. The setup
instructions are provided for later tutorial units.</p>
<ol>
<li>Click the New File (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/new-file-btn.png"
alt="New File button"> ) button in the IDE's toolbar. (Alternatively, press Ctrl-N;
&#8984;-N on Mac.)</li>
<li>Select the <strong>GlassFish</strong> category, then select <strong>JDBC Resource</strong>
and click Next.</li>
<li>In Step 2 of the JDBC Resource wizard, select the <code>Create New JDBC Connection Pool</code>
option. When you do so, three new steps are added to the wizard, enabling you to specify
connection pool settings.</li>
<li>Enter details to set up the data source:
<ul style="margin: 5px 0 0 -2em">
<li><strong>JNDI Name:</strong> <code>jdbc/affablebean</code>
<br><span class="tips" style="line-height: 25px">By convention, the JNDI name for
a JDBC resource begins with the '<code>jdbc/</code>' string.</span></li>
<li><strong>Object Type:</strong> <code>user</code></li>
<li><strong>Enabled:</strong> <code>true</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/jdbc-resource-gen-attributes.png"
class="margin-around b-all" style="width:688px" alt="JDBC Resource wizard - General Attributes"
title="Create a new connection pool and data source using the JDBC Resource wizard">
</li>
<li>Click Next. In Step 3, Additional Properties, you do not need to specify any additional
configuration information for the data source.</li>
<li>Click Next. In Step 4, Choose Database Connection, type in <code>AffableBeanPool</code>
as the JDBC connection pool name. Also, ensure that the <code>Extract from Existing
Connection</code> option is selected, and that the <code>jdbc:mysql://localhost:3306/affablebean</code>
connection is listed.</li>
<li>Click Next. In Step 5, Add Connection Pool Properties, specify the following details:
<ul style="margin: 5px 0 0 -2em">
<li><strong>Datasource Classname:</strong> <code>com.mysql.jdbc.jdbc2.optional.MysqlDataSource</code></li>
<li><strong>Resource Type:</strong> <code>javax.sql.ConnectionPoolDataSource</code></li>
<li><strong>Description:</strong> <em>(Optional)</em> <code>Connects to the affablebean database</code></li>
</ul>
Also, note that the wizard extracts and displays properties from the existing connection.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/jdbc-resource-conn-pool.png"
class="margin-around b-all" style="width:688px" alt="JDBC Resource wizard - Add Connection Pool"
title="Create a new connection pool and data source using the JDBC Resource wizard"></li>
<li>Click Finish. The wizard generates a <code>sun-resources.xml</code> file for the
project that contains all information required to set up the connection pool and
data source on GlassFish. The <code>sun-resources.xml</code> file is a deployment
descriptor specific to the GlassFish application server. When the project next gets
deployed, the server will read in any configuration data contained in
<code>sun-resources.xml</code>, and set up the connection pool and data source
accordingly. Note that once the connection pool and data source exist on the server,
your project no longer requires the <code>sun-resources.xml</code> file.</li>
<li>In the Projects window (Ctrl-1; &#8984;-1 on Mac), expand the Server Resources node
and double-click the <code>sun-resources.xml</code> file to open it in the editor.
Here you see the XML configuration required to set up the connection pool and data
source. (Code below is formatted for readability.)
<pre class="examplecode">
&lt;resources&gt;
&lt;jdbc-resource enabled=&quot;true&quot;
jndi-name=&quot;jdbc/affablebean&quot;
object-type=&quot;user&quot;
pool-name=&quot;AffableBeanPool&quot;&gt;
&lt;/jdbc-resource&gt;
&lt;jdbc-connection-pool allow-non-component-callers=&quot;false&quot;
associate-with-thread=&quot;false&quot;
connection-creation-retry-attempts=&quot;0&quot;
connection-creation-retry-interval-in-seconds=&quot;10&quot;
connection-leak-reclaim=&quot;false&quot;
connection-leak-timeout-in-seconds=&quot;0&quot;
connection-validation-method=&quot;auto-commit&quot;
datasource-classname=&quot;com.mysql.jdbc.jdbc2.optional.MysqlDataSource&quot;
fail-all-connections=&quot;false&quot;
idle-timeout-in-seconds=&quot;300&quot;
is-connection-validation-required=&quot;false&quot;
is-isolation-level-guaranteed=&quot;true&quot;
lazy-connection-association=&quot;false&quot;
lazy-connection-enlistment=&quot;false&quot;
match-connections=&quot;false&quot;
max-connection-usage-count=&quot;0&quot;
max-pool-size=&quot;32&quot;
max-wait-time-in-millis=&quot;60000&quot;
name=&quot;AffableBeanPool&quot;
non-transactional-connections=&quot;false&quot;
pool-resize-quantity=&quot;2&quot;
res-type=&quot;javax.sql.ConnectionPoolDataSource&quot;
statement-timeout-in-seconds=&quot;-1&quot;
steady-pool-size=&quot;8&quot;
validate-atmost-once-period-in-seconds=&quot;0&quot;
wrap-jdbc-objects=&quot;false&quot;&gt;
&lt;description&gt;Connects to the affablebean database&lt;/description&gt;
&lt;property name=&quot;URL&quot; value=&quot;jdbc:mysql://localhost:3306/affablebean&quot;/&gt;
&lt;property name=&quot;User&quot; value=&quot;root&quot;/&gt;
&lt;property name=&quot;Password&quot; value=&quot;nbuser&quot;/&gt;
&lt;/jdbc-connection-pool&gt;
&lt;/resources&gt;</pre>
</li>
<li>In the Projects window (Ctrl-1; &#8984;-1 on Mac), right-click the <code>AffableBean</code>
project node and choose Deploy. The GlassFish server reads configuration data from
the <code>sun-resources.xml</code> file and creates the <code>AffableBeanPool</code>
connection pool, and <code>jdbc/affablebean</code> data source.</li>
<li>In the Services window, expand the Servers &gt; GlassFish &gt; Resources &gt; JDBC node.
Here you can locate the <code>jdbc/affablebean</code> data source listed under JDBC
Resources, and the <code>AffableBeanPool</code> connection pool listed under Connection
Pools.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/gf-server-jdbc-resources.png"
class="margin-around b-all" alt="Services window - GlassFish JDBC Resources"
title="View data sources and connection pools registered on the server">
<br>
<p class="tips">Right-click data source and connection pool nodes to view and
make changes to their properties. You can associate a data source with any
connection pool registered on the server. You can edit property values for
connection pools, and unregister both data sources and connection pools from
the server.</p></li>
</ol>
<br>
<h2 id="testConnPoolDataSource">Testing the Connection Pool and Data Source</h2>
<p>Start by making sure the GlassFish server can successfully connect to the MySQL database.
You can do this by pinging the <code>AffableBeanPool</code> connection pool in the GlassFish
Administration Console.</p>
<p>Then proceed by adding a reference in your project to the data source you created on
the server. To do so, you create a <code>&lt;resource-ref&gt;</code> entry in the
application's <code>web.xml</code> deployment descriptor.</p>
<p>Finally, use the IDE's editor support for the <a href="http://java.sun.com/products/jsp/jstl/" target="_blank">JSTL</a>
<code>sql</code> tag library, and create a JSP page that queries the database and
outputs data in a table on a web page.</p>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#ping">Pinging the Connection Pool</a></li>
<li><a href="#resourceReference">Creating a Resource Reference to the Data Source</a></li>
<li><a href="#query">Querying the Database from a JSP Page</a></li>
</ul>
<div class="indent">
<h3 id="ping">Pinging the Connection Pool</h3>
<ol>
<li>Ensure that the GlassFish server is already running. In the Services window (Ctrl-5;
&#8984;-5 on Mac), expand the Servers node. Note the small green arrow next to the
GlassFish icon ( <img src="../../../../images_www/articles/73/javaee/ecommerce/common/gf-server-running-node.png"
alt="GlassFish server node in Services window"> ).
<br><br>
(If the server is not running, right-click the server node and choose Start.)</li>
<li>Right-click the server node and choose View Admin Console. The GlassFish Administration
Console opens in a browser.</li>
<li>Log into the administration console. The default username / password is: <code>admin</code>
/ <code>adminadmin</code>.</li>
<li>In the console's tree on the left, expand the Resources &gt; JDBC &gt; Connection Pools
nodes, then click <code>AffableBeanPool</code>. In the main window, the Edit Connection
Pool interface displays for the selected connection pool.</li>
<li>Click the Ping button. If the ping succeeds, the GlassFish server has a working connection to
the <code>affablebean</code> database on the MySQL server.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/ping-succeeded.png"
class="margin-around b-all" alt="GlassFish Administration Console - Edit Connection Pool"
title="Ping the connection pool to determine whether it has a physical connection to the database">
<br>
(If the ping fails, see suggestions in the <a href="#troubleshoot">Troubleshooting</a> section
below.)</li>
</ol>
<h3 id="resourceReference">Creating a Resource Reference to the Data Source</h3>
<ol>
<li>In the Projects window, expand the Configuration Files folder and double-click
<code>web.xml</code>. A graphical interface for the file displays in the IDE's
main window.</li>
<li>Click the References tab located along the top of the editor. Expand the Resource
References heading, then click Add. The Add Resource Reference dialog opens.</li>
<li>Enter the following details into the dialog:
<ul style="margin: 5px 0 0 -2em">
<li><strong>Resource Name:</strong> <code>jdbc/affablebean</code></li>
<li><strong>Resource Type:</strong> <code>javax.sql.ConnectionPoolDataSource</code></li>
<li><strong>Authentication:</strong> <code>Container</code></li>
<li><strong>Sharing Scope:</strong> <code>Shareable</code></li>
<li><strong>Description:</strong> <em>(Optional)</em> <code>Connects to database for AffableBean application</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/add-resource-ref-dialog.png"
alt="Add Resource Reference dialog" class="margin-around b-all"
title="Specify resource properties in the Add Resource Reference dialog"></li>
<li>Click OK. The new resource is added under the Resource References heading.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/resource-reference.png"
title="Create a reference to the data source for the application" style="width: 688px"
alt="Resource reference to jdbc/affablebean data source listed in the deployment descriptor"
class="margin-around b-all">
<br>
To verify that the resource is now added to the <code>web.xml</code> file,
click the XML tab located along the top of the editor. Notice that the
following <code>&lt;resource-ref&gt;</code> tags are now included:
<pre class="examplecode">
&lt;resource-ref&gt;
&lt;description&gt;Connects to database for AffableBean application&lt;/description&gt;
&lt;res-ref-name&gt;jdbc/affablebean&lt;/res-ref-name&gt;
&lt;res-type&gt;javax.sql.ConnectionPoolDataSource&lt;/res-type&gt;
&lt;res-auth&gt;Container&lt;/res-auth&gt;
&lt;res-sharing-scope&gt;Shareable&lt;/res-sharing-scope&gt;
&lt;/resource-ref&gt;</pre>
</li>
</ol>
<h3 id="query">Querying the Database from a JSP Page</h3>
<ol>
<li>Create a new JSP page to test the data source. Click the New File (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/new-file-btn.png"
alt="New File button"> ) button. (Alternatively, press Ctrl-N; &#8984;-N on Mac.)</li>
<li>Select the Web category, then select the JSP file type and click Next.</li>
<li>Enter '<code>testDataSource</code>' as the file name. In the Folder field, type
in '<code>test</code>'.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/new-jsp-wzd.png"
class="margin-around b-all" style="width:688px" alt="JSP wizard"
title="Enter details to name and place a new JSP page into the project">
<br>
<p class="tips">The project does not yet have a folder named '<code>test</code>' within
the Web Pages location (i.e., within the <code>web</code> folder). By entering '<code>test</code>'
into the Folder field, you have the IDE create the folder upon completing the wizard.</p></li>
<li>Click finish. The IDE generates a new <code>testDataSource.jsp</code> file, and places
it into the new <code>test</code> folder within the project.</li>
<li>In the new <code>testDataSource.jsp</code> file, in the editor, place your cursor at
the end of the line containing the <code>&lt;h1&gt;</code> tags (line 17). Press Return,
then press Ctrl-Space to invoke code suggestions. Choose DB Report from the list of
options.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/db-report.png"
class="margin-around b-all" alt="Code suggestions displayed in editor"
title="Press Ctrl-Space in editor to invoke code suggestions">
<br>
<p class="tips">If line numbers do not display, right-click in the left margin of the
editor and choose Show Line Numbers.</p></li>
<li>In the Insert DB Report dialog, specify the data source and modify the SQL query
to be executed:
<ul style="margin: 5px 0 0 -2em">
<li><strong>Data Source:</strong> <code>jdbc/affablebean</code></li>
<li><strong>Query Statement:</strong> <code>SELECT * FROM category, product WHERE category.id = product.category_id</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/insert-db-report.png"
class="margin-around b-all" alt="Insert DB Report dialog"
title="Specify the data source and SQL query to be executed"></li>
<li>Click OK. The dialog adds the <code>taglib</code> directives for the JSTL
<code>core</code> and <code>sql</code> libraries to the top of the file:
<pre class="examplecode">
&lt;%@taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot;%&gt;
&lt;%@taglib prefix=&quot;sql&quot; uri=&quot;http://java.sun.com/jsp/jstl/sql&quot;%&gt;</pre>
The dialog also generates template code to display the query results in an
HTML table:
<pre class="examplecode">
&lt;sql:query var=&quot;result&quot; dataSource=&quot;jdbc/affablebean&quot;&gt;
SELECT * FROM category, product
WHERE category.id = product.category_id
&lt;/sql:query&gt;
&lt;table border=&quot;1&quot;&gt;
&lt;!-- column headers --&gt;
&lt;tr&gt;
&lt;c:forEach var=&quot;columnName&quot; items=&quot;${result.columnNames}&quot;&gt;
&lt;th&gt;&lt;c:out value=&quot;${columnName}&quot;/&gt;&lt;/th&gt;
&lt;/c:forEach&gt;
&lt;/tr&gt;
&lt;!-- column data --&gt;
&lt;c:forEach var=&quot;row&quot; items=&quot;${result.rowsByIndex}&quot;&gt;
&lt;tr&gt;
&lt;c:forEach var=&quot;column&quot; items=&quot;${row}&quot;&gt;
&lt;td&gt;&lt;c:out value=&quot;${column}&quot;/&gt;&lt;/td&gt;
&lt;/c:forEach&gt;
&lt;/tr&gt;
&lt;/c:forEach&gt;
&lt;/table&gt;</pre></li>
<li>Before running the file in a browser, make sure you have enabled the JDBC driver
deployment option in NetBeans' GlassFish support. Choose Tools &gt; Servers to
open the Servers window. In the left column, select the GlassFish server you are
deploying to. In the main column, ensure that the 'Enable JDBC Driver Deployment'
option is selected, then click Close.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/servers-window.png"
class="margin-around b-all" style="width:688px" alt="Servers window"
title="Ensure that the Enable JDBC Driver Deployment option is selected">
<br>
For Java applications that connect to a database, the server requires a JDBC
driver to be able to create a communication bridge between the SQL and Java
languages. In the case of MySQL, you use the <a href="http://www.mysql.com/downloads/connector/j/" target="_blank">Connector/J</a>
JDBC driver. Ordinarily you would need to manually place the driver JAR file
into the server's <code>lib</code> directory. With the 'Enable JDBC Driver
Deployment' option selected, the server performs a check to see whether a
driver is needed, and if so, the IDE deploys the driver to the server.</li>
<li>Right-click in the editor and choose Run File (Shift-F6; fn-Shift-F6 on Mac).
The <code>testDataSource.jsp</code> file is compiled into a servlet, deployed
to the server, then runs in a browser.</li>
<li>Open the Output window (Ctrl-4; &#8984;-4 on Mac) and click the 'AffableBean (run)'
tab. The output indicates that the driver JAR file (<code>mysql-connector-java-5.1.6-bin.jar</code>)
is deployed.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/output-window-mysql-driver.png"
class="margin-around b-all" style="width:688px" alt="Output window listing MySQL driver deployment"
title="When JDBC Driver Deployment is enabled, the IDE deploys the MySQL driver to GlassFish when required"></li>
<li>Examine <code>testDataSource.jsp</code> in the browser. You see an HTML table
listing data contained in the <code>category</code> and <code>product</code> tables.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/test-data-source.png"
class="margin-around b-all" style="width:688px" alt="Browser display of testDataSource.jsp"
title="The JSP page contains data extracted from the 'affablebean' database">
<br>
(If you receive a server error, see suggestions in the <a href="#troubleshoot">Troubleshooting</a>
section below.)</li>
</ol>
</div>
<p>At this stage, we have set up a working data source and connection pool on the server, and
demonstrated that the application can access data contained in the <code>affablebean</code>
database.</p>
<br>
<h2 id="param">Setting Context Parameters</h2>
<p>This section demonstrates how to configure context parameters for the application,
and how to access parameter values from JSP pages. The owner of an application may want
to be able to change certain settings without the need to make intrusive changes to
source code. Context parameters enable you application-wide access to parameter
values, and provide a convenient way to change parameter values from a single location,
should the need arise.</p>
<p>Setting up context parameters can be accomplished in two steps:</p>
<ol style="margin-top: 0">
<li>Listing parameter names and values in the web deployment descriptor</li>
<li>Calling the parameters in JSP pages using the <code>initParam</code> object</li>
</ol>
<p>The JSP Expression Language (EL) defines <em>implicit objects</em>, which <code>initParam</code>
is an example of. When working in JSP pages, you can utilize implicit objects
using dot notation and placing expressions within EL delimiters (<code>${...}</code>).
For example, if you have an initialization parameter named <code>myParam</code>,
you can access it from a JSP page with the expression <code>${initParam.myParam}</code>.</p>
<p class="tips">For more information on the JSP Expression Language and implicit objects,
see the Java EE 5 Tutorial:
<a href="http://download.oracle.com/docs/cd/E17477_01/javaee/5/tutorial/doc/bnahq.html" target="_blank">JavaServer
Pages Technology &gt; Unified Expression Language</a>.</p>
<p>By way of demonstration, you create context parameters for the image paths to
category and product images used in the <code>AffableBean</code> project. Begin
by adding the provided image resources to the project, then perform the two steps
outlined above.</p>
<ol>
<li>Download the <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252Fimg.zip">website
sample images</a>, and unzip the file to a location on your computer. The unzipped
file is an <code>img</code> folder that contains all of the image resources required
for the <code>AffableBean</code> application.</li>
<li>Import the <code>img</code> folder into the <code>AffableBean</code> project.
Copy (Ctrl-C; &#8984;-C on Mac) the <code>img</code> folder, then in the IDE's
Projects window, paste (Ctrl-V; &#8984;-V on Mac) the folder into the project's
Web Pages node.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/projects-win-img-folder.png"
class="margin-around b-all" alt="'img' folder displayed in Projects window"
title="Import the 'img' folder into the AffableBean project">
<br>
The <code>categories</code> and <code>products</code> folders contain the
images that will be displayed in the <a href="design.html#index">index</a> and
<a href="design.html#category">category</a> pages, respectively.</li>
<li>Open the project's web deployment descriptor. In the Projects window, expand
the Configuration Files node and double-click <code>web.xml</code>.</li>
<li>Click the General tab, then expand Context Parameters and click the Add button.</li>
<li>In the Add Context Parameter dialog, enter the following details:
<ul style="margin: 5px 0 0 -1em">
<li><strong>Parameter Name:</strong> <code>productImagePath</code></li>
<li><strong>Parameter Value:</strong> <code>img/products/</code></li>
<li><strong>Description:</strong> <em>(Optional)</em>
<code>The relative path to product images</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/add-context-param-dialog.png"
class="margin-around b-all" alt="Add Context Parameter dialog"
title="Add initialization parameters using the Add Context Parameter dialog"></li>
<li>Click OK.</li>
<li>Click the Add button again and enter the following details:
<ul style="margin: 5px 0 0 -1em">
<li><strong>Parameter Name:</strong> <code>categoryImagePath</code></li>
<li><strong>Parameter Value:</strong> <code>img/categories/</code></li>
<li><strong>Description:</strong> <em>(Optional)</em>
<code>The relative path to category images</code></li>
</ul></li>
<li>Click OK. The two context parameters are now listed:
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/context-parameters.png"
class="margin-around b-all" alt="web.xml - context parameters"
title="Context parameters display in the web.xml interface"></li>
<li>Click the XML tab to view the XML content that has been added to the deployment
descriptor. The following <code>&lt;context-param&gt;</code> entries have been
added:
<pre class="examplecode">
&lt;context-param&gt;
&lt;description&gt;The relative path to product images&lt;/description&gt;
&lt;param-name&gt;productImagePath&lt;/param-name&gt;
&lt;param-value&gt;img/products/&lt;/param-value&gt;
&lt;/context-param&gt;
&lt;context-param&gt;
&lt;description&gt;The relative path to category images&lt;/description&gt;
&lt;param-name&gt;categoryImagePath&lt;/param-name&gt;
&lt;param-value&gt;img/categories/&lt;/param-value&gt;
&lt;/context-param&gt;</pre></li>
<li>To test whether the values for the context parameters are accessible to web
pages, open any of the project's web pages in the editor and enter EL
expressions using the <code>initParam</code> implicit object. For example,
open <code>index.jsp</code> and enter the following (New code in <strong>bold</strong>):
<pre class="examplecode">
&lt;div id=&quot;indexLeftColumn&quot;&gt;
&lt;div id=&quot;welcomeText&quot;&gt;
&lt;p&gt;[ welcome text ]&lt;/p&gt;
<strong>&lt;!-- test to access context parameters --&gt;
categoryImagePath: ${initParam.categoryImagePath}
productImagePath: ${initParam.productImagePath}</strong>
&lt;/div&gt;
&lt;/div&gt;</pre></li>
<li>Run the project. Click the Run Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) button. The project's index page opens in the browser,
and you see the values for the <code>categoryImagePath</code> and <code>productImagePath</code>
context parameters displayed in the page.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/context-params-browser.png"
class="margin-around b-all" alt="Context parameter values displayed in browser"
title="Use 'initParam' with JSP EL delimiters to display context parameter values">
</li>
</ol>
<br>
<h2 id="jstl">Working with JSTL</h2>
<p>So far in this tutorial unit, you've established how to access data from the
<code>affablebean</code> database, add image resources to the project, and
have set up several context parameters. In this final section, you combine
these achievements to plug the product and category images into the application.
In order to do so effectively, you need to begin taking advantage of the JavaServer
Pages Standard Tag Library (JSTL).</p>
<p>Note that you do not have to worry about adding the JSTL JAR file (<code>jstl-impl.jar</code>)
to your project's classpath because it already exists. When you created the
<code>AffableBean</code> project and selected GlassFish as your development server,
the libraries contained in the server were automatically added to your project's
classpath. You can verify this in the Projects window by expanding the <code>AffableBean</code>
project's Libraries &gt; GlassFish Server 3 node to view all of the libraries
provided by the server.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/gf-libraries.png"
class="margin-around b-all" alt="GlassFish libraries listed in Projects window"
title="GlassFish libraries are available to your project">
<br>
The <code>jstl-impl.jar</code> file is GlassFish' implementation of JSTL, version 1.2.</p>
<p class="tips">You can also download the GlassFish JSTL JAR file separately from:
<a href="http://jstl.dev.java.net/download.html" target="_blank">http://jstl.dev.java.net/download.html</a></p>
<p>Before embarking upon an exercise involving JSTL, one implementation detail
needs to first be clarified. Examine the files contained in the <code>categories</code>
and <code>products</code> folders and note that the names of the provided
image files match the names of the category and product entries found in the
database. This enables us to leverage the database data to dynamically call
image files within the page. So for example, if the web page needs to access
the image for the broccoli product entry, you can make this happen using the
following statement.</p>
<div class="indent">
<pre class="examplecode" style="width:700px">${initParam.productImagePath}broccoli.png</pre>
</div>
<p>After implementing a JSTL
<code><a href="http://java.sun.com/products/jsp/jstl/1.1/docs/tlddocs/c/forEach.html" target="_blank">forEach</a></code>
loop, you'll be able to replace the hard-coded name of the product with an EL
expression that dynamically extracts the name of the product from the database,
and inserts it into the page.</p>
<div class="indent">
<pre class="examplecode" style="width:700px">${initParam.productImagePath}${product.name}.png</pre>
</div>
<p>Begin by integrating the category images into the index page, then work within the
category page so that data pertaining to the selected category is dynamically handled.</p>
<ul>
<li><a href="#indexJSTL">index page</a></li>
<li><a href="#categoryJSTL">category page</a></li>
</ul>
<div class="indent">
<h3 id=indexJSTL">index page</h3>
<ol>
<li>In the Projects window, double-click the <code>index.jsp</code> node to open
it in the editor. (If already opened, press Ctrl-Tab to select it in the editor.)</li>
<li>At the top of the file, before the first <code>&lt;div&gt;</code> tag, place your
cursor on a blank line, then type '<code>db</code>' and press Ctrl-Space. In the
code-completion pop-up window that displays, choose DB Query.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/db-query.png"
class="margin-around b-all" alt="DB completion items displayed in editor"
title="Type 'db', then press Ctrl-Space to invoke code completion suggestions"></li>
<li>In the Insert DB Query dialog, enter the following details:
<ul style="margin: 5px 0 0 -1em">
<li><strong>Variable Name:</strong> <code>categories</code></li>
<li><strong>Scope:</strong> <code>page</code></li>
<li><strong>Data Source:</strong> <code>jdbc/affablebean</code></li>
<li><strong>Query Statement:</strong> <code>SELECT * FROM category</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/insert-db-query.png"
class="margin-around b-all" alt="Insert DB query dialog"
title="Specify query details to create an SQL query using JSTL <sql:query> tags"></li>
<li>Click OK. The dialog generates an SQL query using JSTL <code>&lt;sql:query&gt;</code> tags.
Also, note that the required reference to the <code>sql</code> <code>taglib</code> directive
has been automatically inserted at the top of the page. (Changes displayed in <strong>bold</strong>.)
<pre class="examplecode">
<strong>&lt;%@taglib prefix=&quot;sql&quot; uri=&quot;http://java.sun.com/jsp/jstl/sql&quot;%&gt;</strong>
&lt;%--
Document : index
Created on : Sep 5, 2009, 4:32:42 PM
Author : nbuser
--%&gt;
<strong>&lt;sql:query var=&quot;categories&quot; dataSource=&quot;jdbc/affablebean&quot;&gt;
SELECT * FROM category
&lt;/sql:query&gt;</strong>
&lt;div id=&quot;indexLeftColumn&quot;&gt;
&lt;div id=&quot;welcomeText&quot;&gt;
&lt;p&gt;[ welcome text ]&lt;/p&gt;
</pre>
The SQL query creates a result set which is stored in the <code>categories</code>
variable. You can then access the result set using EL syntax, e.g., <code>${categories}</code>
(demonstrated below).</li>
<li>Place your cursor at the end of '<code>&lt;div id=&quot;indexRightColumn&quot;&gt;</code>'
(line 22), hit return, type '<code>jstl</code>' then press Ctrl-Space and choose
JSTL For Each.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/jstl-for-each.png"
class="margin-around b-all" alt="JSTL completion items displayed in editor"
title="Type 'jstl', then press Ctrl-Space to invoke code completion suggestions"></li>
<li>In the Insert JSTL For Each dialog, enter the following details:
<ul style="margin: 5px 0 0 -2em">
<li><strong>Collection:</strong> <code>${categories.rows}</code></li>
<li><strong>Current Item of the Iteration:</strong> <code>category</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/insert-jstl-for-each.png"
class="margin-around b-all" style="width:625px" alt="Insert JSTL For Each dialog"
title="Specify details to create a 'for each' loop using JSTL <c:forEach> tags"></li>
<li>Click OK. The dialog sets up syntax for a JSTL <code>forEach</code> loop using <code>&lt;c:forEach&gt;</code>
tags. Also, note that the required reference to the <code>core</code> <code>taglib</code>
directive has been automatically inserted at the top of the page. (Changes displayed in
<strong>bold</strong>.)
<pre class="examplecode">
<strong>&lt;%@taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot;%&gt;</strong>
&lt;%@taglib prefix=&quot;sql&quot; uri=&quot;http://java.sun.com/jsp/jstl/sql&quot;%&gt;
...
&lt;div id=&quot;indexRightColumn&quot;&gt;
<strong>&lt;c:forEach var=&quot;category&quot; items=&quot;categories.rows&quot;&gt;
&lt;/c:forEach&gt;</strong>
&lt;div class=&quot;categoryBox&quot;&gt;</pre>
<br>
<p class="tips">If you are wondering what '<code>rows</code>' refers to in the
generated code, recall that the <code>categories</code> variable represents a
result set. More specifically, <code>categories</code> refers to an object that
implements the
<code><a href="http://java.sun.com/products/jsp/jstl/1.1/docs/api/javax/servlet/jsp/jstl/sql/Result.html" target="_blank">javax.servlet.jsp.jstl.sql.Result</a></code>
interface. This object provides properties for accessing the rows, column names,
and size of the query’s result set. When using dot notation as in the above
example, '<code>categories.rows</code>' is translated in Java to
'<code>categories.getRows()</code>'.</p></li>
<li>Integrate the <code>&lt;c:forEach&gt;</code> tags into the page. You can nest
the <code>&lt;div class=&quot;categoryBox&quot;&gt;</code> tags within the
<code>forEach</code> loop so that HTML markup is generated for each of the four
categories. Use EL syntax to extract the <code>category</code> table's <code>id</code>
and <code>name</code> column values for each of the four records. Make sure to
delete the other <code>&lt;div class=&quot;categoryBox&quot;&gt;</code> tags which
exist outside the <code>forEach</code> loop. When you finish, the complete
<code>index.jsp</code> file will look as follows. (<code>&lt;c:forEach&gt;</code>
tags and contents are displayed in <strong>bold</strong>.)
<pre class="examplecode">
&lt;%@taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot;%&gt;
&lt;%@taglib prefix=&quot;sql&quot; uri=&quot;http://java.sun.com/jsp/jstl/sql&quot;%&gt;
&lt;%--
Document : index
Created on : Sep 5, 2009, 4:32:42 PM
Author : nbuser
--%&gt;
&lt;sql:query var=&quot;categories&quot; dataSource=&quot;jdbc/affablebean&quot;&gt;
SELECT * FROM category
&lt;/sql:query&gt;
&lt;div id=&quot;indexLeftColumn&quot;&gt;
&lt;div id=&quot;welcomeText&quot;&gt;
&lt;p&gt;[ welcome text ]&lt;/p&gt;
&lt;!-- test to access context parameters --&gt;
categoryImagePath: ${initParam.categoryImagePath}
productImagePath: ${initParam.productImagePath}
&lt;/div&gt;
&lt;/div&gt;
<strong>&lt;div id=&quot;indexRightColumn&quot;&gt;
&lt;c:forEach var=&quot;category&quot; items=&quot;${categories.rows}&quot;&gt;
&lt;div class=&quot;categoryBox&quot;&gt;
&lt;a href=&quot;category?${category.id}&quot;&gt;
&lt;span class=&quot;categoryLabelText&quot;&gt;${category.name}&lt;/span&gt;
&lt;img src=&quot;${initParam.categoryImagePath}${category.name}.jpg&quot;
alt=&quot;${category.name}&quot;&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/c:forEach&gt;
&lt;/div&gt;</strong></pre></li>
<li>Click the Run Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) button. The project's index page opens in the browser,
and you see the names and images of the four categories.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/index-category-images.png"
class="margin-around b-all" style="width:688px" alt="Category images displayed in index page in browser"
title="'for each' loop extracts details from the database and utilizes them in the page"></li>
<li>Click any of the four images in the browser. The category page displays.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/category-page.png"
class="margin-around b-all" style="width:688px" alt="Category page in browser"
title="Category images from index page link to category page">
<br>
To understand how linking takes place between the index and category pages,
reexamine the HTML anchor tags within the <code>forEach</code> loop:
<pre class="examplecode">&lt;a href=&quot;category?${category.id}&quot;&gt;</pre>
When a user clicks the image link in the browser, a request for '<code>category</code>'
is sent to the application's context root on the server. In your development environment,
the URL is:
<pre class="examplecode">http://localhost:8080/AffableBean/category</pre>
which can be explained as follows:
<ul style="margin: 5px 0 0 -1em">
<li><code>http://localhost:8080</code>: The default location of the GlassFish server on your computer</li>
<li><code>/AffableBean</code>: The context root of your deployed application</li>
<li><code>/category</code>: The path to the request</li>
</ul>
Recall that in <a href="page-views-controller.html#controller">Preparing the Page
Views and Controller Servlet</a>, you mapped a request for '<code>/category</code>'
to the <code>ControllerServlet</code>. Currently, the <code>ControllerServlet</code>
internally forwards the request to <code>/WEB-INF/view/category.jsp</code>, which
is why the category page displays upon clicking an image link.
<br><br>
<p class="tips">You can verify the application's context root by expanding the Configuration
Files node in the Projects window, and opening the <code>sun-web.xml</code> file. The
<code>sun-web.xml</code> file is a deployment descriptor specific to GlassFish.</p>
<br>
Also, note that a question mark (<code>?</code>) and category ID are appended to
the requested URL.
<pre class="examplecode">&lt;a href=&quot;category<strong>?${category.id}</strong>&quot;&gt;</pre>
This forms the <em>query string</em>. As is demonstrated in the next section,
you can apply <code>(pageContext.request.queryString}</code> to extract the value
of the query string from the request. You can then use the category ID from the
query string to determine which category details need to be included in the
response.</li>
</ol>
<h3 id="categoryJSTL">category page</h3>
<p>Three aspects of the category page need to be handled dynamically. The left column
must indicate which category is selected, the table heading must display the name
of the selected category, and the table must list product details pertaining to
the selected category. In order to implement these aspects using JSTL, you can
follow a simple, 2-step pattern:</p>
<ol style="margin: 5px 0 0 -1em">
<li>Retrieve data from the database using the JSTL <code>sql</code> tag library.</li>
<li>Display the data using the JSTL <code>core</code> library and EL syntax.</li>
</ol>
<p>Tackle each of the three tasks individually.</p>
<h4>Display selected category in left column</h4>
<ol>
<li>In the Projects window, double-click the <code>category.jsp</code> node to open
it in the editor. (If already opened, press Ctrl-Tab to select it in the editor.)</li>
<li>Add the following SQL query to the top of the file.
<pre class="examplecode">
&lt;sql:query var=&quot;categories&quot; dataSource=&quot;jdbc/affablebean&quot;&gt;
SELECT * FROM category
&lt;/sql:query&gt;</pre>
Either use the Insert DB Query dialog as <a href="#categoryIndex">described above</a>,
or use the editor's code suggestion and completion facilities by pressing Ctrl-Space
while typing.</li>
<li>Between the <code>&lt;div id=&quot;categoryLeftColumn&quot;&gt;</code> tags,
replace the existing static placeholder content with the following
<code>&lt;c:forEach&gt;</code> loop.
<pre class="examplecode">
&lt;div id=&quot;categoryLeftColumn&quot;&gt;
<strong>&lt;c:forEach var=&quot;category&quot; items=&quot;${categories.rows}&quot;&gt;
&lt;c:choose&gt;
&lt;c:when test=&quot;${category.id == pageContext.request.queryString}&quot;&gt;
&lt;div class=&quot;categoryButton&quot; id=&quot;selectedCategory&quot;&gt;
&lt;span class=&quot;categoryText&quot;&gt;
${category.name}
&lt;/span&gt;
&lt;/div&gt;
&lt;/c:when&gt;
&lt;c:otherwise&gt;
&lt;a href=&quot;category?${category.id}&quot; class=&quot;categoryButton&quot;&gt;
&lt;div class=&quot;categoryText&quot;&gt;
${category.name}
&lt;/div&gt;
&lt;/a&gt;
&lt;/c:otherwise&gt;
&lt;/c:choose&gt;
&lt;/c:forEach&gt;</strong>
&lt;/div&gt;</pre>
In the above snippet, you access the request's query string using
'<code>pageContext.request.queryString</code>'. <code>pageContext</code>
is another <a href="http://download.oracle.com/docs/cd/E17477_01/javaee/5/tutorial/doc/bnahq.html#bnaij" target="_blank">implicit
object</a> defined by the JSP Expression Language. The EL expression uses the
<code><a href="http://java.sun.com/webservices/docs/1.6/api/javax/servlet/jsp/PageContext.html" target="_blank">PageContext</a></code>
to access the current request (an <code><a href="http://java.sun.com/webservices/docs/1.6/api/javax/servlet/http/HttpServletRequest.html" target="_blank">HttpServletRequest</a></code>
object). From <code>HttpServletRequest</code>, the <code>getQueryString()</code>
method is called to obtain the value of the request's query string.</li>
<li>Make sure to add the JSTL <code>core</code> and <code>sql</code> <code>taglib</code>
directives to the top of the page. (This is done automatically when using the
editor's code suggestion and completion facilities.)
<pre class="examplecode">
&lt;%@taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot;%&gt;
&lt;%@taglib prefix=&quot;sql&quot; uri=&quot;http://java.sun.com/jsp/jstl/sql&quot;%&gt;</pre></li>
<li>Run the project. In the browser, navigate to the category page and click
the category buttons in the left column. Each time you click, the page refreshes
highlighting the selected category.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/category-page-bakery.png"
class="margin-around b-all" style="width:688px" alt="Category page with bakery category selected"
title="Select categories by clicking category buttons in the left column">
<br>
Also, note that the ID of the selected category is displayed in the page's URL.
(In the above image, the bakery category is selected, and '<code>3</code>' is
appended to the URL in the browser's navigation toolbar.)
<br><br>
<p class="tips">Your servlet container (i.e., GlassFish) converts JSP pages
into servlets before running them as part of a project. You can view the
generated servlet for a JSP page by right-clicking the page node in the
Projects window and choosing View Servlet. Of course, you first need to
run the project so that the servlet is generated. Taking the <code>index.jsp</code>
file as an example, when you choose View Servlet, the IDE displays a read-only
copy of the generated servlet, <code>index_jsp.java</code>, in the editor.
The servlet exists on the server at:
<code><em>&lt;gf-install-dir&gt;</em>/glassfish/domains/domain1/generated/jsp/AffableBean/org/apache/jsp/index_jsp.java</code>.</p></li>
</ol>
<div class="indent">
<div class="feedback-box float-left" style="width: 703px;">
<h3>Examining Implicit Object Values using the IDE's Debugger</h3>
<p>You can use the IDE's Java debugger to examine values for implicit objects.
To do so, set a breakpoint on a line containing JSP or JSTL syntax in a
JSP page, then run the debugger. When the debugger suspends on the breakpoint,
you can open the Variables window (Window &gt; Debugging &gt; Variables)
to inspect values currently held by the application.</p>
<p>Taking your current implementation of <code>category.jsp</code> as an
example, perform the following steps:</p>
<ol>
<li>Set a breakpoint on the line containing:
<pre>&lt;c:when test=&quot;${category.id == pageContext.request.queryString}&quot;&gt;</pre>
(To set a breakpoint, click in the left margin of the line. A breakpoint
( <img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/breakpoint-icon.png"
alt="Breakpoint icon"> ) icon displays.)</li>
<li>In the IDE's main toolbar, click the Debug Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/debug-project-btn.png"
alt="Debug Project button"> ) button. A debugging session is
activated for the project, and the application's index page opens
in the browser.</li>
<li>Click the bakery category in the index page. (You know that the
ID for the bakery category is '<code>3</code>').</li>
<li>Return to the IDE, and note that the debugger is suspended on the
line containing the breakpoint. When suspended, the margin shows
a green arrow on the breakpoint (
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/debugger-suspended-icon.png"
alt="Debug Project button"> ), and the line displays with green background.</li>
<li>Open the Variables window (Ctrl-Shift-1) and expand the Implicit Objects &gt;
pageContext &gt; request &gt; queryString node. Inspect the variable value
and note that the value is '<code>3</code>', corresponding to the category ID
from your selection.</li>
<li>Press the Finish Debugger Session (
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/finish-debugger-session-btn.png"
alt="Finish Debuger Session button"> ) button to terminate the debugger session.</li>
</ol>
</div>
</div>
<br style="clear: left"/>
<h4>Display title heading above product table</h4>
<ol>
<li>Add the following SQL query to the top of the file, underneath the query you
just implemented. (New query is shown in <strong>bold</strong>.)
<pre class="examplecode">
&lt;sql:query var=&quot;categories&quot; dataSource=&quot;jdbc/affablebean&quot;&gt;
SELECT * FROM category
&lt;/sql:query&gt;
<strong>&lt;sql:query var=&quot;selectedCategory&quot; dataSource=&quot;jdbc/affablebean&quot;&gt;
SELECT name FROM category WHERE id = ?
&lt;sql:param value=&quot;${pageContext.request.queryString}&quot;/&gt;
&lt;/sql:query&gt;</strong></pre></li>
<li>Use JSP EL syntax to extract the category name from the query and
display it in the page. Make the following change to the
<code>&lt;p id=&quot;categoryTitle&quot;&gt;</code> element.
(Displayed in <strong>bold</strong>.)
<pre class="examplecode">
&lt;p id=&quot;categoryTitle&quot;&gt;<strong>${selectedCategory.rows[0].name}</strong>&lt;/p&gt;</pre>
Since the result from the <code>selectedCategory</code> query contains
only one item (i.e., user can select only one category), you can retrieve
the first row of the result set using '<code>selectedCategory<strong>.rows[0]</strong></code>'.
If a user selects the 'meats' category for example, the returned expression
would be '<code>{name=meats}</code>'. You could then access the category name
with '<code>${selectedCategory.rows[0]<strong>.name</strong>}</code>'.</li>
<li>Save (Ctrl-S; &#8984;-S on Mac) changes made to the file.</li>
<li>Return to the browser and refresh the category page. The name of
the selected category now displays above the product table.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/category-page-bakery-title.png"
class="margin-around b-all" style="width:688px" alt="Category page with bakery title displayed over product table"
title="The name of the selected category dynamically displays above the product table">
<br>
<p class="notes"><strong>Note:</strong> As demonstrated in this and the
previous step, you do not need to explicitly recompile, deploy, and run
the project with each change to your code base. The IDE provides a Deploy
on on Save feature, which is enabled for Java web projects by default.
To verify that the feature is activated, right-click your project node
in the Projects window and choose Properties. In the Project Properties
window, click the Run category and examine the 'Deploy on Save' option.</p></li>
</ol>
<h4>Display product details within the table</h4>
<ol>
<li>Add the following SQL query to the top of the file, underneath the previous
queries you implemented. (New query is shown in <strong>bold</strong>.)
<pre class="examplecode">
&lt;sql:query var=&quot;categories&quot; dataSource=&quot;jdbc/affablebean&quot;&gt;
SELECT * FROM category
&lt;/sql:query&gt;
&lt;sql:query var=&quot;selectedCategory&quot; dataSource=&quot;jdbc/affablebean&quot;&gt;
SELECT name FROM category WHERE id = ?
&lt;sql:param value=&quot;${pageContext.request.queryString}&quot;/&gt;
&lt;/sql:query&gt;
<strong>&lt;sql:query var=&quot;categoryProducts&quot; dataSource=&quot;jdbc/affablebean&quot;&gt;
SELECT * FROM product WHERE category_id = ?
&lt;sql:param value=&quot;${pageContext.request.queryString}&quot;/&gt;
&lt;/sql:query&gt;</strong></pre></li>
<li>Between the <code>&lt;table id=&quot;productTable&quot;&gt;</code> tags,
replace the existing static table row placeholders (<code>&lt;tr&gt;</code>
tags) with the following <code>&lt;c:forEach&gt;</code> loop.
(Changes are displayed in <strong>bold</strong>.)
<pre class="examplecode">
&lt;table id=&quot;productTable&quot;&gt;
<strong>&lt;c:forEach var=&quot;product&quot; items=&quot;${categoryProducts.rows}&quot; varStatus=&quot;iter&quot;&gt;
&lt;tr class=&quot;${((iter.index % 2) == 0) ? 'lightBlue' : 'white'}&quot;&gt;
&lt;td&gt;
&lt;img src=&quot;${initParam.productImagePath}${product.name}.png&quot;
alt=&quot;${product.name}&quot;&gt;
&lt;/td&gt;
&lt;td&gt;
${product.name}
&lt;br&gt;
&lt;span class=&quot;smallText&quot;&gt;${product.description}&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&amp;euro; ${product.price} / unit
&lt;/td&gt;
&lt;td&gt;
&lt;form action=&quot;addToCart&quot; method=&quot;post&quot;&gt;
&lt;input type=&quot;hidden&quot;
name=&quot;productId&quot;
value=&quot;${product.id}&quot;&gt;
&lt;input type=&quot;submit&quot;
value=&quot;add to cart&quot;&gt;
&lt;/form&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/c:forEach&gt;</strong>
&lt;/table&gt;</pre>
Note that in the above snippet an EL expression is used to determine the background
color for table rows:
<pre class="examplecode">class=&quot;${((iter.index % 2) == 0) ? 'lightBlue' : 'white'}&quot;</pre>
The API documentation for the <code><a href="http://java.sun.com/products/jsp/jstl/1.1/docs/tlddocs/c/forEach.html" target="_blank">&lt;c:forEach&gt;</a></code>
tag indicates that the <code>varStatus</code> attribute represents an object
that implements the
<code><a href="http://java.sun.com/products/jsp/jstl/1.1/docs/api/javax/servlet/jsp/jstl/core/LoopTagStatus.html" target="_blank">LoopTagStatus</a></code>
interface. Therefore, <code>iter.index</code> retrieves the index of the current
round of the iteration. Continuing with the expression, <code>(iter.index % 2) == 0)</code>
evaluates the remainder when <code>iter.index</code> is divided by <code>2</code>,
and returns a boolean value based on the outcome. Finally, an EL conditional operator
(<code>? :</code>) is used to set the returned value to '<code>lightBlue</code>' if true,
'<code>white</code>' otherwise.
<br><br>
<p class="tips">For a description of JSP Expression Language operators, see the
Java EE 5 Tutorial: <a href="http://download.oracle.com/docs/cd/E17477_01/javaee/5/tutorial/doc/bnahq.html#bnaik" target="_blank">JavaServer
Pages Technology &gt; Unified Expression Language &gt; Operators</a>.</p></li>
<li>Save (Ctrl-S; &#8984;-S on Mac) changes made to the file.</li>
<li>Return to the browser and refresh the category page. Product details
now display within the table for the selected category.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/category-page-bakery-product-table.png"
class="margin-around b-all" style="width:688px" alt="Category page displaying products for selected category"
title="Product details are dynamically displayed for the selected category"></li>
</ol>
<p>You have now completed this tutorial unit. In it, you explored how to connect your
application to the database by setting up a connection pool and data source on the
server, then referenced the data source from the application. You also created several
context parameters, and learned how to access them from JSP pages. Finally, you
implemented JSTL tags into the application's web pages in order to dynamically
retrieve and display database data.</p>
<p>You can download and examine <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot3.zip">snapshot
3</a> if you'd like to compare your work with the solution project. The solution project
contains enhancements to the HTML markup and stylesheet in order to properly display all
provided images. It also provides welcome page text, and a basic implementation for the
page footer.</p>
</div>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans E-commerce Tutorial - Connecting the Application to the Database">Send
Us Your Feedback</a></div>
<br style="clear:both;">
<h2 id="troubleshoot">Troubleshooting</h2>
<p>If you are having problems, see the troubleshooting tips below. If you continue to have difficulty,
or would like to provide constructive feedback, use the Send us Your Feedback link.</p>
<ul>
<li>You receive the following exception:
<pre class="examplecode" style="width: 700px">
org.apache.jasper.JasperException: PWC6188: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application</pre>
This is a <a href="https://netbeans.org/bugzilla/show_bug.cgi?id=188406" target="_blank">known
issue</a> for NetBeans IDE 6.9. Try to deploy the project, then access the file by typing its
URL in the browser. For example, if you are trying to view <code>testDataSource.jsp</code> in
a browser, enter '<code>http://localhost:8080/AffableBean/test/testDataSource.jsp</code>' in
the browser's URL field directly. Otherwise, add the IDE's JSTL 1.1 library to the project. In
the Projects window, right-click the Libraries node and choose Add Library. Select JSTL 1.1.
For more information, see:
<a href="http://forums.netbeans.org/topic28571.html" target="_blank">http://forums.netbeans.org/topic28571.html</a>.</li>
<li>You receive the following exception:
<pre class="examplecode" style="width: 700px">javax.servlet.ServletException: javax.servlet.jsp.JspException: Unable to get connection, DataSource invalid: "java.sql.SQLException: Error in allocating a connection. Cause: Class name is wrong or classpath is not set for : com.mysql.jdbc.jdbc2.optional.MysqlDataSource"</pre>
This can occur when the MySQL driver has not been added to the domain <code>lib</code>
folder. (Note that after adding, it is necessary to restart the server if it is already
running.)</li>
<li>You receive the following exception:
<pre class="examplecode" style="width: 700px">javax.servlet.ServletException: javax.servlet.jsp.JspException: Unable to get connection, DataSource invalid: "java.sql.SQLException: No suitable driver found for jdbc/affablebean"</pre>
This can occur when the <code>jdbc/affablebean</code> resource reference hasn't been
added to the <code>web.xml</code> deployment descriptor.</li>
<li>You receive the following exception:
<pre class="examplecode" style="width: 700px">javax.servlet.ServletException: javax.servlet.jsp.JspException: Unable to get connection, DataSource invalid: "java.sql.SQLException: Error in allocating a connection. Cause: Connection could not be allocated because: Access denied for user 'root'@'localhost' (using password: YES)"</pre>
This can occur when you are using an incorrect username/password combination. Make sure
the username and password you use to connect to the MySQL server are correctly set for
your connection pool in the <code>sun-resources.xml</code> file. Also, check that the
username and password are correctly set for the connection pool in the GlassFish
Administration Console.</li>
</ul>
<br>
<h2 id="seeAlsoConnectDb">See Also</h2>
<div class="indent">
<h3>NetBeans Resources</h3>
<ul>
<li><a href="../../ide/mysql.html" target="_blank">Connecting to a MySQL Database</a></li>
<li><a href="../../web/quickstart-webapps.html" target="_blank">Introduction to Developing Web Applications</a></li>
<li><a href="../../web/mysql-webapp.html" target="_blank">Creating a Simple Web Application Using a MySQL Database</a></li>
<li><a href="../../ide/database-improvements-screencast.html" target="_blank">Screencast: Database Support in NetBeans IDE</a></li>
</ul>
<h3>MySQL Resources</h3>
<ul>
<li><a href="http://dev.mysql.com/librarian/" target="_blank">The MySQL Community Librarian</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/" target="_blank">MySQL 5.1 Reference Manual</a></li>
<li><a href="http://www.mysql.com/why-mysql/java/#howtos" target="_blank">MySQL and Java</a></li>
<li><a href="http://forums.mysql.com/" target="_blank">MySQL Forums</a></li>
</ul>
<h3>JSP & EL Resources</h3>
<ul>
<li><strong>Product Page:</strong> <a href="http://java.sun.com/products/jsp/" target="_blank">JavaServer Pages Technology</a></li>
<li><strong>Specification Download:</strong> <a href="http://jcp.org/aboutJava/communityprocess/mrel/jsr245/index.html" target="_blank">JSR 245: JSP and EL 2.2 Maintenance Release</a></li>
<li><strong>API Documentation:</strong> <a href="http://java.sun.com/products/jsp/2.1/docs/jsp-2_1-pfd2/index.html" target="_blank">JavaServer Pages 2.1 API Documentation</a></li>
<li><strong>Supporting Documentation:</strong> <a href="http://download.oracle.com/docs/cd/E17477_01/javaee/5/tutorial/doc/bnagx.html" target="_blank">Java EE 5 Tutorial - Chapter 5: JavaServer Pages Technology</a></li>
<li><strong>Syntax Reference:</strong> <a href="http://java.sun.com/products/jsp/syntax/2.0/syntaxref20.html" target="_blank">JavaServer Pages 2.0 Syntax Reference</a></li>
<li><strong>Official Forum:</strong> <a href="http://forums.sun.com/forum.jspa?forumID=45" target="_blank">Web Tier APIs - JavaServer Pages (JSP) and JSTL</a></li>
</ul>
<h3>JSTL Resources</h3>
<ul>
<li><strong>Product Page:</strong> <a href="http://java.sun.com/products/jsp/jstl/" target="_blank">JavaServer Pages Standard Tag Library</a></li>
<li><strong>Specification Download:</strong> <a href="http://jcp.org/aboutJava/communityprocess/final/jsr052/index2.html" target="_blank">JSR 52: JSTL 1.2 Maintenance Release</a></li>
<li><strong>Implementation Download:</strong> <a href="http://jstl.dev.java.net/download.html" target="_blank">GlassFish JSTL Project Download</a></li>
<li><strong>Tag Library Documentation:</strong> <a href="http://java.sun.com/products/jsp/jstl/1.1/docs/tlddocs/index.html" target="_blank">JSTL 1.1 Tag Reference</a></li>
<li><strong>API Documentation:</strong> <a href="http://java.sun.com/products/jsp/jstl/1.1/docs/api/index.html" target="_blank">JSTL 1.1 API Reference</a></li>
</ul>
<h3>Technical Articles & Reference Cards</h3>
<ul>
<li><a href="http://java.sun.com/developer/technicalArticles/javaserverpages/JSP20/" target="_blank">Developing Web Applications With JavaServer Pages 2.0</a></li>
<li><a href="http://java.sun.com/developer/technicalArticles/J2EE/jsp_21/" target="_blank">Web Tier to Go With Java EE 5: Summary of New Features in JSP 2.1 Technology</a></li>
<li><a href="http://java.sun.com/products/jsp/reference/techart/unifiedEL.html" target="_blank">Unified Expression Language</a></li>
<li><a href="http://today.java.net/pub/a/today/2003/10/07/jstl1.html" target="_blank">Practical JSTL, Part 1</a></li>
<li><a href="http://www.ibm.com/developerworks/java/library/j-jstl0520/index.html" target="_blank">A JSTL primer, Part 4: Accessing SQL and XML content</a></li>
<li><a href="http://java.sun.com/products/jsp/syntax/2.0/card20.pdf">JavaServer Pages v2.0 Syntax Card</a></li>
<li><a href="http://refcardz.dzone.com/refcardz/essential-jsp-expression" target="_blank">Essential JSP Expression Language Reference Card</a></li>
<li><a href="http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/jdbc/index.html" target="_blank">The Java Tutorials: JDBC Database Access</a></li>
<li><a href="http://java.sun.com/developer/Books/jdbc/" target="_blank">Database Programming with JDBC and Java, Second Edition</a></li>
<li><a href="http://refcardz.dzone.com/refcardz/essential-jsp-expression" target="_blank">Essential JSP Expression Language Reference Card</a></li>
<li><a href="http://java.sun.com/products/jndi/tutorial/" target="_blank">The JNDI Tutorial</a></li>
</ul>
</div>
<br><br><br><br>
<h1 id="entity-session">The NetBeans E-commerce Tutorial - Adding Entity Classes and Session Beans</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Tutorial Contents</h4>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#design">Designing the Application</a></li>
<li><a href="#setup-dev-environ">Setting up the Development Environment</a></li>
<li><a href="#data-model">Designing the Data Model</a></li>
<li><a href="#page-views-controller">Preparing the Page Views and Controller Servlet</a></li>
<li><a href="#connect-db">Connecting the Application to the Database</a></li>
<li><strong>Adding Entity Classes and Session Beans</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#whatEJB">What are EJB and JPA Technologies?</a></li>
<li><a href="#whatSession">What are Session Beans?</a></li>
<li><a href="#specification">About Specifications and Implementations</a></li>
<li><a href="#addEntity">Adding Entity Classes</a></li>
<li><a href="#addSession">Adding Session Beans</a></li>
<li><a href="#access">Accessing Data with EJBs</a></li>
<li><a href="#seeAlsoEntitySession">See Also</a></li>
</ul></li>
<li><a href="#manage-sessions">Managing Sessions</a></li>
<li><a href="#transaction">Integrating Transactional Business Logic</a></li>
<li><a href="#language">Adding Language Support</a></li>
<li><a href="#security">Securing the Application</a></li>
<li><a href="#test-profile">Testing and Profiling</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ol>
</div>
</div>
<p><img src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" class="stamp"
alt="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"
title="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"></p>
<p>This tutorial unit introduces the <a href="http://java.sun.com/products/ejb/" target="_blank">Enterprise
JavaBeans</a> (EJB) and <a href="http://java.sun.com/javaee/technologies/persistence.jsp" target="_blank">Java
Persistence</a> (JPA) technologies. In it, you use two of the IDE's wizards that are essential
to Java EE development. These are:</p>
<ul style="margin-left: 320px">
<li><strong>Entity Classes from Database wizard:</strong> Creates a Java Persistence API
entity class for each selected database table, complete with named query annotations,
fields representing columns, and relationships representing foreign keys.</li>
<li><strong>Session Beans for Entity Classes wizard:</strong> Creates an EJB session facade
for each entity class with basic access methods.</li>
</ul>
<p>These two wizards provide an efficient way for you to quickly set up the model for your
application. If you reexamine the <a href="design.html#mvcDiagram">MVC diagram</a> for
the application you are building, you can see where EJB session beans and JPA entity
classes fit into its structure.</p>
<div class="indent" style="text-align: center">
<img src="../../../../images_www/articles/73/javaee/ecommerce/design/mvc-diagram.png"
style="width:596px; margin-top:10px; margin-bottom:10px"
title="MVC diagram of the AffableBean application"
alt="MVC diagram of the AffableBean application">
</div>
<p>In this unit, the entity classes you create form a Java-based representation of the <code>affablebean</code>
database. While each entity class represents a database table, instances of entity classes
correspond to records that can be saved (i.e., <em>persisted</em>) to the database. The business
logic of the application is encapsulated by session beans, which can either be used as <em>facade</em>
classes that enable CRUD (Create-Read-Update-Delete) access to entities (as demonstrated here),
or they can contain code that implements actions specific to your application. (An example of this
is provided in <a href="#transaction">Unit 9: Integrating Transactional Business Logic</a>).</p>
<p>You can view a live demo of the application that you build in this tutorial:
<a href="http://services.netbeans.org/AffableBean/" target="_blank">NetBeans E-commerce
Tutorial Demo Application</a>.</p>
<br style="clear:left;">
<br>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html" target="_blank">NetBeans IDE</a></td>
<td class="tbltd1">Java bundle, 6.8 or 6.9</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank">Java Development Kit (JDK)</a></td>
<td class="tbltd1">version 6</td>
</tr>
<tr>
<td class="tbltd1"><a href="#glassFishEntitySession">GlassFish server</a></td>
<td class="tbltd1">v3 or Open Source Edition 3.0.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://dev.mysql.com/downloads/mysql/" target="_blank">MySQL database server</a></td>
<td class="tbltd1">version 5.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot3.zip">AffableBean
project</a></td>
<td class="tbltd1">snapshot 3</td>
</tr>
</tbody>
</table>
<p><strong class="notes">Notes:</strong></p>
<ul>
<li>The NetBeans IDE requires the Java Development Kit (JDK) to run properly.
If you do not have any of the resources listed above, the JDK should be
the first item that you download and install.</li>
<li>The NetBeans IDE Java Bundle includes Java Web and EE technologies, which are
required for the application you build in this tutorial.</li>
<li id="glassFishEntitySession">The NetBeans IDE Java Bundle also includes the GlassFish server,
which you require for this tutorial. You could
<a href="http://glassfish.dev.java.net/public/downloadsindex.html" target="_blank">download
the GlassFish server independently</a>, but the version provided with the
NetBeans download has the added benefit of being automatically registered with
the IDE.</li>
<li>You can follow this tutorial unit without having completed previous units. To
do so, see the <a href="#setup">setup instructions</a>, which describe how
to prepare the database and establish connectivity between the IDE, GlassFish,
and MySQL.</li>
<li><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot4.zip">Snapshot
4</a> of the <code>AffableBean</code> project is available for download and
corresponds to state the project after completing this unit using NetBeans IDE
6.9.</li>
</ul>
<br>
<h2 id="whatEJB">What are EJB and JPA Technologies?</h2>
<p>Up until now, the project that you've been developing in this tutorial could be run
in a web server with a servlet container, such as Apache Tomcat. After all, you've
so far only made use of JSTL and servlet technologies, and are connecting to the
database directly using JDBC. In fact, you could theoretically continue to develop
the application using just these technologies, while manually coding for all aspects
of your application, including thread-safety, transactions, and security. However,
using Enterprise beans with JPA entity classes allows you focus on the business logic
of your application while relying on solutions that have already been tried and tested.
The following sections introduce the two technologies and define their role in EE
development.</p>
<ul>
<li><a href="#ejb">Enterprise JavaBeans</a></li>
<li><a href="#jpa">Java Persistence</a></li>
</ul>
<div class="indent">
<h3 id="ejb">Enterprise JavaBeans</h3>
<p>The official <a href="http://java.sun.com/products/ejb/" target="_blank">EJB product
page</a> describes EnterPrise JavaBeans technology as a &quot;server-side component
architecture&quot; that &quot;enables rapid and simplified development of distributed,
transactional, secure and portable applications.&quot; You can apply EJBs (i.e.,
Enterprise beans) to your projects, and the services provided by the technology
remain transparent to you as a developer, thus eliminating the tedious and often
error-prone task of adding a lot of boiler plate code which would otherwise be
required. If you are new to EE development, you may question the need for EJBs in
your Java web application. The book
<a href="http://www.manning.com/panda/" target="_blank">EJB 3 In Action</a>, by Debu
Panda, Reza Rahman and Derek Lane, paraphrases the role of EJB technology nicely:</p>
<blockquote style="margin-top: 0">
<em>Although many people think EJBs are overkill for developing relatively
simple web applications of moderate size, nothing could be further from
the truth. When you build a house, you don't build everything from scratch.
Instead, you buy materials or even the services of a contractor as you need
it. It isn't too practical to build an enterprise application from scratch
either. Most server-side applications have a lot in common, including churning
business logic, managing application state, storing and retrieving information
from a relational database, managing transactions, implementing security,
performing asynchronous processing, integrating systems, and so on.
<br><br>
As a framework, the EJB container provides these kinds of common functionality
as out-of-the-box services so that your EJB components can use them in your
applications without reinventing the wheel. For instance, let's say that when
you build a credit card module in your web application, you write a lot of
complex and error-prone code to manage transactions and security access control.
You could have avoided that by using the declarative transaction and security
services provided by the EJB container. These services as well as many others
are available to EJB components when they are deployed in an EJB container.
This means writing high-quality, feature-rich applications much faster than
you might think.</em><sup><a href="#footnote1EntitySession" id="1EntitySession"
style="text-decoration:none">[1]</a></sup>
</blockquote>
<p>You can think of EJB both as components, or Java classes that are incorporated in
your project, as well as a <em>framework</em> that provides numerous enterprise-related
services. Some of the services that we take advantage of in this tutorial are described
in <a href="http://www.manning.com/panda/" target="_blank">EJB 3 In Action</a> as follows:</p>
<ul>
<li><strong>Pooling:</strong> For each EJB component, the EJB platform creates
a pool of component instances that are shared by clients. At any point in
time, each pooled instance is only allowed to be used by a single client.
As soon as an instance is finished servicing a client, it is returned to
the pool for reuse instead of being frivolously discarded for the garbage
collector to reclaim.</li>
<li><strong>Thread Safety:</strong> EJB makes all components thread-safe and
highly performant in ways athat are completely invisible. This means that
you can write your server components as if you were developing a single-threaded
desktop application. It doesn't matter how complex the component itself is;
EJB will make sure it is thread-safe.</li>
<li><strong>Transactions:</strong> EJB supports declarative transaction management
that helps you add transactional behavior to components using simple
configuration instead of code. In effect, you can designate any component
method to be transactional. If the method completes normally, EJB commits
the transaction and makes the data changes made by the method permanent.
Otherwise the transaction is rolled back. Container-managed EJB transactions
are demonstrated in Unit 9, <a href="#transaction">Integrating Transactional
Business Logic</a>.</li>
<li><strong>Security:</strong> EJB supports integration with the Java Authentication
and Authorization Service (JAAS) API, so it is easy to completely externalize
security and secure an application using simple configuration instead of cluttering
up your application with security code.<sup><a href="#footnote2EntitySession" id="2EntitySession"
style="text-decoration:none">[2]</a></sup> In Unit 11, <a href="security.html#secureEJB">Securing
the Application</a>, a demonstration of EJB's <a href="http://download.oracle.com/javaee/6/api/javax/annotation/security/RolesAllowed.html"
target="_blank"<code>@RolesAllowed</code></a> annotation is provided.</li>
</ul>
<h3 id="jpa">Java Persistence</h3>
<p>In the context of Java Enterprise, <em>persistence</em> refers to the act of
automatically storing data contained in Java objects into a relational database.
The <a href="http://java.sun.com/javaee/technologies/persistence.jsp" target="_blank">Java
Persistence API</a> (JPA) is an object-relational mapping (ORM) technology that
enables applications to manage data between Java objects and a relational database
in a way that is transparent to the developer. This means that you can apply
JPA to your projects by creating and configuring a set of Java classes (<em>entities</em>)
that mirror your data model. Your application can then access these entities
as though it were directly accessing the database.</p>
<p>There are various benefits to using JPA in your projects:</p>
<ul>
<li>JPA has its own rich, SQL-like query language for static and dynamic queries.
Using the Java Persistence Query Language (JPQL), your applications remain
portable across different database vendors.</li>
<li>You can avoid the task of writing low-level, verbose and error-prone JDBC/SQL code.</li>
<li>JPA transparently provides services for data caching and performance optimization.</li>
</ul>
</div>
<br>
<h2 id="whatSession">What are Session Beans?</h2>
<p>Enterprise session beans are invoked by a client in order to perform a specific business
operation. The name <em>session</em> implies that a bean instance is available for the
duration of a &quot;unit of work&quot;. The <a href="http://jcp.org/aboutJava/communityprocess/final/jsr318/index.html" target="_blank">EJB
3.1 specification</a> describes a typical session object as having the following
characteristics:</p>
<ul class="toc">
<li>Executes on behalf of a single client</li>
<li>Can be transaction-aware</li>
<li>Updates shared data in an underlying database</li>
<li>Does not represent directly shared data in the database, although it may
access and update such data</li>
<li>Is relatively short-lived</li>
<li>Is removed when the EJB container crashes. The client has to re-establish
a new session object to continue computation.</li>
</ul>
<p>EJB provides three types of session beans: <em>stateful</em>, <em>stateless</em>,
and <em>singleton</em>. The following descriptions are adapted from the
<a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/tutorial/doc/index.html" target="_blank">Java
EE 6 Tutorial</a>.</p>
<ul>
<li><strong>Stateful:</strong> The state of the bean is maintained across multiple
method calls. The &quot;state&quot; refers to the values of its instance variables.
Because the client interacts with the bean, this state is often called the
<em>conversational</em> state.</li>
<li><strong>Stateless:</strong> Stateless beans are used for operations that can
occur in a single method call. When the method finishes processing, the
client-specific state of the bean is not retained. A stateless session bean
therefore does not maintain a conversational state with the client.</li>
<li><strong>Singleton:</strong> A singleton session bean is instantiated once
per application, and exists for the lifecycle of the application. Singleton
session beans are designed for circumstances where a single enterprise bean
instance is shared across and concurrently accessed by clients.</li>
</ul>
<p class="tips">For more information on EJB session beans, see the
<a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/tutorial/doc/gipjg.html" target="_blank">Java
EE 6 Tutorial: What is a Session Bean?</a>.</p>
<p>For purposes of developing the e-commerce application in this tutorial, we will
only be working with stateless session beans.</p>
<br>
<h2 id="specification">About Specifications and Implementations</h2>
<p>EJB and JPA technologies are defined by the following specifications:</p>
<ul>
<li><a href="http://jcp.org/en/jsr/summary?id=317" target="_blank">JSR 317: Java Persistence 2.0</a></li>
<li><a href="http://jcp.org/en/jsr/summary?id=318" target="_blank">JSR 318: Enterprise JavaBeans 3.1</a></li>
</ul>
<p>These specifications define the technologies. To apply a technology to your
project however, you must use an <em>implementation</em> of the specification.
When a specification becomes finalized, it includes a reference implementation,
which is a free implementation of the technology. If you find this concept
confusing, consider the following analogy: A musical composition (i.e., the notes
on a page) defines a piece of music. When a musician learns the composition and
records her performance, she provides an <em>interpretation</em> of the piece.
In this manner the musical composition is likened to the technical specification,
and the musician's recording corresponds to the specification's implementation.</p>
<p class="tips">See <a href="intro.html#jcp">What is the Java Community Process?</a>
for an explanation of Java technical specifications, and how they are formally
standardized.</p>
<p>If you examine the download pages for the final releases of the EJB and JPA specifications,
you'll find links to the following reference implementations:</p>
<ul>
<li><strong>JPA:</strong> <a href="http://www.eclipse.org/eclipselink/downloads/ri.php" target="_blank">http://www.eclipse.org/eclipselink/downloads/ri.php</a></li>
<li><strong>EJB:</strong> <a href="http://glassfish.dev.java.net/downloads/ri" target="_blank">http://glassfish.dev.java.net/downloads/ri</a></li>
</ul>
<p>Implementations of the JPA specification are dubbed <em>persistence providers</em>,
and the persistence provider which has been chosen as the reference implementation
for the JPA 2.0 specification is <a href="http://www.eclipse.org/eclipselink/" target="_blank">EclipseLink</a>.</p>
<p>If you examine the link for the EJB reference implementation, you'll come to a page
that lists not only the implementation for EJB, but for all reference implementations
provided by <a href="http://glassfish.dev.java.net/" target="_blank">Project GlassFish</a>.
The reason for this is that Project GlassFish forms the reference implementation of the
Java EE 6 platform specification (<a href="http://jcp.org/en/jsr/summary?id=316" target="_blank">JSR
316</a>). The GlassFish v3 application server (or the Open Source Edition), which you
are using to build the e-commerce project in this tutorial, contains the reference
implementations of all technologies developed under Project GlassFish. As such, it
is referred to as a Java EE 6 <em>container</em>.</p>
<p>A Java EE container contains three essential components: a web (i.e., servlet) container,
an EJB container, and a persistence provider. The deployment scenario for the e-commerce
application is displayed in the diagram below. Entity classes that you create in this
unit are managed by the persistence provider. The session beans that you create in this
unit are managed by the EJB container. Views are rendered in JSP pages, which are
managed by the web container.</p>
<div id="gf-java-ee-container" class="indent">
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/java-ee-container.png"
class="margin-around" alt="GlassFish v3 Java EE container"
title="As a Java EE container, GlassFish v3 contains web and EJB containers, and EclipseLink, the persistence provider">
</div>
<br>
<h2 id="addEntity">Adding Entity Classes</h2>
<p>Begin by using the IDE's Entity Classes from Database wizard to generate entity classes
based on the <code>affablebean</code> schema. The wizard relies on the underlying
persistence provider to accomplish this task.</p>
<ol>
<li>Open the <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot3.zip">project
snapshot</a> in the IDE. In the IDE, press Ctrl-Shift-O (�-Shift-O on Mac) and
navigate to the location on your computer where you unzipped the downloaded file.</li>
<li>Press Ctrl-N (&#8984;-N on Mac) to open the File wizard.</li>
<li>Select the Persistence category, then select Entity Classes from Database. Click Next.</li>
<li>In Step 2: Database Tables, choose <code>jdbc/affablebean</code> from the Data Source
drop-down list. The drop-down list is populated by data sources registered with the
application server.
<br><br>
When you choose the <code>jdbc/affablebean</code> data source, the IDE scans the
database and lists the database tables in the Available Tables pane.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/entity-from-database.png"
class="margin-around b-all" alt="Entity Classes from Database wizard" style="width: 688px"
title="Choose an available data source to have the IDE read in database tables"></li>
<li>Click the Add All button, then click Next.</li>
<li>Step 3 of the Entity Classes from Database wizard differs slightly between NetBeans
IDE 6.8 and 6.9. Depending on the version IDE you are using, perform the following steps.
<ul style="margin: 5px 0 0 -1em">
<li><a href="#68">NetBeans IDE 6.8</a></li>
<li><a href="#69">NetBeans IDE 6.9</a></li>
</ul>
<h4 id="68">NetBeans IDE 6.8</h4>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/entity-classes-68.png"
class="margin-around b-all" alt="Entity Classes from Database wizard, Step 3: Entity Classes"
title="NetBeans 6.8 - Entity Classes from Database wizard, Step 3: Entity Classes" width="688px">
<ol style="list-style-type: lower-alpha">
<li>Type in <strong>entity</strong> in the Package field. The wizard will create a new
package for the entity classes upon completing.</li>
<li>Click the Create Persistence Unit button. The Create Persistence Unit dialog opens.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/create-pu.png"
class="margin-around b-all" alt="Create Persistence Unit dialog"
title="Use the Create Persistence Unit dialog to generate a persistence.xml file">
<br>
A <em>persistence unit</em> refers to a collection of entity classes that exist in an
application. The above dialog generates a <code>persistence.xml</code> file, which is
used by your persistence provider to specify configuration settings for the persistence
unit. Note that 'EclipseLink (JPA 2.0)' is the default selection for the server associated
with the project. Leave 'Table Generation Strategy' set to '<code>None</code>'. This
prevents the persistence provider from affecting your database. (For example, if you
want the persistence provider to delete then recreate the database based on the existing
entity classes, you could set the strategy to '<code>Drop and Create</code>'. This action
would then be taken each time the project is deployed.)</li>
<li>Click Create.</li>
<li>Back in Step 3: Entity Classes, note that the class names for the entities are based
on database tables. For example, the <code>CustomerOrder</code> entity is mapped to
the <code>customer_order</code> database table. Also note that the 'Generate Named
Query Annotations for Persistent Fields' option is selected by default. We will be
using various named queries later in the tutorial.</li>
<li>Continue to <a href="#step7">step 7</a> below.</li>
</ol>
<h4 id="69">NetBeans IDE 6.9</h4>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/entity-classes-69.png"
class="margin-around b-all" alt="Entity Classes from Database wizard, Step 3: Entity Classes"
title="NetBeans 6.9 - Entity Classes from Database wizard, Step 3: Entity Classes" width="688px">
<ol style="list-style-type: lower-alpha">
<li>Type in <strong>entity</strong> in the Package field. The wizard will create a new
package for the entity classes upon completing.</li>
<li>Note the following:
<ul style="margin: 5px 0 0 -2em">
<li>The class names for the entities are based on database tables. For example, the
<code>CustomerOrder</code> entity will be mapped to the <code>customer_order</code>
database table.</li>
<li>The 'Generate Named Query Annotations for Persistent Fields' option is selected by
default. We will be using various named queries later in the tutorial.</li>
<li>The 'Create Persistence Unit' option is selected by default. A <em>persistence
unit</em> is a collection of entity classes that exist in an application. The
persistence unit is defined by a <code>persistence.xml</code> configuration file,
which is read by your persistence provider. Enabling this option therefore means
that the wizard will also generate a <code>persistence.xml</code> file and populate
it with default settings.</li>
</ul>
</li>
</ol></li>
<li id="step7">Click Finish. The JPA entity classes are generated, based on the <code>affablebean</code>
database tables. You can examine the entity classes in the Projects window by expanding
the newly created <code>entity</code> package. Also, note that the new persistence unit
exists under the Configuration Files node.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/entity-classes.png"
class="margin-around b-all" alt="Projects window - entity classes displayed in project"
title="View new entity classes in the Projects window">
<br><br>
Note that the wizard generated an additional entity class, <code>OrderedProductPK</code>.
Recall that the data model's <code>ordered_product</code> table uses a composite
primary key that comprises the primary keys of both the <code>customer_order</code>
and <code>product</code> tables. (See <a href="data-model.html#manyToMany">Designing
the Data Model - Creating Many-To-Many Relationships</a>.) Because of this, the
persistence provider creates a separate entity class for the composite key, and
<em>embeds</em> it into the <code>OrderedProduct</code> entity. You can open
<code>OrderedProduct</code> in the editor to inspect it. JPA uses the <code>@EmbeddedId</code>
annotation to signify that the embeddable class is a composite primary key.
<pre class="examplecode">
public class OrderedProduct implements Serializable {
private static final long serialVersionUID = 1L;
<strong>@EmbeddedId</strong>
protected OrderedProductPK orderedProductPK;</pre>
<p class="tips">Press Ctrl-Space on the <code>@EmbeddedId</code> annotation to
invoke the API documentation.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/embedded-id.png"
class="margin-around b-all" alt="API documentation invoked on @EmbeddedId"
title="Press Ctrl-Space to invoke the API documentation"></li>
<li id="pu">Open the persistence unit (<code>persistence.xml</code>) in the editor. The
IDE provides a Design view for persistence units, in addition to the XML view. The
Design view provides a convenient way to make configuration changes to the persistence
provider's management of the project.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/persistence-unit.png"
class="margin-around b-all" alt="Design view of AffableBeanPU persistence unit" style="width: 688px"
title="Design view of the AffableBeanPU persistence unit"></li>
<li>Click the XML tab at the top of the <code>AffableBeanPU</code> persistence unit
to open the XML view. Add the following property to the file.
<pre class="examplecode">
&lt;persistence-unit name=&quot;AffableBeanPU&quot; transaction-type=&quot;JTA&quot;&gt;
&lt;jta-data-source&gt;jdbc/affablebean&lt;/jta-data-source&gt;
<strong>&lt;properties&gt;
&lt;property name=&quot;eclipselink.logging.level&quot; value=&quot;FINEST&quot;/&gt;
&lt;/properties&gt;</strong>
&lt;/persistence-unit&gt;</pre>
You set the logging level property to <code>FINEST</code> so that you can view all
possible output produced by the persistence provider when the application runs. This
enables you to see the SQL that the persistence provider is using on the database,
and can facilitate in any required debugging.
<br><br>
<p class="tips">See the official EclipseLink documentation for an explanation
of logging and a list of all logging values:
<a href="http://wiki.eclipse.org/EclipseLink/Examples/JPA/Logging" target="_blank">How
To Configure Logging</a></p></li>
</ol>
<br>
<h2 id="addSession">Adding Session Beans</h2>
<p>In this section, we use the IDE's Session Beans for Entity Classes wizard to generate
an EJB <em>session facade</em> for each of the entity classes that you just created.
Each session bean will contain basic access methods for its respective entity class.</p>
<p>A <em>session facade</em> is a design pattern advertised in the
<a href="http://java.sun.com/blueprints/enterprise/index.html" target="_blank">Enterprise
BluePrints program</a>. As stated in the
<a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/SessionFacade.html" target="_blank">Core
J2EE Pattern Catalog</a>, it attempts to resolve common problems that arise in a
multi-tiered application environment, such as:</p>
<ul class="toc">
<li>Tight coupling, which leads to direct dependence between clients and business objects</li>
<li>Too many method invocations between client and server, leading to network performance problems</li>
<li>Lack of a uniform client access strategy, exposing business objects to misuse</li>
</ul>
<p>A session facade abstracts the underlying business object interactions and provides a
service layer that exposes only the required functionality. Thus, it hides from the
client's view the complex interactions between the participants. Thus, the session
bean (representing the session facade) manages the relationships between business
objects. The session bean also manages the life cycle of these participants by
creating, locating, modifying, and deleting them as required by the workflow.</p>
<ol>
<li>Press Ctrl-N (&#8984;-N on Mac) to open the File wizard.</li>
<li>Select the Persistence category, then select Session Beans for Entity Classes.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/session-beans-for-entity-classes.png"
class="margin-around b-all" alt="File wizard: Persistence category, Session Beans for Entity Classes file type"
style="width: 688px" title="Select Session Beans for Entity Classes to generate a session facade for your persistence model"></li>
<li>Click Next.</li>
<li>In Step 2: Entity Classes, note that all entity classes contained in your project
are listed on the left, under Available Entity Classes. Click Add All. All entity
classes are moved to the right, under Selected Entity Classes.</li>
<li>Click Next.</li>
<li>In Step 3: Generated Session Beans, type in <strong>session</strong> into the Package field.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/generated-session-beans.png"
class="margin-around b-all" alt="Session Beans for Entity Classes wizard - Step 3: Generated Session Beans"
title="Specify the location of the new session beans, and whether to create interfaces">
<br>
<p class="notes"><strong>Note:</strong> You can use the wizard to generate local and remote
interfaces for the session beans. While there is benefit to programming session beans to
interfaces (For example, hiding business object interactions behind an interface enables
you to further decouple the client from your business logic. This also means that you can
code multiple implementations of the interface for your application, should the need arise.),
this lies outside the scope of the tutorial. Note that EJB versions prior to 3.1 <em>require</em>
that you implement an interface for each session bean.</p></li>
<li>Click Finish. The IDE generates session beans for each of the entity classes contained
in your project. In the Projects window, expand the new <code>session</code> package to
examine the session beans.
<br><br>
<table>
<tr class="align-left">
<th style="padding-left:10px">NetBeans 6.8</th>
<th style="padding-left:10px">NetBeans 6.9</th>
</tr>
<tr>
<td>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/projects-window-session-beans.png"
class="margin-around b-all" alt="Projects window - session beans displayed in project"
title="Examine new session beans in the Projects window">
</td>
<td>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/projects-window-session-beans-69.png"
class="margin-around b-all" alt="Projects window - session beans displayed in project"
title="Examine new session beans in the Projects window">
</td>
</tr>
</table>
<p class="notes"><strong>Note:</strong> As shown above, NetBeans IDE 6.9 provides slight
improvements in the way the Session Beans for Entity Classes wizard generates facade
classes. Namely, boiler-plate code that is common to all classes is factored out
into an abstract class named <code>AbstractFacade</code>. If you are working in version
6.9, open any of the facade classes that have been generated (aside from <code>AbstractFacade</code>).
You'll see that the class extends <code>AbstractFacade</code>.</p></li>
<li>Open a session facade in the editor, for example, <code>ProductFacade</code>. All of
the generated session facades instantiate an
<a href="http://java.sun.com/javaee/6/docs/api/javax/persistence/EntityManager.html"
target="_blank"><code>EntityManager</code></a> using the
<a href="http://download.oracle.com/javaee/6/api/javax/persistence/PersistenceContext.html"
target="_blank"><code>@PersistenceContext</code></a> annotation.
<pre class="examplecode">
@PersistenceContext(unitName = "AffableBeanPU")
private EntityManager em;</pre>
The <code>@PersistenceContext</code> annotation is used to inject a container-managed
<code>EntityManager</code> into the class. In other words, we rely on GlassFish' EJB
container to open and close <code>EntityManager</code>s as and when needed. The
<code>unitName</code> element specifies the <code>AffableBeanPU</code> persistence unit,
which has been defined in the application's <code>persistence.xml</code> file.
<br><br>
The <code>EntityManager</code> is an integral component of the Java Persistence
API, and is responsible for performing persistence actions on the database.
The book <a href="http://www.manning.com/panda/" target="_blank">EJB 3 In Action</a>
describes the <code>EntityManager</code> as follows:
<blockquote>
<em>The JPA <code>EntityManager</code> interface manages entities in terms
of actually providing persistence services. While entities tell a JPA
provider how they map to the database, they do not persist themselves.
The <code>EntityManager</code> interface reads the ORM metadata for an
entity and performs persistence operations.</em>
</blockquote></li>
<!-- TEXT CURRENTLY NOT USED:
In the above example, the <code>EntityManager</code>'s <code>createQuery</code>
method is called to perform a query on the database. If you examine the
<code>createQuery</code> API documentation (press Ctrl-Space on the method
in the editor), you see that the method takes a Java Persistence Query Language
(JPQL) query string as an argument, and returns a <code>Query</code> object.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/create-query-api.png"
class="margin-around b-all" alt="API documentation for EntityManager's createQuery method"
style="width:688px" title="Press Ctrl-Space to view API documentation">
<br>
<p class="tips">For more information on the JPQL, including terminology, syntax,
and example queries, see the
<a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/tutorial/doc/bnbtg.html" target="_blank">Java
EE 6 Tutorial, Chapter 21: The Java Persistence Query Language</a>.</p>
The <code>Query</code> object in turn calls <code>setParameter</code> to
bind the <code>categoryId</code> parameter used in the query string with the
the <code>Category</code> object that is passed into the method. Finally,
<code>getResultList()</code> is called to execute a <code>SELECT</code> query
and return the query results as a <code>List</code> of <code>Product</code>s.
-->
</ol>
<p>Your application now contains a persistence model of the <code>affablebean</code> database in
the form of JPA entity classes. It also contains a session facade consisting of Enterprise
beans that can be used to access the entity classes. The next section demonstrates how you
can access the database using the session beans and entity classes.</p>
<br>
<h2 id="access">Accessing Data with EJBs</h2>
<p>In the <a href="#connect-db">previous tutorial unit</a>, you learned how to access the
database from the application by configuring a data source on GlassFish, adding a resource
reference to the application's deployment descriptor, and using JSTL <code>&lt;sql&gt;</code>
tags in the application's JSP pages. This is a valuable technique, as it allows you to
quickly set up prototypes that include data from the database. However, this is not a
realistic scenario for medium to large-sized applications, or applications managed by a
team of developers, as it would prove difficult to maintain or scale. Furthermore, if you
are developing the application into multiple tiers or are adhering to the MVC pattern, you
would not want to keep data-access code in your front-end. Using Enterprise beans with a
persistence model enables you better conform to the MVC pattern by effectively decoupling
the presentation and model components.</p>
<p>The following instructions demonstrate how to begin using the session and entity beans in
the <code>AffableBean</code> project. You are going to remove the JSTL data access logic
that you previously set up for the index and category pages. In its place, you'll utilize
the data access methods provided by the session beans, and store the data in scoped
variables so that it can be retrieved from front-end page views. We'll tackle the index
page first, then move on to the more complicated category page.</p>
<ul>
<li><a href="#index">index page</a></li>
<li><a href="#category">category page</a></li>
</ul>
<div class="indent">
<h3 id="index">index page</h3>
<p>The index page requires data for the four product categories. In our current setup,
the JSTL <code>&lt;sql&gt;</code> tags query the database for category details each
time the index page is requested. Since this information is rarely modified, it makes
more sense from a performance standpoint to perform the query only once after the
application has been deployed, and store the data in an application-scoped attribute.
We can accomplish this by adding this code to the <code>ControllerServlet</code>'s
<code>init</code> method.</p>
<ol>
<li>In the Projects window, double-click the Source Packages &gt; <code>controller</code>
&gt; <code>ControllerServlet</code> node to open it in the editor.</li>
<li>Declare an instance of <code>CategoryFacade</code>, and apply the <code>@EJB</code>
annotation to the instance.
<pre class="examplecode">
public class ControllerServlet extends HttpServlet {
<strong>@EJB
private CategoryFacade categoryFacade;</strong>
...
}</pre>
The <code>@EJB</code> annotation instructs the EJB container to instantiate
the <code>categoryFacade</code> variable with the EJB named <code>CategoryFacade</code>.</li>
<li>Use the IDE's hints to add import statements for:
<ul style="margin: 5px 0 0 -1em">
<li><code>javax.ejb.EJB</code></li>
<li><code>session.CategoryFacade</code></li>
</ul>
<p class="tips">Pressing Ctrl-Shift-I (&#8984;-Shift-I on Mac) automatically adds
required imports to your class.</p></li>
<li>Add the following <code>init</code> method to the class. The web container
initializes the servlet by calling its <code>init</code> method. This occurs
only once, after the servlet is loaded and before it begins servicing requests.
<pre class="examplecode">
public class ControllerServlet extends HttpServlet {
@EJB
private CategoryFacade categoryFacade;
<strong>public void init() throws ServletException {
// store category list in servlet context
getServletContext().setAttribute(&quot;categories&quot;, categoryFacade.findAll());
}</strong>
...
}</pre>
Here, you apply the facade class' <code>findAll</code> method to query
the database for all records of <code>Category</code>. You then set the resulting
<code>List</code> of <code>Category</code> objects as an attribute that can be
referenced by the &quot;<code>categories</code>&quot; string. Placing the
reference in the <code>ServletContext</code> means that the reference exists
in a scope that is application-wide.
<br><br>
<p class="tips">To quickly determine the method signature of the <code>findAll</code>
method, hover your mouse over the method while holding down the Ctrl key
(&#8984; on Mac). (The image below displays the popup that appears using
NetBeans IDE 6.8.)</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/method-signature.png"
class="margin-around b-all" alt="Editor displaying method signature in a pop-up"
title="Over your mouse over the method while holding down the Ctrl key to view its signature">
<br>
Clicking the hyperlink enables you to navigate directly to the method.</li>
<li>Use the IDE's hint to add the <code>@Overrides</code> annotation. The <code>init</code>
method is defined by <code>HttpServlet</code>'s superclass, <code>GenericServlet</code>.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/override.png"
class="margin-around b-all" alt="Hint displayed in editor"
title="Use the IDE's hint to add the @Overrides annotation to the method">
<br>
Adding the annotation is not required, however it does provide several advantages:
<ul style="margin: 5px 0 0 -1em">
<li>It enables you to use compiler checking to ensure that you are actually
overriding a method that you assume you are overriding.</li>
<li>It improves readability, as it becomes clear when methods in your source code
are being overridden.</li>
</ul>
<p class="tips">For more information on annotations, see the
<a href="http://download.oracle.com/javase/tutorial/java/javaOO/annotations.html" target="_blank">Java
Tutorials: Annotations</a>.</p></li>
<li>Now that you have set up an application-scoped attribute that contains a list of
categories, modify the index page to access the newly created attribute.
<br><br>
Double-click the Web Pages &gt; <code>index.jsp</code> node in the Projects window
to open the file in the editor.</li>
<li>Comment out (or delete) the <code>&lt;sql:query&gt;</code> statement that is
listed at the top of the file. To comment out code in the editor, highlight
the code, then press Ctrl-/ (&#8984;-/ on Mac).
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/commented-out.png"
class="margin-around b-all" alt="Commented-out snippet displayed in editor"
title="Press Ctrl-/ to comment out a code snippet in the editor"></li>
<li>Modify the opening <code>&lt;c:forEach&gt;</code> tag so that its <code>items</code>
attribute references the new application-scoped <code>categories</code> attribute.
<pre class="examplecode">&lt;c:forEach var=&quot;category&quot; items=&quot;<strong>${categories}</strong>&quot;&gt;</pre></li>
<li>Open the project's web deployment descriptor. Press Alt-Shift-O (Ctrl-Shift-O on Mac)
and in the Go to File dialog, type '<code>web</code>', then click OK.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/go-to-file.png"
class="margin-around b-all" alt="Go to File dialog"
title="Use the Go to File dialog to quickly open files in the editor"></li>
<li>Comment out (or delete) the <code>&lt;resource-ref&gt;</code> entry. The entry was required
for the <code>&lt;sql&gt;</code> tags in order to identify the data source registered on the
server. We are now relying on JPA to access the database, and the <code>jdbc/affablebean</code>
data source has already been specified in the persistence unit. (Refer to the <a href="#pu">Design
view of the project's persistence unit</a> above.)
<br><br>
Highlight the entire <code>&lt;resource-ref&gt;</code> entry, then press Ctrl-/ (&#8984;-/ on Mac).
<pre class="examplecode">
<strong>&lt;!-- </strong>&lt;resource-ref&gt;
&lt;description&gt;Connects to database for AffableBean application&lt;/description&gt;
&lt;res-ref-name&gt;jdbc/affablebean&lt;/res-ref-name&gt;
&lt;res-type&gt;javax.sql.ConnectionPoolDataSource&lt;/res-type&gt;
&lt;res-auth&gt;Container&lt;/res-auth&gt;
&lt;res-sharing-scope&gt;Shareable&lt;/res-sharing-scope&gt;
&lt;/resource-ref&gt; <strong>--&gt;</strong></pre></li>
<li>Run the project. Click the Run Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) button. The project's index page opens in the browser,
and you see that all four category names and images display.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/index-page.png"
class="margin-around b-all" alt="Index page displaying category details" style="width:688px"
title="Verify that the index page is able to retrieve category details"></li>
</ol>
<h3 id="category">category page</h3>
<p>The <a href="design.html#category">category page</a> requires three pieces of data
in order to render properly:</p>
<ol style="margin: 5px 0 0 -1em" class="toc">
<li><strong>category data:</strong> for left column category buttons</li>
<li><strong>selected category:</strong> the selected category is highlighted in
the left column, and the name of the selected category displays above the
product table</li>
<li><strong>product data for selected category:</strong> for products displayed
in the product table</li>
</ol>
<p>Let's approach each of the three pieces of data individually.</p>
<ul style="margin: 5px 0 0 -1.5em">
<li><a href="#categoryData">category data</a></li>
<li><a href="#selectedCategoryData">selected category</a></li>
<li><a href="#productData">product data for selected category</a></li>
</ul>
<h4 id="categoryData">category data</h4>
<p>To account for category data, we can reuse the application-scoped <code>categories</code>
attribute that we created for the index page.</p>
<ol>
<li>Open <code>category.jsp</code> in the editor, and comment out (Ctrl-/; &#8984;-/ on Mac)
the JSTL <code>&lt;sql&gt;</code> statements that are listed at the top of the file.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/comment-out-sql.png"
class="margin-around b-all" alt="<sql> statements commented out in editor"
title="Comment out JSTL <sql> statements in the category page"></li>
<li>Modify the opening <code>&lt;c:forEach&gt;</code> tag so that its <code>items</code>
attribute references the application-scoped <code>categories</code> attribute.
(This is identical to what you did above for <code>index.jsp</code>.)
<pre class="examplecode">&lt;c:forEach var=&quot;category&quot; items=&quot;<strong>${categories}</strong>&quot;&gt;</pre></li>
<li>Run the project to examine the current state of the category page. Click the Run Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) button. When the project's index page opens in the browser,
click any of the four categories. The category buttons in the left column display and
function as expected.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/category-page-left-column.png"
class="margin-around b-all" alt="Category page displaying category buttons in left column"
style="width:688px" title="Category buttons in left column display and function as expected"></li>
</ol>
<h4 id="selectedCategoryData">selected category</h4>
<p>To retrieve the selected category, we can use the <code>categoryFacade</code>
that we already created to find the <code>Category</code> whose ID matches
the request query string.</p>
<ol>
<li>Open the <code>ControllerServlet</code> in the editor. (If already opened, press Ctrl-Tab
and choose from the pop-up list.)</li>
<li>Start implementing functionality to acquire the selected category. Locate
the <code>TODO: Implement category request</code> comment, delete it and
add the following code (in <strong>bold</strong>).
<pre class="examplecode">
// if category page is requested
if (userPath.equals(&quot;/category&quot;)) {
<strong>// get categoryId from request
String categoryId = request.getQueryString();
if (categoryId != null) {
}</strong>
// if cart page is requested
} else if (userPath.equals(&quot;/viewCart&quot;)) {</pre>
You retrieve the requested category ID by calling <code>getQueryString()</code>
on the request.
<br><br>
<p class="notes"><strong>Note:</strong> The logic to determine the selected
category within the left column category buttons is already implemented
in <code>category.jsp</code> using an EL expression, which is comparable
to calling <code>getQueryString()</code> in the servlet. The EL expression
is: <code>pageContext.request.queryString</code>.</p></li>
<li>Add the following line of code within the <code>if</code> statement.
<pre class="examplecode">
// get categoryId from request
String categoryId = request.getQueryString();
if (categoryId != null) {
<strong>// get selected category
selectedCategory = categoryFacade.find(Short.parseShort(categoryId));</strong>
}</pre>
You use the <code>CategoryFacade</code>'s <code>find</code> method to
retrieve the <code>Category</code> object based on the requested category
ID. Note that you must cast <code>categoryId</code> to a <code>Short</code>,
as this is the type used for the <code>id</code> field in the <code>Category</code>
entity class.</li>
<li>Click the badge ( <img src="../../../../images_www/articles/73/javaee/ecommerce/common/editor-badge.png"
alt="Hint badge"> ) in the left margin to use the editor's hint to declare
<code>selectedCategory</code> as a local variable within the <code>doGet</code>
method.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/local-variable.png"
class="margin-around b-all" alt="Editor hints"
title="Use editor hints to declare local variables">
<br>
Because <code>selectedCategory</code> is of type <code>Category</code>, which
hasn't yet been imported into the class, the IDE automatically adds an import
statement for <code>entity.Category</code> to the top of the file.</li>
<li>Add the following line to place the retrieved <code>Category</code> object
in the request scope.
<pre class="examplecode">
// get categoryId from request
String categoryId = request.getQueryString();
if (categoryId != null) {
// get selected category
selectedCategory = categoryFacade.find(Short.parseShort(categoryId));
<strong>// place selected category in request scope
request.setAttribute(&quot;selectedCategory&quot;, selectedCategory);</strong>
}</pre></li>
<li>In the editor, switch to <code>category.jsp</code>. (Press Ctrl-Tab and choose from
the pop-up list.)</li>
<li>Locate <code>&lt;p id=&quot;categoryTitle&quot;&gt;</code> and make the following
change.
<pre class="examplecode">
&lt;p id=&quot;categoryTitle&quot;&gt;
&lt;span style=&quot;background-color: #f5eabe; padding: 7px;&quot;&gt;<strong>${selectedCategory.name}</strong>&lt;/span&gt;
&lt;/p&gt;</pre>
You are now using the <code>selectedCategory</code> attribute, which you just placed
in the request scope from the <code>ControllerServlet</code>. Using '<code>.name</code>'
within the EL expression calls the <code>getName</code> method on the given
<code>Category</code> object.</li>
<li>Switch back to the browser and refresh the category page. The name of the selected
category now displays in the page.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/category-page-selected-category.png"
class="margin-around b-all" alt="Category page displaying name of selected category"
style="width:688px" title="Selected category name displays in the category page">
</li>
</ol>
<h4 id="productData">product data for selected category</h4>
<p>In order to retrieve all products for a selected category, we'll make use of the
<code>Category</code> entity's <code>getProductCollection()</code> method. Start
by calling this method on <code>selectedCategory</code> to get a collection of
all <code>Product</code>s associated with the <code>selectedCategory</code>.
Then store the collection of products as an attribute in the request scope, and
finally reference the scoped attribute from the <code>category.jsp</code> page
view.</p>
<ol>
<li>In the <code>ControllerServlet</code>, add the following statement to the code that
manages the category request.
<pre class="examplecode">
// if category page is requested
if (userPath.equals(&quot;/category&quot;)) {
// get categoryId from request
String categoryId = request.getQueryString();
if (categoryId != null) {
// get selected category
selectedCategory = categoryFacade.find(Short.parseShort(categoryId));
// place selected category in request scope
request.setAttribute(&quot;selectedCategory&quot;, selectedCategory);
<strong>// get all products for selected category
categoryProducts = selectedCategory.getProductCollection();</strong>
}</pre>
Calling <code>getProductCollection()</code> here enables us to get a collection
of all <code>Product</code>s associated with the <code>selectedCategory</code>.</li>
<li>Use the editor's hint to define <code>categoryProducts</code> as a local variable
for the <code>doGet</code> method.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/local-variable2.png"
class="margin-around b-all" alt="Editor hints"
title="Use editor hints to declare local variables"></li>
<li>Place the collection of <code>Product</code>s in the request scope so that it
can be retrieved from the application's front-end.
<pre class="examplecode">
// if category page is requested
if (userPath.equals(&quot;/category&quot;)) {
// get categoryId from request
String categoryId = request.getQueryString();
if (categoryId != null) {
// get selected category
selectedCategory = categoryFacade.find(Short.parseShort(categoryId));
// place selected category in request scope
request.setAttribute(&quot;selectedCategory&quot;, selectedCategory);
// get all products for selected category
categoryProducts = selectedCategory.getProductCollection();
<strong>// place category products in request scope
request.setAttribute(&quot;categoryProducts&quot;, categoryProducts);
}</strong></pre></li>
<li>Open the <code>category.jsp</code> file in the editor and make the following
change to the product table.
<pre class="examplecode">
&lt;table id=&quot;productTable&quot;&gt;
&lt;c:forEach var=&quot;product&quot; items=&quot;<strong>${categoryProducts}</strong>&quot; varStatus=&quot;iter&quot;&gt;</pre>
The <code>&lt;c:forEach&gt;</code> tag now references the <code>categoryProducts</code>
collection. The <code>c:forEach</code> loop will now iterate over each <code>Product</code>
object contained in the collection, and extract data accordingly.</li>
<li>Press F6 (fn-F6 on Mac) to run the project. Navigate to the category
page in the browser and note that all products now display for each category.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/category-page-product-table.png"
class="margin-around b-all" alt="Category page displaying products in table"
style="width:688px" title="Product table displays products of a given category">
</li>
</ol>
</div>
<p>This tutorial unit provided a brief introduction to JPA and EJB technologies. It also
described the role of Java specifications, and how their reference implementations are
used by the GlassFish application server. It then demonstrated how to create a set of
JPA entity classes that provide a Java implementation of the project database. Then,
following the <em>session facade</em> pattern, it showed how to create a set of EJB
session beans that exist on top of the entity classes and enable convenient access to
them. Finally, you modified the <code>AffableBean</code> project to utilize the new
session beans and entities for database access required in the index and category pages.</p>
<p>You can download
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot4.zip">snapshot
4</a> of the <code>AffableBean</code> project, which corresponds to state the project
after completing this unit using NetBeans IDE 6.9.</p>
<p>In the next unit you explore session management, and how to enable the application to
remember a user's actions as he or she clicks through the site. This is key to implementing
a shopping cart mechanism in an e-commerce application.</p>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans E-commerce Tutorial - Adding Entity Classes and Session Beans">Send
Us Your Feedback</a></div>
<br style="clear:both;">
<br>
<h2 id="seeAlsoEntitySession">See Also</h2>
<div class="indent">
<h3>NetBeans Resources</h3>
<ul>
<li><a href="../../../trails/java-ee.html" target="_blank">Java EE & Java Web Learning Trail</a></li>
<li><a href="../javaee-intro.html" target="_blank">Introduction to Java EE Technology</a></li>
<li><a href="../javaee-gettingstarted.html" target="_blank">Getting Started with Java EE Applications</a></li>
<li><a href="../secure-ejb.html" target="_blank">Building Secure Enterprise Beans in Java EE</a></li>
<li><a href="../javaee-entapp-ejb.html" target="_blank">Creating an Enterprise Application with EJB 3.1</a></li>
<li><a href="../jpa-eclipselink-screencast.html" target="_blank">Using JPA Support with EclipseLink</a> [screencast]</li>
<li><a href="../../../../community/media.html" target="_blank">Video Tutorials and Demos for NetBeans IDE</a></li>
<li><a href="http://refcardz.dzone.com/refcardz/netbeans-java-editor-68" target="_blank">NetBeans Java Editor 6.8 Reference Card</a></li>
</ul>
<h3>EJB Resources</h3>
<ul>
<li><strong>Product Page:</strong> <a href="http://java.sun.com/products/ejb/" target="_blank">Enterprise JavaBeans Technology</a></li>
<li><strong>Specification Download:</strong> <a href="http://jcp.org/aboutJava/communityprocess/final/jsr318/index.html" target="_blank">JSR 318: EJB 3.1 Final Release</a></li>
<li><strong>Reference Implementation:</strong> <a href="http://glassfish.dev.java.net/downloads/ri" target="_blank">http://glassfish.dev.java.net/downloads/ri</a></li>
<li><strong>Official Forum:</strong> <a href="http://forums.sun.com/forum.jspa?forumID=13" target="_blank">Enterprise Technologies - Enterprise JavaBeans</a></li>
<li><strong>Java EE 6 Tutorial:</strong> <a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/tutorial/doc/bnblr.html" target="_blank">Part IV - Enterprise Beans</a></li>
</ul>
<h3>JPA Resources</h3>
<ul>
<li><strong>Product Page:</strong> <a href="http://java.sun.com/javaee/technologies/persistence.jsp" target="_blank">Java Persistence API</a></li>
<li><strong>Specification Download:</strong> <a href="http://jcp.org/aboutJava/communityprocess/final/jsr317/index.html" target="_blank">JSR 317: Java Persistence 2.0 Final Release</a></li>
<li><strong>Reference Implementation:</strong> <a href="http://www.eclipse.org/eclipselink/downloads/ri.php" target="_blank">http://www.eclipse.org/eclipselink/downloads/ri.php</a></li>
<li><strong>Java EE 6 Tutorial:</strong> <a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/tutorial/doc/bnbpy.html" target="_blank">Part VI - Persistence</a></li>
</ul>
<h3>GlassFish Resources</h3>
<ul>
<li><a href="http://glassfish.dev.java.net/docs/index.html" target="_blank">GlassFish v3 Documentation</a></li>
<li><a href="http://www.sun.com/offers/details/GlassFish_Tomcat.html" target="_blank">Learning GlassFish for Tomcat Users</a></li>
<li><a href="http://glassfish.dev.java.net/javaee5/persistence/persistence-example.html" target="_blank">GlassFish Project - Java Persistence Example</a></li>
<li><a href="http://docs.sun.com/app/docs/doc/820-7759" target="_blank">Your First Cup: An Introduction to the Java EE Platform</a></li>
<li><a href="http://glassfish.dev.java.net/downloads/ri/" target="_blank">Reference Implementation Downloads</a></li>
</ul>
<h3>Technical Articles</h3>
<ul>
<li><a href="http://www.theserverside.com/news/1363656/New-Features-in-EJB-31" target="_blank">New Features in EJB 3.1</a></li>
<li><a href="http://www.ibm.com/developerworks/java/library/j-ejb1008.html" target="_blank">EJB Best Practices: Entity Bean Protection</a></li>
<li><a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/SessionFacade.html" target="_blank">Core J2EE Patterns - Session Facade</a></li>
<li><a href="http://www.ibm.com/developerworks/websphere/library/techarticles/0106_brown/sessionfacades.html" target="_blank">Rules and Patterns for Session Facades</a></li>
<li><a href="http://www.oracle.com/technology/sample_code/tech/java/j2ee/designpattern/businesstier/sessionfacade/readme.html" target="_blank">Design Pattern Sample Application - Session Facade</a></li>
<li><a href="http://www.ibm.com/developerworks/websphere/library/bestpractices/using_httpservlet_method.html" target="_blank">Best Practice: Using HttpServlet <code>init</code> Method</a></li>
</ul>
<h3>Books</h3>
<ul>
<li><a href="http://www.amazon.com/Beginning-Java-EE-GlassFish-Second/dp/143022889X/ref=dp_ob_title_bk" target="_blank">Beginning Java EE 6 with GlassFish 3</a></li>
<li><a href="http://www.amazon.com/Java-EE-GlassFish-Application-Server/dp/1849510369/ref=sr_1_1?s=books&ie=UTF8&qid=1281888153&sr=1-1" target="_blank">Java EE 6 with GlassFish 3 Application Server</a></li>
<li><a href="http://www.apress.com/book/view/1590598954" target="_blank">Pro NetBeans IDE 6 Rich Client Platform Edition</a></li>
<li><a href="http://www.amazon.com/Real-World-Patterns-Rethinking-Practices/dp/0557078326/ref=pd_sim_b_4" target="_blank">Real World Java EE Patterns Rethinking Best Practices</a></li>
<li><a href="http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420/ref=sr_1_1?s=books&ie=UTF8&qid=1281985949&sr=1-1" target="_blank">Patterns of Enterprise Application Architecture</a></li>
<li><a href="http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ref=sr_1_1?s=books&ie=UTF8&qid=1281985959&sr=1-1" target="_blank">Domain-Driven Design: Tackling Complexity in the Heart of Software</a></li>
</ul>
</div>
<br>
<h2>References</h2>
<ol>
<li id="footnote1EntitySession"><a href="#1EntitySession" style="text-decoration:none">^</a> Adapted from <a href="http://www.manning.com/panda/" target="_blank">EJB
3 In Action</a> Chapter 1, section 1.1.2: EJB as a framework.</li>
<li id="footnote2EntitySession"><a href="#2EntitySession" style="text-decoration:none">^</a> There are many other services
provided by EJB. For a more comprehensive list, see <a href="http://www.manning.com/panda/" target="_blank">EJB
3 In Action</a>, Chapter 1, section 1.3.3: Gaining functionality with EJB services.</li>
</ol>
<br><br><br><br>
<h1 id="manage-sessions">The NetBeans E-commerce Tutorial - Managing Sessions</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Tutorial Contents</h4>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#design">Designing the Application</a></li>
<li><a href="#setup-dev-environ">Setting up the Development Environment</a></li>
<li><a href="#data-model">Designing the Data Model</a></li>
<li><a href="#page-views-controller">Preparing the Page Views and Controller Servlet</a></li>
<li><a href="#connect-db">Connecting the Application to the Database</a></li>
<li><a href="#entity-session">Adding Entity Classes and Session Beans</a></li>
<li><strong>Managing Sessions</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#session-data">Handling Session Data</a></li>
<li><a href="#debug">Examining Session Data with the Java Debugger</a></li>
<li><a href="#session-track">Examining Session Tracking Options</a></li>
<li><a href="#time-out">Handling Session Time-Outs</a></li>
<li><a href="#seeAlsoManageSessions">See Also</a></li>
</ul></li>
<li><a href="#transaction">Integrating Transactional Business Logic</a></li>
<li><a href="#language">Adding Language Support</a></li>
<li><a href="#security">Securing the Application</a></li>
<li><a href="#test-profile">Testing and Profiling</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ol>
</div>
</div>
<p><img src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" class="stamp"
alt="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"
title="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"></p>
<p>Every e-commerce application that offers some form of shopping cart functionality
needs to be able to remember user-specific data as users click through the website.
Unfortunately for you the developer, the HTTP protocol, over which communication
on the Internet takes place, is a <em>stateless</em> protocol. Each request received
by your server is an independent piece of information that has no relation to previously
received requests. Therefore, if a customer clicks a button to add an item to his
or her shopping cart, your application must take measures to ensure not only that
the state of the user's cart is updated, but that the action doesn't affect the
cart of another user who happens to be browsing the site at the same time.</p>
<p>In order to properly handle the above-described scenario, you need to implement
functionality so that a <em>session</em> can be created and maintained for the
duration of a user's visit to the site. Servlet technology, which is the foundation
of all Java-based web applications, provides for this with its
<a href="http://java.sun.com/javaee/6/docs/api/javax/servlet/http/HttpSession.html" target="_blank"><code>HttpSession</code></a>
interface. You also need to define several classes, namely <code>ShoppingCart</code>
and <code>ShoppingCartItem</code>, that allow the application to temporarily store
user data while the session is being maintained.</p>
<p>This tutorial unit takes a different approach from others in the NetBeans E-commerce
Tutorial. Instead of having you create project files and providing steps with code
snippets for you to copy and paste into your own project, you open the completed
project snapshot for this unit, and examine the code using the IDE's debugger and
other tools. In the process, you'll learn how to apply an <code>HttpSession</code>
object to your code so that each visit to the website results in a dedicated session.
You also learn about <em>scoped variables</em>, and their usage in both Java classes
and JSP pages. This unit also discusses <code>HttpSession</code>'s default mechanism
for maintaining sessions (i.e., cookies) and shows what steps need to be taken in
the event that cookies are deactivated in a user's browser. Finally, session time-outs
are covered, and the unit demonstrates how to handle them by creating a simple filter
that intercepts requests to check whether a session exists.</p>
<p>You can view a live demo of the application that you build in this tutorial:
<a href="http://services.netbeans.org/AffableBean/" target="_blank">NetBeans E-commerce
Tutorial Demo Application</a>.</p>
<br style="clear:left;">
<br>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html" target="_blank">NetBeans IDE</a></td>
<td class="tbltd1">Java bundle, 6.8 or 6.9</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank">Java Development Kit (JDK)</a></td>
<td class="tbltd1">version 6</td>
</tr>
<tr>
<td class="tbltd1"><a href="#glassFishManageSessions">GlassFish server</a></td>
<td class="tbltd1">v3 or Open Source Edition 3.0.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://dev.mysql.com/downloads/mysql/" target="_blank">MySQL database server</a></td>
<td class="tbltd1">version 5.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot5.zip">AffableBean
project</a></td>
<td class="tbltd1">snapshot 5</td>
</tr>
</tbody>
</table>
<p><strong class="notes">Notes:</strong></p>
<ul>
<li>The NetBeans IDE requires the Java Development Kit (JDK) to run properly.
If you do not have any of the resources listed above, the JDK should be
the first item that you download and install.</li>
<li>The NetBeans IDE Java Bundle includes Java Web and EE technologies, which are
required for the application you build in this tutorial.</li>
<li id="glassFishManageSessions">The NetBeans IDE Java Bundle also includes the GlassFish server,
which you require for this tutorial. You could
<a href="http://glassfish.dev.java.net/public/downloadsindex.html" target="_blank">download
the GlassFish server independently</a>, but the version provided with the
NetBeans download has the added benefit of being automatically registered with
the IDE.</li>
<li>You can follow this tutorial unit without having completed previous units. To
do so, see the <a href="#setup">setup instructions</a>, which describe how
to prepare the database and establish connectivity between the IDE, GlassFish,
and MySQL.</li>
</ul>
<br>
<h2 id="session-data">Handling Session Data</h2>
<p>Applications can manage user sessions with the <code>HttpSession</code> object.
You can bind user-specific data to the <code>HttpSession</code> object, then access
this data at a later stage. Both bind and access actions can be done from Java
classes, as well as from session-scoped variables in EL expressions.</p>
<ul>
<li><a href="#httpSession">Working with an HttpSession Object</a></li>
<li><a href="#scopedVariables">Working with Scoped Variables in Web Applications</a></li>
</ul>
<div class="indent">
<h3 id="httpSession">Working with an HttpSession Object</h3>
<p>The <code>AffableBean</code> application uses the <code>HttpSession</code> object
to identify users over multiple requests. An <code>HttpSession</code> object is
obtained using <code>getSession()</code> on a given request:</p>
<pre class="examplecode" style="width:664px; margin-left:10px; margin-top:-2px">
HttpSession session = request.getSession();</pre>
<p>If a session object doesn't yet exist for the request, the method creates and returns
a new session object.</p>
<p>You can use the session object as a vehicle for passing data between requests. You
use the <code>setAttribute</code> method to bind objects to the session. Likewise,
you use <code>getAttribute</code> to retrieve objects from the session. In the
<code>AffableBean</code> application for example, the user's shopping cart is created
and bound to the user session in the following manner:</p>
<pre class="examplecode" style="width:664px; margin-left:10px; margin-top:-2px">
ShoppingCart cart = new ShoppingCart();
session.setAttribute(&quot;cart&quot;, cart);</pre>
<p>In order to retrieve the cart from the session, the <code>getAttribute</code> method
is applied:</p>
<pre class="examplecode" style="width:664px; margin-left:10px; margin-top:-2px">
cart = (ShoppingCart) session.getAttribute(&quot;cart&quot;);</pre>
<p>In JSP pages, you can access objects bound to the session using EL expressions. Continuing
with the above example, if a <code>ShoppingCart</code> object named '<code>cart</code>'
is bound to the session, you can access the object using the following EL expression:
<pre class="examplecode" style="width:664px; margin-left:10px; margin-top:-2px">${cart}</pre>
<p>Accessing the <code>ShoppingCart</code> object on its own is of little value however.
What you really want is a way to access values stored in the object. If you explore
the new <code>ShoppingCart</code> class in the project snapshot, you'll note that it
contains the following properties:</p>
<ul>
<li><code>double total</code></li>
<li><code>int numberOfItems</code></li>
<li><code>List&lt;String, ShoppingCartItem&gt; items</code></li>
</ul>
<p>Provided that properties have matching getter methods, you can access values for
singular properties using simple dot notation in an EL expression. If you examine
the <code>cart.jsp</code> page, you'll see that this is exactly how the value for
<code>numberOfItems</code> is accessed:</p>
<pre class="examplecode" style="width:664px; margin-left:10px; margin-top:-2px">
&lt;p&gt;Your shopping cart contains ${cart.numberOfItems} items.&lt;/p&gt;</pre>
<p>In order to extract data from properties that contain multiple values, such as the
above <code>items</code> list, the <code>cart.jsp</code> page uses a <code>&lt;c:forEach&gt;</code>
loop:</p>
<pre class="examplecode" style="width:664px; margin-left:10px; margin-top:-2px">
&lt;c:forEach var=&quot;cartItem&quot; items=&quot;${cart.items}&quot; varStatus=&quot;iter&quot;&gt;
&lt;c:set var=&quot;product&quot; value=&quot;${cartItem.product}&quot;/&gt;
&lt;tr class=&quot;${((iter.index % 2) == 0) ? 'lightBlue' : 'white'}&quot;&gt;
&lt;td&gt;
&lt;img src=&quot;${initParam.productImagePath}${product.name}.png&quot;
alt=&quot;${product.name}&quot;&gt;
&lt;/td&gt;
&lt;td&gt;${product.name}&lt;/td&gt;
&lt;td&gt;
&amp;euro; ${cartItem.total}
&lt;br&gt;
&lt;span class=&quot;smallText&quot;&gt;( &amp;euro; ${product.price} / unit )&lt;/span&gt;
&lt;/td&gt;
...
&lt;/tr&gt;
&lt;/c:forEach&gt;</pre>
<p><code>ShoppingCartItem</code>'s <code>product</code> property identifies the product
type for a cart item. The above loop takes advantage of this by first setting a
<code>product</code> variable to the expression <code>${cartItem.product}</code>. It
then uses the variable to obtain information about that product (e.g., name, price).</p>
<h3 id="scopedVariables">Working with Scoped Variables in Web Applications</h3>
<p>When working with JSP/Servlet technology, there are four scope objects available to
you within the realm of the application. JSP technology implements <em>implicit
objects</em> that allows you to access classes defined by the Servlet API.</p>
<div class="margin-around">
<table width="688px">
<tr>
<th class="tblheader" scope="col">Scope</th>
<th class="tblheader" scope="col">Definition</th>
<th class="tblheader" scope="col">Servlet Class</th>
<th class="tblheader" scope="col">JSP Implicit Object</th>
</tr>
<tr>
<td class="tbltd1"><strong>Application</strong></td>
<td class="tbltd1">Global memory for a web application</td>
<td class="tbltd1"><code><a href="http://java.sun.com/javaee/6/docs/api/javax/servlet/ServletContext.html" target="_blank">javax.servlet.ServletContext</a></code></td>
<td class="tbltd1"><code>applicationScope</code></td>
</tr>
<tr>
<td class="tbltd1"><strong>Session</strong></td>
<td class="tbltd1">Data specific to a user session</td>
<td class="tbltd1"><code><a href="http://java.sun.com/javaee/6/docs/api/javax/servlet/http/HttpSession.html" target="_blank">javax.servlet.http.HttpSession</a></code></td>
<td class="tbltd1"><code>sessionScope</code></td>
</tr>
<tr>
<td class="tbltd1"><strong>Request</strong></td>
<td class="tbltd1">Data specific to an individual server request</td>
<td class="tbltd1"><code><a href="http://java.sun.com/javaee/6/docs/api/javax/servlet/http/HttpServletRequest.html" target="_blank">javax.servlet.HttpServletRequest</a></code></td>
<td class="tbltd1"><code>requestScope</code></td>
</tr>
<tr>
<td class="tbltd1"><strong>Page</strong></td>
<td class="tbltd1">Data that is only valid in the context of a single page (JSPs only)</td>
<td class="tbltd1"><code>[n/a]</code></td>
<td class="tbltd1"><code>pageScope</code></td>
</tr>
</table>
</div>
<p>If you open your project's <code>category.jsp</code> file in the editor, you'll see
that EL expressions include various scoped variables, including <code>${categories}</code>,
<code>${selectedCategory}</code> and <code>${categoryProducts}</code>. The <code>${categories}</code>
variable is application-scoped, which is set in the <code>ControllerServlet</code>'s
<code>init</code> method:</p>
<pre class="examplecode" style="width:664px; margin-left:10px; margin-top:-2px">
// store category list in servlet context
getServletContext().setAttribute(&quot;categories&quot;, categoryFacade.findAll());</pre>
<p>The other two, <code>${selectedCategory}</code> and <code>${categoryProducts}</code>,
are placed in the application's session scope from the <code>ControllerServlet</code>.
For example:</p>
<pre class="examplecode" style="width:664px; margin-left:10px; margin-top:-2px">
// place selected category in session scope
session.setAttribute(&quot;selectedCategory&quot;, selectedCategory);</pre>
<p class="notes"><strong>Note:</strong> If you are continuing from the previous tutorial
units, you'll likely note that <code>${selectedCategory}</code> and <code>${categoryProducts}</code>
were originally placed in the request scope. In previous units this was fine, but
consider now what happens if a user clicks the 'add to cart' button in a category page.
The server responds to an <code>addToCart</code> request by returning the currently
viewed category page. It therefore needs to know the <code>selectedCategory</code> and
the <code>categoryProducts</code> pertaining to the selected category. Rather than
establishing this information for each request, you place it in the session scope from
a <code>category</code> request so that it is maintained across multiple requests, and
can be accessed when you need it. Also, examine the functionality provided by the cart
page. (A functional description is <a href="#cartPage">provided below</a>.) The 'continue
shopping' button returns the user to the previously viewed category. Again, the
<code>selectedCategory</code> and the <code>categoryProducts</code> variables are required.</p>
<p>When referencing scoped variables in an EL expression, you do not need to specify the
variable's scope (provided that you do not have two variables of the same name in
different scopes). The JSP engine checks all four scopes and returns the first
variable match it finds. In <code>category.jsp</code> for example, the expression:</p>
<pre class="examplecode" style="width:664px; margin-left:10px; margin-top:-2px">
${categoryProducts}</pre>
<p>is shorthand for:</p>
<pre class="examplecode" style="width:664px; margin-left:10px; margin-top:-2px">
${sessionScope.categoryProducts}</pre>
<span class="tips">For more information, see the following resources:</span>
<ul style="margin: 5px 0 0 1em">
<li><a href="http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/web-tier/web-tier5.html#1079198" target="_blank">Designing
Enterprise Applications with the J2EE Platform: State Scopes</a></li>
<li><a href="http://download.oracle.com/docs/cd/E17477_01/javaee/5/tutorial/doc/bnafo.html" target="_blank">Sharing Information &gt; Using Scoped Objects</a></li>
<li><a href="http://download.oracle.com/docs/cd/E17477_01/javaee/5/tutorial/doc/bnahq.html#bnaij" target="_blank">Unified Expression Language &gt; Implicit Objects</a></li>
</ul>
</div>
<br>
<h2 id="debug">Examining Session Data with the Java Debugger</h2>
<p>Begin exploring how the application behaves during runtime. Use the IDE's debugger to
step through code and examine how the <code>HttpSession</code> is created, and how other
objects can be placed in the session scope to be retrieved at a later point.</p>
<ol>
<li>Open the <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot5.zip">project
snapshot</a> for this tutorial unit in the IDE. Click the Open Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/open-project-btn.png"
alt="Open Project button"> ) button and use the wizard to navigate to the location
on your computer where you downloaded the project. If you are proceeding from the
<a href="#entity-session">previous tutorial unit</a>, note that this project
snapshot includes a new <code>cart</code> package, containing <code>ShoppingCart</code>
and <code>ShoppingCartItem</code> classes.
Also, the following files have been modified:
<ul style="margin: 5px 0 0 -.7em">
<li><code>WEB-INF/web.xml</code></li>
<li><code>css/affablebean.css</code></li>
<li><code>WEB-INF/jspf/header.jspf</code></li>
<li><code>WEB-INF/jspf/footer.jspf</code></li>
<li><code>WEB-INF/view/cart.jsp</code></li>
<li><code>WEB-INF/view/category.jsp</code></li>
<li><code>WEB-INF/view/checkout.jsp</code></li>
<li><code>controller/ControllerServlet</code></li>
</ul></li>
<li>Run the project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) to ensure that it is properly configured with your database and
application server.
<br><br>
<p class="alert">If you receive an error when running the project, revisit the
<a href="#setup">setup instructions</a>, which describe how to prepare the
database and establish connectivity between the IDE, GlassFish, and MySQL.</p></li>
<li>Test the application's functionality in your browser. If you are continuing directly from
the <a href="#entity-session">previous tutorial unit</a>, you'll note the following
enhancements.
<h4>category page</h4>
<ul style="margin: 5px 0 0 -.7em">
<li>Clicking 'add to cart' for the first time enables the shopping cart and 'proceed to
checkout' widgets to display in the header.</li>
<li>Clicking 'add to cart' results in an update to the number of cart items in the header's
shopping cart widget.</li>
<li>Clicking 'view cart' results in the cart page displaying.</li>
<li>Clicking 'proceed to checkout' results in the checkout page displaying.</li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/category-page.png"
class="margin-around b-all" alt="Browser image of category page" style="width:688px"
title="Category page includes shopping cart functionality">
<h4 id="cartPage">cart page</h4>
<ul style="margin: 5px 0 0 -.7em">
<li>Clicking 'clear cart' results in shopping cart being emptied of items.</li>
<li>Clicking 'continue shopping' results in a return to the previously viewed category.</li>
<li>Clicking 'proceed to checkout' results in the checkout page displaying.</li>
<li>Entering a number (1 - 99) in an item's quantity field then clicking 'update'
results in a recalculation of the total price for the item, and of the subtotal.</li>
<li>Entering zero in an item's quantity field then clicking 'update' results in
the item being removed from the displayed table.</li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/cart-page.png"
class="margin-around b-all" alt="Browser image of cart page" style="width:688px"
title="Cart page includes shopping cart functionality">
<h4>checkout page</h4>
<ul style="margin: 5px 0 0 -.7em">
<li>Clicking 'view cart' results in the cart page displaying.</li>
<li>Clicking 'submit purchase' results in the confirmation page displaying (without
user-specific data).</li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/checkout-page.png"
class="margin-around b-all" alt="Browser image of checkout page" style="width:688px"
title="Checkout page includes shopping cart functionality"></li>
<li>Use the Go to File dialog to open the <code>ControllerServlet</code> in the editor. Press
Alt-Shift-O (Ctrl-Shift-O on Mac), then type '<code>Controller</code>' in the dialog and
click OK.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/connect-db/go-to-file-dialog.png"
class="margin-around b-all" alt="Go to File dialog"
title="Use the Go to File dialog to quickly open project resources in the editor"></li>
<li>Set a breakpoint in the <code>doPost</code> method on the line that creates an <code>HttpSession</code>
object (line 150). To set a breakpoint, click in the left margin of the editor.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/breakpoint.png"
class="margin-around b-all" alt="Breakpoint set in editor"
title="Click in editor's left margin to set breakpoints">
<p class="tips">To toggle line numbers for the editor, right-click in the left margin and
choose Show Line Numbers.</p></li>
<li>Run the debugger. Click the Debug Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/debug-project-btn.png"
alt="Debug Project button"> ) button in the IDE's main toolbar. The GlassFish server starts
(or restarts, if it is already running) and opens a socket on its debug port number. The
application welcome page opens in your browser.
<br><br>
<p class="tips">You can view and modify the debug port number from the Servers window (Tools
&gt; Servers). Select the Java tab for the server you are using. Specify the port number
in the 'Address to use' field under Debug Settings.</p></li>
<li>When the application's welcome page displays in the browser, click any category image to navigate
to the category page. Recall that clicking the 'add to cart' button sends an <code>addToCart</code>
request to the server:
<pre class="examplecode">&lt;form action=&quot;addToCart&quot; method=&quot;post&quot;&gt;</pre>
As you may recall from <a href="page-views-controller.html#controller">Preparing the Page Views
and Controller Servlet</a>, the <code>ControllerServlet</code>'s <code>doPost</code> method handles
requests for the <code>/addToCart</code> URL pattern. You can therefore expect that when a user
clicks an 'add to cart' button, the <code>doPost</code> method is called.</li>
<li>Click 'add to cart' for any product in the category page. Switch back to the IDE and note that
the debugger suspends on the breakpoint.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/breakpoint-suspended.png"
class="margin-around b-all" alt="Debugger suspended on breakpoint in editor"
title="Debugger suspends on breakpoints in editor"></li>
<li>Place your cursor on the call to <code>getSession()</code> and press Ctrl-Space to invoke the
Javadoc documentation.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/javadoc-getsession.png"
class="margin-around b-all" alt="Javadoc documentation displayed in editor" style="width:688px"
title="Press Ctrl-Space to invoke Javadoc documentation">
<br>
According to the documentation, <code>getSession()</code> returns the <code>HttpSession</code>
currently associated with the request, and if no session exists, the method creates a new session
object.
<br><br>
<div class="feedback-box float-left" style="width: 683px;">
<h3>Taking Advantage of the IDE's Javadoc Support</h3>
<p>The IDE provides built-in Javadoc support for Java EE development. The IDE
bundles with the Java EE 6 API Specification, which you can open in an
external browser by choosing Help &gt; Javadoc References &gt; Java EE 6.</p>
<p>The IDE also includes various other features that enable easy access to API
documentation:</p>
<ul style="margin: 5px 0 0 -.7em">
<li><strong>Javadoc window:</strong> Choose Window &gt; Other &gt; Javadoc.
The Javadoc window opens in the bottom region of the IDE, and displays
API documentation relevant to your cursor's location in the editor.</li>
<li><strong>Javadoc Index Search:</strong> Choose Help &gt; Javadoc Index
Search (Shift-F1; fn-Shift-F1 on Mac). Type in the name of the class
you are looking for, then select a class from the listed results. The
complete class description from the API Specification displays in the
bottom pane of the window.</li>
<li><strong>Documentation popup in the editor:</strong> Javadoc documentation
displays in a popup window when you press Ctrl-Space on a given element
in the editor. You can click the External Browser (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/external-browser-btn.png"
alt="External Browser button"> ) button to have the documentation open
in your browser.
If you want to use Ctrl-Space for code completion only, you can deactivate
the documentation popup by opening the Options window (Tools &gt; Options;
NetBeans &gt; Preferences on Mac), then selecting Editor &gt; Code Completion.
Deselect the 'Auto Popup Documentation Window' option.</li>
</ul>
<p>When you document your own work, consider adding Javadoc comments to your
classes and methods. Open the <code>ShoppingCart</code> class and examine
the Javadoc comments added to the class methods. Javadoc comments are marked
by the <code>/** ... */</code> delimiters. For example, the <code>addItem</code>
method has the following comment before its signature:</p>
<div class="margin-around">
<pre class="examplecode" style="width:643px">
/**
* Adds a &lt;code&gt;ShoppingCartItem&lt;/code&gt; to the &lt;code&gt;ShoppingCart&lt;/code&gt;'s
* &lt;code&gt;items&lt;/code&gt; list. If item of the specified &lt;code&gt;product&lt;/code&gt;
* already exists in shopping cart list, the quantity of that item is
* incremented.
*
* @param product the &lt;code&gt;Product&lt;/code&gt; that defines the type of shopping cart item
* @see ShoppingCartItem
*/
public synchronized void addItem(Product product) {</pre>
</div>
<p>This enables you (and others working on the project) to view Javadoc documentation
on the method. To demonstrate, open the Navigator (Ctrl-7; &#8984;-7 on Mac) and
hover your mouse over the <code>addItem</code> method.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/javadoc-additem.png"
title="Hover over methods in Navigator to view Javadoc documentation"
alt="Javadoc popup" class="margin-around b-all">
<p>You can also use the IDE to generate a set of Javadoc HTML pages. In the Projects
window, right-click your project node and choose Generate Javadoc. The IDE generates
the Javadoc in the <code>dist/javadoc</code> folder of your project's directory
and opens the index page in the browser.</p>
<br>
<p>For more information on Javadoc, see the following resources:</p>
<ul style="margin: 5px 0 0 -.7em">
<li><a href="http://java.sun.com/j2se/javadoc/" target="_blank">Javadoc Tool Official Home Page</a></li>
<li><a href="http://java.sun.com/j2se/javadoc/writingdoccomments/index.html" target="_blank">How
to Write Doc Comments for the Javadoc Tool</a></li>
</ul>
</div>
<div style="clear:left"></div>
</li>
<li>Hover your mouse over the <code>session</code> variable. Note that the debugger suspends
on the line <em>it is about to execute.</em> The value returned by <code>getSession()</code>
has not yet been saved into the <code>session</code> variable, and you see a popup stating
that &quot;<code>session</code> is not a known variable in the current context.&quot;
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/session-variable.png"
class="margin-around b-all" alt="Debugger popup displayed in editor"
title="Hover your mouse over variables and expressions to determine their current values"></li>
<li>Click the Step Over (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/step-over-btn.png"
alt="Step Over button"> ) button in the debugger toolbar located above the editor. The line is
executed, and the debugger steps to the next line in the file.</li>
<li>Hover your mouse over the <code>session</code> variable again. Now you see the value currently
set to the <code>session</code> variable.
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/session-variable-set.png"
rel="lytebox" title="Hover your mouse over variables and expressions to determine their current values">
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/session-variable-set.png"
class="margin-around b-all" alt="Debugger popup displayed in editor" width="688px"
title="Click to enlarge"></a>
<p class="tips">In NetBeans 6.9, you can click the grey pointer (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/grey-pointer.png"
alt="Step Over button"> ) in the popup to expand a list of variable values contained in the
highlighted element.</p></li>
<li>Click the Step Over (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/step-over-btn.png"
alt="Step Over button"> ) button (F8; fn-F8 on Mac) to arrive at the <code>if</code> statement (line
154). Because you just clicked the 'add to cart' button in the browser, you know that the expression
<code>userPath.equals(&quot;/addToCart&quot;)</code> should evaluate to <code>true</code>.</li>
<li>Highlight the <code>userPath.equals(&quot;/addToCart&quot;)</code> expression (by control-clicking
with your mouse). This time you see a popup indicating the value of the expression you highlighted.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/expression.png"
class="margin-around b-all" alt="Evaluated expression displayed in popup"
title="Highlight expressions to determine their current values"></li>
<li>Press F8 (fn-F8 on Mac) to step to the next line (line 158). The application has been designed
so that the <code>ShoppingCart</code> object for the user session is only created when the user
adds an item to the cart for the first time. Since this is the first time the <code>addToCart</code>
request has been received in this debug session, you can expect the <code>cart</code> object to
equal <code>null</code>.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/cart-null.png"
class="margin-around b-all" alt="Evaluated expression displayed in popup"
title="Cart object doesn't exist until user adds item to shopping cart"></li>
<li>Press F8 (fn-F8 on Mac) to step to the next line (line 160). Then, on line 160, where the
<code>ShoppingCart</code> object is created, click the Step Into (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/step-into-btn.png"
alt="Step Into button"> ) button. The debugger steps into the method being called. In this
case, you are taken directly to the <code>ShoppingCart</code>'s constructor.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/cart-constructor.png"
class="margin-around b-all" alt="Evaluated expression displayed in popup"
title="Step into methods to follow runtime execution to other classes"></li>
<li>Press Ctrl-Tab to switch back to the <code>ControllerServlet</code>. Note that the IDE
provides a Call Stack (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/call-stack-badge.png"
alt="Call Stack badge"> ) badge on line 160, indicating that the debugger is currently suspended
somewhere on a method higher up in the call stack.
<br><br>
<p class="tips">Press Alt-Shift-3 (Ctrl-Shift-3 on Mac) to open the IDE's Call Stack window.</p></li>
<li>Press F8 (fn-F8 on Mac) to continue stepping through code. When the debugger completes the
<code>ShoppingCart</code> constructor, you are taken back to the <code>ControllerServlet</code>.
<br><br>
Line 161 of the <code>ControllerServlet</code> binds the newly-created <code>cart</code> object
to the session.
<pre class="examplecode">session.setAttribute(&quot;cart&quot;, cart);</pre>
To witness this, open the debugger's Variables window. Choose Window &gt; Debugging &gt; Variables,
or press Alt-Shift-1 (Ctrl-Shift-1 on Mac).
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/variables-win-session.png"
rel="lytebox" title="Open the debugger's Variables window to inspect variable values as you step through code">
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/variables-win-session.png"
class="margin-around b-all" alt="Variables window" width="688px"
title="Click to enlarge"></a>
<br>
If you expand the session &gt; session &gt; attributes node, you are able to view the
objects that are bound to the session. In the above image, there are two items currently
bound to the session (highlighted). These are <code>selectedCategory</code> and
<code>categoryProducts</code>, instantiated in the <code>ControllerServlet</code> at lines
83 and 89, respectively. Both of these items were bound earlier, when you clicked a category
image, and the <code>ControllerServlet</code> processed the category page request.</li>
<li>Press F8 (fn-F8 on Mac) to execute line 161. The <code>cart</code> object is bound to the
session, and the Variables window updates to reflect changes. In the Variables window, note
that the session now contains three attributes, the third being the newly initialized
<code>ShoppingCart</code> object (highlighted below).
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/variables-win-session-cart.png"
rel="lytebox" title="ShoppingCart object is bound to session with the setAttribute method">
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/variables-win-session-cart.png"
class="margin-around b-all" alt="Variables window" width="688px"
title="Click to enlarge"></a>
<br>
<p class="tips">So far, we have not &quot;proven&quot; that the session, as listed in
the Variables window, represents an <code>HttpSession</code>. As previously mentioned,
<code>HttpSession</code> is actually an interface, so when we talk about an <code>HttpSession</code>
object, or session object, we are in fact referring to any object that implements the
<code>HttpSession</code> interface. In the Variables window, if you hover your cursor
over '<code>session</code>', a popup displays indicating that the variable represents
an <code>HttpSession</code> object. The <code>StandardSessionFacade</code> type, as
displayed, is the internal class that GlassFish uses to implement the <code>HttpSession</code>
interface. If you are familiar with Tomcat and are puzzled by the
'<code>org.apache.catalina</code>' paths that appear in the Value column, this is
because the GlassFish web/servlet container is in fact a derivative of the Apache Tomcat
container.</p>
A new <code>ShoppingCart</code> is added to the session, and the request continues
to be processed. In order to complete implementation of the 'add to cart' functionality,
the following actions are taken:
<ul style="margin: 5px 0 0 -.7em">
<li>the ID of the selected product is retrieved from the request (line 165)</li>
<li>a <code>Product</code> object is created using the ID (line 169)</li>
<li>a new <code>ShoppingCartItem</code> is created using the <code>product</code> (line 170)</li>
<li>the <code>ShoppingCartItem</code> is added to <code>ShoppingCart</code>'s <code>items</code> list (line 170)</li>
</ul></li>
<li>Press F8 (fn-F8 on Mac) to continue stepping through code while being mindful of the above-listed
four actions. Pause when the debugger suspends on line 170.</li>
<li id="step21">Create a watch on the session. This will allow you to view values contained
in the session when you step into the <code>addItem</code> method in the next step.
Right-click the session in the Variables window and choose Create Fixed Watch.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/create-watch.png"
class="margin-around b-all" alt="Right-click menu displayed in Variables window"
title="Create watches on variables as you step through code in a debug session">
<p class="tips">Alternatively, you can place your cursor on the <code>session</code> variable
in the editor, then right-click and choose New Watch. The New Watch dialog enables you to
specify variables or expressions to watch continuously when debugging an application. (In
the case of expressions, highlight the expression first, then right-click and choose New
Watch.)
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/new-watch-dialog.png"
class="margin-around b-all" alt="New Watch dialog"
title="Right-click variables and expressions in the editor and choose New Watch"></p>
A new watch is created on the <code>session</code> variable and all variables it contains.
The watch is visible from the Watches window (Window &gt; Debugging &gt; Watches) or, if
you toggle the Watches (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/watch-btn.png"
alt="Watches button"> ) button in the left margin of the Variables window, it displays in
the top row of the Variables window.
<br><br>
The debugger enables you to keep an eye on variables as it steps through code. This can
be helpful, for example if you'd like to follow changes to specific variable values (and
don't want to need to sift through the full list presented in the Variables window with
each step), or if you temporarily step into a class that doesn't contain the variables
you are interested in.</li>
<li>Click the Step Into (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/step-into-btn.png"
alt="Step Into button"> ) button to step into <code>ShoppingCart</code>'s <code>addItem</code>
method.</li>
<li>Step through the <code>addItem</code> method until you reach line 53. As the Javadoc states,
<code>addItem</code> <em>&quot;adds a <code>ShoppingCartItem</code> to the <code>ShoppingCart</code>'s
<code>items</code> list. If item of the specified <code>product</code> already exists in
shopping cart list, the quantity of that item is incremented.&quot;</em></li>
<li>Examine the <code>session</code> variable which you created a watch on (<a href="#step21">step
21</a> above). The <code>items.add(scItem)</code> statement in line 51 added the new
<code>ShoppingCartItem</code> to the <code>items</code> list in the <code>ShoppingCart</code>.
This is evident by drilling into the third attribute (i.e., the <code>cart</code> variable)
contained in the session.
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/variables-window-add-item.png"
rel="lytebox" title="Session displays the new ShoppingCartItem as listed in the ShoppingCart's 'items' list">
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/variables-window-add-item.png"
class="margin-around b-all" alt="Variables window" width="688px"
title="Click to enlarge"></a>
<br>
At this stage, you can see how an <code>HttpSession</code> is created for the request,
how a <code>ShoppingCart</code> object is created and attached to the session, and how
a <code>ShoppingCartItem</code> is created based on the user's product choice, then added
to the <code>ShoppingCart</code>'s list of <code>items</code>. The only remaining action
is to forward the request to the <code>category.jsp</code> view.</li>
<li>Open the header JSP fragment (<code>header.jspf</code>) in the editor and place a
breakpoint on line 86. This line contains the EL statement within the shopping cart
widget that displays the number of cart items.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/breakpoint-jsp.png"
class="margin-around b-all" alt="Breakpoint set in JSP page" width="688px"
title="You can suspend the debugger in JSP pages"></li>
<li>Click the Continue (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/continue-btn.png"
alt="Continue button"> ) button in the debugger toolbar. The debugger continues until
execution completes, or until it reaches another breakpoint. In this case, the debugger
suspends on line 86 in the header JSP fragment.
<br><br>
<p class="notes"><strong>Note:</strong> In order to suspend the debugger in a JSP page,
you need to set a breakpoint. For example, when the <code>ControllerServlet</code>
forwards the request to the appropriate view, the debugger will not automatically
suspend within the JSP page.</p></li>
<li>Open the Variables window (Alt-Shift-1; Ctrl-Shift-1 on Mac) if it is not already open.
Unlike with Java classes, the debugger <em>does not</em> provide tooltips when you hover
your mouse over variables or expressions in a JSP page. However, the Variables window does
enable you to determine variable values as you step through code. So, where can you find
the value for <code>${cart.numberOfItems}</code>?</li>
<li>In the Variables window, expand the Implicit Objects &gt; pageContext &gt; session &gt;
session &gt; attributes node. This provides access to the session object, just as you
saw earlier when working in the <code>ControllerServlet</code>. In fact, you may note
that the session which you created a watch on in step 21 above points to the very same
object. Here you can verify that the value of <code>${cart.numberOfItems}</code> equals
'<code>1</code>'.
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/variables-window-number-of-items.png"
rel="lytebox" title="In JSP pages, view session attributes within the pageContext implicit object">
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/variables-window-number-of-items.png"
class="margin-around b-all" alt="Variables window" width="688px"
title="Click to enlarge"></a>
<p class="tips">Maximize the Variables window, or any window in the IDE, by right-clicking
the window header, then choosing Maximize Window (Shift-Esc).</p>
The debugger gives you access to the <code>pageContext</code> implicit object.
<code>pageContext</code> represents the context of the JSP page, and offers direct
access to various objects including the <code>HttpServletRequest</code>,
<code>HttpSession</code>, and <code>ServletContext</code> objects. For more information,
see the <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnahq.html#bnaij" target="_blank">Java
EE 5 Tutorial: Implicit Objects</a>.</li>
<li>Click the Finish Session (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/finish-session-btn.png"
alt="Finish Session button"> ) button. The runtime finishes executing, and the debug
session terminates. The browser displays a fully-rendered category page, and you can
see that the shopping cart widget in the page header contains one item.</li>
</ol>
<p>Hopefully you now feel comfortable using the IDE's debugger not only to examine your project
when it behaves unexpectedly, but also as a tool to become more familiar with code.
Other useful buttons in the debugger toolbar include:</p>
<ul>
<li>( <img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/step-out.png"
alt="Step Out button"> ) <strong>Step Out:</strong> Steps you out of the current method call.
Executes and removes the topmost method call in your call stack.</li>
<li>( <img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/run-to-cursor.png"
alt="Run to Cursor button"> ) <strong>Run to Cursor:</strong> Executes up to the line on
which your cursor is placed.</li>
<li>( <img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/apply-code-changes.png"
alt="Apply Code Changes button"> ) <strong>Apply Code Changes:</strong> After editing a
file, you can press this button so that the file is recompiled and changes are taken into
account in the debug session.</li>
<li>( <img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/step-over-expression.png"
alt="Step Over Expression button"> ) <strong>Step Over Expression:</strong> Enables you
to view the input parameters and resulting output values of each method call within an
expression. You can inspect the output values for the previous method and the input
parameters for the next method in the Local Variables window. When there are no further
method calls, Step Over Expression behaves like the Step Over (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/step-over-btn.png"
alt="Step Over button"> ) command.</li>
</ul>
<br>
<h2 id="session-track">Examining Session Tracking Options</h2>
<p>There are three conventional ways of tracking sessions between client and server. By
far the most common is with cookies. URL rewriting can be applied in the event that
cookies are not supported or disabled. Hidden form fields can also be used as a means
of &quot;maintaining state&quot; over multiple requests, but these are limited to
usage within forms.</p>
<p>The <code>AffableBean</code> project includes an example of the hidden field method
in both the category and cart pages. The 'add to cart' and 'update' buttons that display
for product items contain a hidden field which relays the product ID to the server
when the button is clicked. If you open the <code>cart.jsp</code> page in the editor,
you'll see that the <code>&lt;form&gt;</code> tags contain a hidden field.</p>
<pre class="examplecode" style="width:730px; margin-left:10px; margin-top:-2px">
&lt;form action=&quot;updateCart&quot; method=&quot;post&quot;&gt;
<strong>&lt;input type=&quot;hidden&quot;
name=&quot;productId&quot;
value=&quot;${product.id}&quot;&gt;</strong>
...
&lt;/form&gt;</pre>
<p>In this manner, the product ID is sent as a request parameter which the server uses
to identify the item within the user's cart whose quantity needs to be modified.</p>
<p>The Servlet API provides a high-level mechanism for managing sessions. Essentially,
it creates and passes a cookie between the client and server with each request-response
cycle. If the client browser doesn't accept cookies, the servlet engine automatically
reverts to URL rewriting. The following two exercises demonstrate this functionality.</p>
<ul>
<li><a href="#http-monitor">Examining Client-Server Communication with the HTTP Monitor</a></li>
<li><a href="#url-rewrite">Maintaining Sessions with URL Rewriting</a></li>
</ul>
<div class="indent">
<h3 id="http-monitor">Examining Client-Server Communication with the HTTP Monitor</h3>
<p>By default, the servlet engine uses cookies to maintain and identify sessions between
requests. A random, alphanumeric number is generated for each session object, which
serves as a unique identifier. This identifier is passed as a '<code>JSESSIONID</code>'
cookie to the client. When the client makes a request, the servlet engine reads the
value of the <code>JSESSIONID</code> cookie to determine the session which the request
belongs to.</p>
<p>To demonstrate this, we'll use the debugger in tandem with the IDE's HTTP Monitor.</p>
<ol>
<li>Begin by activating the HTTP Monitor for the server you are using. Choose Tools
&gt; Servers. In the left column of the Servers window, select the server you are
using (GlassFish). Then, in the main column, select the Enable HTTP Monitor option.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/servers-win-http-monitor.png"
class="margin-around b-all" alt="Servers window" width="688px"
title="Select the Enable HTTP Monitor option to activate the HTTP Monitor"></li>
<li>If your server is already running, you need to restart it. However, since we plan
to use the debugger, and running the debugger restarts the server to communicate
on a different port, just click the Debug Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/debug-project-btn.png"
alt="Debug Project button"> ) button in the IDE's main toolbar. The server restarts,
a debug session begins and the application's welcome page opens in your browser. The
HTTP Monitor displays in the bottom region of the IDE.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/http-monitor.png"
class="margin-around b-all" alt="HTTP Monitor" width="688px"
title="HTTP Monitor displays by default in bottom region of the IDE"></li>
<li>Click the AffableBean record in the left column (as shown in the above image). When
you select records in the left column, the right (i.e., main) column refreshes to
display corresponding data. In the above image, the Request tab displays the requested
URI (<code>/AffableBean/</code>), the HTTP method (<code>GET</code>), and points out
that there was no query string sent with the request.</li>
<li>Select the Session tab. Note that there is a statement, &quot;The session was created
as a result of this request.&quot This is due to the fact that the server has sent a
<code>Set-Cookie</code> header for the <code>JSESSIONID</code> cookie in its response.
Also note that the new session ID is listed under 'Session properties'. As will later
be shown, the session ID is the value of the <code>JSESSIONID</code> cookie.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/session-tab.png"
class="margin-around b-all" alt="HTTP Monitor - Session tab"
title="Session details are displayed under the Session tab in the HTTP Monitor">
<br>
You may wonder how a session object was created from a request for the site welcome page.
After all, the <code>ControllerServlet</code> does not handle the initial request for
<code>/AffableBean/</code>, and nowhere does this request encounter <code>getSession()</code>.
Or does it? Recall that JSP pages are compiled into servlets upon deployment. Once you've
deployed your project to the server, you can actually use the IDE to view the JSP's compiled
servlet on your server.</li>
<li>In the Projects window, right-click the <code>index.jsp</code> file and choose View Servlet.
An <code>index_jsp.java</code> file opens in the editor. This is the servlet that was automatically
compiled from the <code>index.jsp</code> page.</li>
<li>Perform a search in the file for <code>getSession</code>. Press Ctrl-F (&#8984;-F on Mac),
type '<code>getSession</code>' in the search bar, then press Enter.
<br><br>
<p class="tips"> Ctrl-F (&#8984;-F on Mac) is a keyboard shortcut for Edit &gt; Find.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/get-session.png"
class="margin-around b-all" alt="Editor displaying getSession method"
title="The getSession method exists in the JSP page's compiled servlet">
<br>
The <code>getSession</code> method is in fact called. The reason this occurs is because
JSP pages include the <code>pageContext.session</code> implicit object by default. If you
wanted to deactivate this behavior, you could add the following directive to the top of
a JSP file:
<pre class="examplecode">&lt;%@page session=&quot;false&quot; %&gt;</pre>
and the <code>getSession</code> method in the compiled servlet would be removed.
<br><br>
<p class="tips">To find out the location of the compiled servlet on your server,
you can hover your mouse over the servlet's name tab above the editor. A popup
displays the path to the file on your computer.</p></li>
<li>In the browser, select a category then add an item to your cart. Switch back to the
IDE. Note that the debugger suspends on the breakpoint in the <code>ControllerServlet</code>
you set earlier (line 150). All breakpoints are remembered between sessions. To remove
the breakpoint, you could click the breakpoint (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/breakpoint-badge.png"
alt="Breakpoint badge"> ) badge in the editor's left margin. However, since there are
multiple breakpoints already set in the project, open the debugger's Breakpoints
window (Window &gt; Debugging &gt; Breakpoints).
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/breakpoints-window.png"
class="margin-around b-all" alt="Breakpoints window"
title="View all breakpoints in your project from the Breakpoints window">
<br>
From the Breakpoints window, you can view and call actions on all breakpoints
set in projects opened in the IDE.</li>
<li>Right-click the breakpoint set in <code>header.jspf</code> and choose Delete.
Then right-click the breakpoint set in the <code>ControllerServlet</code> and
choose Disable. (You'll re-enable it later in this exercise.)</li>
<li>Click the Continue (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/continue-btn.png"
alt="Continue button"> ) button. The request finishes executing, and the category
page displays in the browser with one item added to the cart.</li>
<li>In the HTTP Monitor, search for the <code>addToCart</code> request in the left
column, then select it to display details in the main column.
<br><br>
<p class="tips">Click the Ascending Sort (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/ascending-sort-btn.png"
alt="Ascending Sort button"> ) button so that the most recent records are listed
at the top.</p>
<br>
Under the Request tab, note the requested URI (<code>/AffableBean/addToCart</code>),
the HTTP method (<code>POST</code>), and the request parameters (<code>productId</code>
and <code>submit</code>).
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/http-monitor-add-to-cart.png"
rel="lytebox" title="View request data, including request parameters, under the HTTP Monitor's Request tab">
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/http-monitor-add-to-cart.png"
class="margin-around b-all" style="width:688px" alt="HTTP Monitor - Request tab"
title="Click to enlarge"></a></li>
<li>Select the Cookies tab. Here you see that a cookie named <code>JSESSIONID</code> exists,
and was sent from the client to the server. Note that the value for the cookie is the
same as the Session ID displayed under the Session tab.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/cookies-tab.png"
class="margin-around b-all" alt="HTTP Monitor - Cookies tab"
title="Cookies are displayed under the Cookies tab in the HTTP Monitor">
<br>
Likewise, if you click the Header tab, you see the cookie listed, since '<code>Cookie</code>'
is a request header that was sent by the client.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/headers-tab.png"
class="margin-around b-all" alt="HTTP Monitor - Cookies tab"
title="Cookies are displayed under the Cookies tab in the HTTP Monitor">
<p class="tips">See Wikipedia's <a href="http://en.wikipedia.org/wiki/List_of_HTTP_headers" target="_blank">List
of HTTP headers</a> for more information on request and response headers.</p></li>
<li>Select the Session tab. There is a statement which indicates, &quot;The session existed
before this request.&quot; Also note that the <code>cart</code> attribute is listed under
'Session attributes after the request'. This makes sense, since we know that the
<code>cart</code> object is bound to the session when the <code>addToCart</code> request
is processed for the first time.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/session-tab-add-to-cart.png"
class="margin-around b-all" alt="HTTP Monitor - Session tab"
title="Session attributes are displayed under the Session tab in the HTTP Monitor">
<br><br>
In the next few steps, locate the session ID and <code>JSESSIONID</code> cookie in the
Variables window.</li>
<li>Re-enable the breakpoint you set earlier in the <code>ControllerServlet</code>. Press
Alt-Shift-5 (Ctrl-Shift-5 on Mac) to open the Breakpoints window, then click in the
checkbox next to the breakpoint entry to re-enable it.</li>
<li>In the browser, click the 'add to cart' button for one of the listed products.</li>
<li>Switch to the IDE and note that the debugger is suspended on the breakpoint set
in the <code>ControllerServlet</code>. Click the Step Over (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/step-over-btn.png"
alt="Step Over button"> ) button so that the <code>session</code> variable is assigned
to the session object.</li>
<li>Open the Variables window (Alt-Shift-1; Ctrl-Shift-1 on Mac) and expand session &gt;
session. You'll find the session ID listed as the value for the <code>id</code>
variable.</li>
<li>To locate the <code>JSESSIONID</code> cookie, recall that you can normally access
cookies from a servlet by calling the
<a href="http://java.sun.com/webservices/docs/1.6/api/javax/servlet/http/HttpServletRequest.html#getCookies%28%29" target="_blank"><code>getCookies</code></a>
method on the <code>HttpServletRequest</code>. Therefore, drill into the request object:
request &gt; Inherited &gt; request &gt; request &gt; Inherited &gt; cookies.
Here you see the <code>cookies</code> ArrayList. If you expand the list, you'll
find the <code>JSESSIONID</code> cookie, the value of which is the session ID.</li>
<li>Click the Finish Session (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/finish-session-btn.png"
alt="Finish Session button"> ) button to terminate the debug session.</li>
</ol>
<h3 id="url-rewrite">Maintaining Sessions with URL Rewriting</h3>
<p>As mentioned, the servlet engine detects whether cookies are supported for the client
browser, and if not, it switches to URL rewriting as a means of maintaining sessions.
This all happens transparently for the client. For you, the developer, the process
isn't entirely transparent.</p>
<p>You need to ensure that the application is capable of rewriting URLs whenever cookies
are disabled. You do this by calling the response’s <code>encodeURL</code> method
on all URLs returned by servlets in your application. Doing so enables the session
ID to be appended to the URL in the event that the use of cookies is not an option;
otherwise, it returns the URL unchanged.</p>
<p>For example, the browser sends a request for <code>AffableBean</code>'s third category
(bakery): <code>category?3</code>. The server responds with session ID included in the
URL:</p>
<pre class="examplecode">/AffableBean/category<strong>;jsessionid=364b636d75d90a6e4d0085119990</strong>?3</pre>
<p>As stated above, <em>all URLs returned by your application's servlets must be encoded</em>.
Keep in mind that JSP pages are compiled into servlets. How can you encode URLs in JSP
pages? JSTL's
<a href="http://java.sun.com/products/jsp/jstl/1.1/docs/tlddocs/c/url.html" target="_blank"><code>&lt;c:url&gt;</code></a>
tag serves this purpose. The following exercise demonstrates the problem and illustrates
a solution.</p>
<ol>
<li>Temporarily disable cookies in your browser. If you are using Firefox, you can
choose Tools &gt; Options (Firefox &gt; Preferences on Mac). In the window that
displays, select the Privacy tab, then under History, select 'Use custom settings
for history' in the provided drop-down. Deselect the 'Accept cookies from sites'
option.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/firefox.png"
class="margin-around b-all" alt="Firefox Preferences window"
title="Temporarily disable cookies in your browser"></li>
<li>Run the <code>AffableBean</code> project. When the welcome page displays, click
into a category, then try adding an item to your cart. You'll see that the
application's functionality is severely compromised in its present state.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/compromised.png"
class="margin-around b-all" alt="Broken categories page" width="688px"
title="The application's functionality is compromised when the client doesn't accept cookies">
<br>
As before, the server generates a session and binds objects to it. This is how
the category page is able to display the selected category and products. However,
the server has failed in its attempt to set a <code>JSESSIONID</code> cookie.
Therefore, when the client makes a second request (when user clicks 'add to cart'),
the server has no way of identifying the session which the request belongs to.
It therefore cannot locate any of the attributes previously set in the session,
such as <code>selectedCategory</code> and <code>categoryProducts</code>. This
why the rendered response lacks the information specified by these attributes.</li>
<li>Open the project's <code>category.jsp</code> page in the editor. Locate the line
that implements the 'add to cart' button (line 58). The <code>&lt;form&gt;</code>
element's <code>action</code> attribute determines the request sent to the server.
<pre class="examplecode">&lt;form action=&quot;addToCart&quot; method=&quot;post&quot;&gt;</pre></li>
<li>Modify the request so that it is passed through the <code>&lt;c:url&gt;</code> tag.
<pre class="examplecode">&lt;form action=&quot;<strong>&lt;c:url value='addToCart'/&gt;</strong>&quot; method=&quot;post&quot;&gt;</pre></li>
<li>Press Ctrl-S (&#8984;-S on Mac) to save changes to the file. Recall that the IDE
provides the Deploy on Save feature, which is enabled by default. This means that
any saved changes are automatically deployed to your server.</li>
<li>In the browser, select a different category so that the application renders the
newly modified category page.</li>
<li>Examine the source code for the page. In Firefox, you can press Ctrl-U (&#8984;-U on
Mac). The 'add to cart' button for each product displays with the session ID appended
to the URL.
<pre class="examplecode">
&lt;form action=&quot;addToCart<strong>;jsessionid=4188657e21d72f364e0782136dde</strong>&quot; method=&quot;post&quot;&gt;</pre></li>
<li>Click the 'add to cart' button for any item. You see that the server is now able
to determine the session which the request belongs to, and renders the response
appropriately.</li>
<li>Before proceeding, make sure to re-enable cookies for your browser.</li>
</ol>
<p id="encodeUrl">Again, every link that a user is able to click on within the application,
whose response requires some form of session-related data, needs to be properly encoded.
Sometimes implementation is not as straight-forward as the example shown above. For
example, the 'clear cart' widget used in <code>cart.jsp</code> currently sets a
<code>clear</code> parameter to <code>true</code> when the link is clicked.</p>
<div class="indent">
<pre class="examplecode" style="width:700px">
&lt;%-- clear cart widget --%&gt;
&lt;c:if test=&quot;${!empty cart && cart.numberOfItems != 0}&quot;&gt;
&lt;a href=&quot;viewCart<strong>?clear=true</strong>&quot; class=&quot;bubble hMargin&quot;&gt;clear cart&lt;/a&gt;
&lt;/c:if&gt;</pre></div>
<p>The <code>&lt;c:url&gt;</code> tag can be applied to the URL in the following manner:</p>
<div class="indent">
<pre class="examplecode" style="width:700px">
&lt;%-- clear cart widget --%&gt;
&lt;c:if test=&quot;${!empty cart && cart.numberOfItems != 0}&quot;&gt;
<strong>&lt;c:url var=&quot;url&quot; value=&quot;viewCart&quot;&gt;
&lt;c:param name=&quot;clear&quot; value=&quot;true&quot;/&gt;
&lt;/c:url&gt;</strong>
&lt;a href=&quot;<strong>${url}</strong>&quot; class=&quot;bubble hMargin&quot;&gt;clear cart&lt;/a&gt;
&lt;/c:if&gt;</pre></div>
<p>The <code>clear=true</code> parameter is set by adding a <code>&lt;c:param</code> tag
between the <code>&lt;c:url&gt;</code> tags. A variable named '<code>url</code>' is set
using &lt;c:url&gt;'s <code>var</code> attribute, and <code>var</code> is then accessed
in the HTML anchor tag using the <code>${url}</code> expression.</p>
<p>You can download and examine
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot6.zip">snapshot
6</a> to see how all links in the project have been encoded.</p>
<p class="alert">URL rewriting should only be used in the event that cookies are not an
available tracking method. URL rewriting is generally considered a suboptimal solution
because it exposes the session ID in logs, bookmarks, referer headers, and cached HTML,
in addition to the browser's address bar. It also requires more server-side resources,
as the server needs to perform additional steps for each incoming request in order
to extract the session ID from the URL and pair it with an existing session.</p>
</div>
<br>
<h2 id="time-out">Handling Session Time-Outs</h2>
<ul>
<li><a href="#time-interval">Setting Session Time Intervals</a></li>
<li><a href="#programmatically">Programmatically Handling Session Time-Outs</a></li>
</ul>
<div class="indent">
<h3 id="time-interval">Setting Session Time Intervals</h3>
<p>You should consider the maximum time interval which your server maintains sessions for.
If your website receives heavy traffic, a large number of sessions could expend your
server's memory capacity. You might therefore shorten the interval in hopes of removing
unused sessions. On the other hand, you certainly wouldn't want to cut sessions too short,
as this could become a usability issue that might have a negative impact on the business
behind the website. Taking the <code>AffableBean</code> application as an example, a user
proceeds to checkout after filling her shopping cart with items. She then realizes she
needs to enter her credit card details and goes off to find her purse. After returning
to her computer with credit card in hand, she fills in the checkout form and clicks submit.
During this time however, her session has expired on the server. The user sees that her
shopping cart is empty and is redirected to the homepage. Will she really take the time
to step through the process again?</p>
<p>The following steps demonstrate how to set the session time-out interval in the
<code>AffableBean</code> project to 10 minutes. Of course, the actual duration ultimately
depends on your server resources, the business objectives of the application, and the
popularity of your website.</p>
<ol>
<li>Open the application's deployment descriptor in the editor. Press Alt-Shift-O
(Ctrl-Shift-O on Mac) to use the IDE's Go to File dialog. Type in '<code>web</code>',
then click OK.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/go-to-file.png"
class="margin-around b-all" alt="Go to File dialog"
title="The Go to File dialog enables quick navigation to project files">
<br>
The editor displays the <code>web.xml</code> file in the XML view. The
template that NetBeans provides for the <code>web.xml</code> file includes
a default setting for 30 minutes.
<pre class="examplecode">
&lt;session-config&gt;
&lt;session-timeout&gt;
30
&lt;/session-timeout&gt;
&lt;/session-config&gt;</pre></li>
<li>Click the General tab, and type in '<code>10</code>' in the Session Timeout field.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/session-timeout.png"
class="margin-around b-all" alt="General tab of web.xml file" style="width:688px"
title="Specify session time-out for the application under the web.xml's General tab"></li>
<li>Save the file (Ctrl-S; &#8984;-S on Mac).
<br><br>
If you switch back to the XML view, you'll see that the <code>&lt;session-timeout&gt;</code>
element has been updated.
<pre class="examplecode">
&lt;session-config&gt;
&lt;session-timeout&gt;10&lt;/session-timeout&gt;
&lt;/session-config&gt;</pre>
</li>
</ol>
<p class="notes"><strong>Note:</strong> Alternatively, you could remove the <code>&lt;session-timeout&gt;</code>
element altogether, and edit the <code>session-properties</code> element in the GlassFish-specific
deployment descriptor (<code>sun-web.xml</code>). This would set the global time-out for all
applications in the server's web module. See the
<a href="http://docs.sun.com/app/docs/doc/821-1752/beaha" target="_blank">Oracle GlassFish Server
3.0.1 Application Development Guide: Creating and Managing Sessions</a> for more details.</p>
<h3 id="programmatically">Programmatically Handling Session Time-Outs</h3>
<p>If your application relies on sessions, you need to take measures to ensure that it can
gracefully handle situations in which a request is received for a session that has timed
out or cannot be identified. You can accomplish this in the <code>AffableBean</code>
application by creating a simple filter that intercepts requests heading to the <code>ControllerServlet</code>.
The filter checks if a session exists, and if not, it forwards the request to the site's
welcome page.</p>
<ol>
<li>Start by examining the problem that arises when a session times out midway through
a user's visit to the site. Temporarily reset the session time-out interval to one
minute. Open the web deployment descriptor (<code>web.xml</code>) and enter '<code>1</code>'
between the <code>&lt;session-timeout&gt;</code> tags.
<pre class="examplecode">
&lt;session-config&gt;
&lt;session-timeout&gt;<strong>1</strong>&lt;/session-timeout&gt;
&lt;/session-config&gt;</pre></li>
<li>Run the <code>AffableBean</code> project. In the browser, click into a category page,
add several items to your cart, then click 'view cart'.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/cart-page-session-intact.png"
class="margin-around b-all" alt="Cart page displaying items in shopping cart" style="width:688px"
title="The cart page relies on a session object to display items in shopping cart"></li>
<li>Wait at least one full minute.</li>
<li>Update the quantity for one of the items displayed in the cart page. (Any number between
1 and 99 is acceptable.) Click 'update'. The server returns an HTTP Status 500 message.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/glassfish-error-report.png"
class="margin-around b-all" alt="GlassFish error report displayed in browser" style="width:688px"
title="NullPointerException occurs when request for expired session is received"></li>
<li>Examine the GlassFish server log in the IDE. Open the Output window (Ctrl-4; &#8984;-4 on Mac)
and select the GlassFish Server tab. Scroll to the bottom of the log to examine the error's stack
trace.
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/gf-server-output.png" rel="lytebox"
title="NullPointerException occurs when request belonging to expired session is received">
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/gf-server-output.png"
class="margin-around b-all" alt="GlassFish error report displayed in browser" style="width:688px"
title="Click to enlarge"></a>
<br>
The server log indicates that a <code>NullPointerException</code> occurred at line 184
in the <code>ControllerServlet</code>. The Output window forms a link to the line where
the exception occurred.</li>
<li>Click the link. You navigate directly to line 184 in the <code>ControllerServlet</code>.
Hovering your mouse over the error badge in the editor's left margin provides a tooltip
describing the exception.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/nullpointer-exception.png"
class="margin-around b-all" alt="Error badge and tooltip displayed in editor"
title="Error badge and tooltip indicate the location and cause of the problem">
<br>
Because the session had already expired before the request was received, the servlet
engine was unable to associate the request with its corresponding session. It was
therefore unable to locate the <code>cart</code> object (line 151). The exception
finally occurred in line 184 when the engine attempted to call a method on a variable
equating to <code>null</code>.
<br><br>
Now that we've identified the problem, let's fix it by implementing a filter.</li>
<li>Click the New File (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/new-file-btn.png"
alt="New File button"> ) button in the IDE's toolbar. (Alternatively, press Ctrl-N;
&#8984;-N on Mac.)</li>
<li>Select the <strong>Web</strong> category, then select <strong>Filter</strong>
and click Next.</li>
<li>Name the filter <code>SessionTimeoutFilter</code>. Type <code>filter</code> into
the Packages field so that the filter class is placed in a new package when created.</li>
<li>Click Next. Accept default settings and click Finish. A template for the <code>SessionTimeoutFilter</code>
is generated and opens in the editor.
<br><br>
<p class="notes"><strong>Note:</strong> Currently, in NetBeans 6.9, it isn't possible
to use the wizard to set a mapping to a servlet that isn't registered in the web
deployment descriptor. (<code>ControllerServlet</code> was registered using the
<code>@WebServlet</code> annotation.) We'll therefore modify the generated code
in the next step.</p></li>
<li>Modify the <code>@WebFilter</code> annotation signature so that it appears as follows.
<pre class="examplecode">@WebFilter(<strong>servletNames = {&quot;Controller&quot;}</strong>)
public class SessionTimeoutFilter implements Filter {</pre>
This sets the filter to intercept any requests that are handled by the <code>ControllerServlet</code>.
(Alternatively, you could have kept the <code>urlPatterns</code> attribute, and listed all
patterns that the <code>ControllerServlet</code> handles.)
<br><br>
Note that '<code>Controller</code>' is the name of the <code>ControllerServlet</code>,
as specified in the servlet's <code>@WebServlet</code> annotation signature. Also note
that you've removed the <code>filterName</code> attribute, since the name of the filter
class is used by default.
<br><br>
The IDE's filter template provides a lot of interesting code which is worth inspecting
in its own right. However, most of it is not needed for our purposes here. Any filter
class must implement the <code>Filter</code> interface, which defines three methods:
<ul style="margin: 5px 0 0 -.7em">
<li><strong><code>init</code>:</strong> performs any actions after the filter is initialized
but before it is put into service</li>
<li><strong><code>destroy</code>:</strong> removes the filter from service. This method can
also be used to perform any cleanup operations.</li>
<li><strong><code>doFilter</code>:</strong> used to perform operations for each request the
filter intercepts</li>
</ul>
<p class="tips">Use the Javadoc Index Search to pull up documentation on the
<code>Filter</code> interface. Press Shift-F1 (fn-Shift-F1 on Mac), then type
'<code>Filter</code>' into the search field and hit Enter. Select the 'Interface
in javax.servlet' entry. The Javadoc documentation displays in the lower pane of
the index search tool.</p></li>
<li>Replace the body of the <code>SessionTimeoutFilter</code> with the following contents.
<pre class="examplecode">
@WebFilter(servletNames = {&quot;Controller&quot;})
public class SessionTimeoutFilter implements Filter {
<strong>public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpSession session = req.getSession(false);
// if session doesn't exist, forward user to welcome page
if (session == null) {
try {
req.getRequestDispatcher(&quot;/index.jsp&quot;).forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}
return;
}
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {}
public void destroy() {}</strong>
}</pre></li>
<li>Press Ctrl-Shift-I (&#8984;-Shift-I on Mac) to fix import statements.
(Imports need to be added for <code>HttpServletRequest</code> and <code>HttpSession</code>.)
Also, use the editor hints to add the <code>@Override</code> annotation
to the <code>init</code>, <code>destroy</code>, and <code>doFilter</code>
methods.
<br><br>
In the coming steps, you run the debugger on the project and step through the
<code>doFilter</code> method to see how it determines whether the request is bound
to an existing session.</li>
<li>Open the Breakpoints window (Alt-Shift-5; Ctrl-Shift-5 on Mac) and ensure that
you do not have any existing breakpoints set. To delete a breakpoint, right-click
the breakpoint and choose Delete. (If you completed the above exercise,
<a href="#http-monitor">Examining Client-Server Communication with the HTTP
Monitor</a>, you may have an outstanding breakpoint set in the <code>ControllerServlet</code>.)</li>
<li>Run the debugger. Click the Debug Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/debug-project-btn.png"
alt="Debug Project button"> ) button in the IDE's main toolbar.</li>
<li>When the welcome page displays in the browser, select a category, then add several
items to your shopping cart.</li>
<li>Set a breakpoint on the line in <code>SessionTimeoutFilter</code>'s
<code>doFilter</code> method that tries to access the session (line 32).
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/filter-breakpoint.png"
class="margin-around b-all" alt="Breakpoint set in editor"
title="Set a breakpoint on the getSession method"></li>
<li>In the browser, click the 'view cart' button. Switch to the IDE and note that the
debugger has suspended on the breakpoint.
<br><br>
Recall that <code>getSession()</code> creates a new session object if
the current one doesn't exist. Here, we use <code>getSession(false)</code>,
which refrains from creating a new object if none is found. In other words,
the method returns <code>null</code> if the session doesn't exist.</li>
<li>Click the Step Over (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/step-over-btn.png"
alt="Step Over button"> ) button, then hover your mouse over the <code>session</code>
variable. Provided that a minute hasn't passed since the previous request was
sent, you'll see that the variable has been assigned to a <code>StandardSessionFacade</code>.
This represents the session object for the request.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/session-exists.png"
class="margin-around b-all" alt="Popup displaying 'session' variable assigned to a session object"
title="Hover your mouse over variables to determine their current value"></li>
<li>Continue stepping through the method until the request is processed. Since <code>session</code>
doesn't equal <code>null</code>, you skip the <code>if</code> statement and <code>chain.doFilter</code>
then forwards the request to the <code>ControllerServlet</code> (line 44).</li>
<li>In the browser, make sure a full minute has passed, then update a quantity for
one of the product items in your cart. This is the same procedure we went through
earlier in the exercise when the status 500 message was returned. Now that the
filter intercepts requests heading to the <code>ControllerServlet</code>, let's
see what happens when a session time-out occurs.</li>
<li>After clicking 'update', switch to the IDE and note that the debugger is again suspended
on the breakpoint set in the filter.</li>
<li>Highlight the <code>req.getSession(false)</code> expression, then hover your
mouse over it. Here you see the expression equates to <code>null</code>, as the
session has already expired.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/session-null.png"
class="margin-around b-all" alt="Popup displaying 'session' variable equates to 'null'"
title="Highlight expressions and hover your mouse over them to determine their current value"></li>
<li>Continue stepping through the code. Now that the <code>session</code> variable
equals <code>null</code>, the <code>if</code> statement on line 35 is processed,
and the request is forwarded to <code>/index.jsp</code>. When the debugger finishes
executing, you'll see that the browser displays the site's welcome page.</li>
<li>Click the Finish Session (
<img src="../../../../images_www/articles/73/javaee/ecommerce/manage-sessions/finish-session-btn.png"
alt="Finish Session button"> ) button to terminate the debug session.</li>
<li>Open the project's <code>web.xml</code> file and change the session time-out interval
back to 10 minutes.
<pre class="examplecode">
&lt;session-config&gt;
&lt;session-timeout&gt;<strong>10</strong>&lt;/session-timeout&gt;
&lt;/session-config&gt;</pre>
</li>
<li>Save (Ctrl-S; &#8984;-S on Mac) the file.</li>
</ol>
</div>
<p><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot6.zip">Snapshot
6</a> provides you with the completed project version for this tutorial unit. One final topic
concerning session management should be mentioned. You can explicitly terminate a session by
calling the <code>invalidate</code> method on the session object. If the session is no longer
needed, it should be removed in order to conserve the memory available to your server. After
you complete the next unit, <a href="#transaction">Integrating Transactional Business
Logic</a>, you will see how the <code>ControllerServlet</code>, upon successfully processing
a customer order, destroys the user's <code>cart</code> object and terminates the session
using the <code>invalidate</code> method.</p>
<div class="indent">
<pre class="examplecode" style="width:710px; margin-left:10px; margin-top:-2px">
// if order processed successfully send user to confirmation page
if (orderId != 0) {
// dissociate shopping cart from session
cart = null;
// end session
session.invalidate();
...
}</pre></div>
<p>This is demonstrated in
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot8.zip">project
snapshot 8</a> (and later snapshots).</p>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans E-commerce Tutorial - Managing Sessions">Send
Us Your Feedback</a></div>
<br style="clear:both;">
<h2 id="seeAlsoManageSessions">See Also</h2>
<div class="indent">
<h3>NetBeans Resources</h3>
<ul>
<li><a href="../../../../features/java/debugger.html" target="_blank">NetBeans IDE Features: Debugger</a></li>
<li><a href="../../java/debug-multithreaded.html" target="_blank">Debugging Multithreaded Applications</a></li>
<li><a href="../../java/debug-multithreaded-screencast.html" target="_blank">Video of the Multithreaded Debugging with the NetBeans IDE</a></li>
<li><a href="../../java/debug-evaluator-screencast.html" target="_blank">Video of Using the Code Snippet Evaluator in the NetBeans Debugger</a></li>
<li><a href="../../../../community/media.html" target="_blank">Video Tutorials and Demos for NetBeans IDE</a></li>
<li><a href="https://netbeans.org/projects/www/downloads/download/shortcuts.pdf">Keyboard Shortcuts & Code Templates Card</a></li>
<li><a href="../javaee-gettingstarted.html" target="_blank">Getting Started with Java EE Applications</a></li>
<li><a href="../javaee-intro.html" target="_blank">Introduction to Java EE Technology</a></li>
<li><a href="../../../trails/java-ee.html" target="_blank">Java EE & Java Web Learning Trail</a></li>
</ul>
<h3>GlassFish Resources</h3>
<ul>
<li><a href="http://wiki.glassfish.java.net/Wiki.jsp?page=Screencasts" target="_blank">GlassFish Screencasts</a></li>
<li><a href="http://glassfish.dev.java.net/docs/index.html" target="_blank">GlassFish v3 Documentation</a></li>
<li><a href="http://www.sun.com/offers/details/GlassFish_Tomcat.html" target="_blank">Learning GlassFish for Tomcat Users</a></li>
<li><a href="http://docs.sun.com/app/docs/doc/821-1751" target="_blank">Oracle GlassFish Server 3.0.1 Administration Guide</a></li>
<li><a href="http://docs.sun.com/app/docs/doc/821-1750" target="_blank">Oracle GlassFish Server 3.0.1 Application Deployment Guide</a></li>
<li><a href="http://docs.sun.com/app/docs/doc/821-1752" target="_blank">Oracle GlassFish Server 3.0.1 Application Development Guide</a></li>
</ul>
<h3>Technical Articles & Miscellaneous Resources</h3>
<ul>
<li><a href="http://java.sun.com/javaee/reference/code/" target="_blank">Java EE Code Samples & Apps</a></li>
<li><a href="http://java.sun.com/j2se/javadoc/" target="_blank">Javadoc Tool</a> [product homepage]</li>
<li><a href="http://java.sun.com/j2se/javadoc/writingdoccomments/index.html" target="_blank">How to Write Doc Comments for the Javadoc Tool</a></li>
<li><a href="http://java.sun.com/products/servlet/Filters.html" target="_blank">The Essentials of Filters</a></li>
<li><a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/InterceptingFilter.html" target="_blank">Core J2EE Patterns - Intercepting Filter</a></li>
<li><a href="http://courses.coreservlets.com/Course-Materials/csajsp2.html" target="_blank">Beginning and Intermediate-Level Servlet, JSP, and JDBC Tutorials</a></li>
<li><a href="http://courses.coreservlets.com/Course-Materials/msajsp.html" target="_blank">Advanced Servlet and JSP Tutorials</a></li>
<li><a href="http://courses.coreservlets.com/Course-Materials/java5.html" target="_blank">Java 5 & Java 6 Tutorials</a></li>
<li><a href="http://www.ibm.com/developerworks/java/library/j-jstl0211.html" target="_blank">A JSTL primer, Part 1: The expression language</a></li>
<li><a href="http://www.ibm.com/developerworks/java/library/j-jstl0318/index.html" target="_blank">A JSTL primer, Part 2: Getting down to the core</a></li>
</ul>
</div>
<br><br><br><br>
<h1 id="transaction">The NetBeans E-commerce Tutorial - Integrating Transactional Business Logic</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Tutorial Contents</h4>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#design">Designing the Application</a></li>
<li><a href="#setup-dev-environ">Setting up the Development Environment</a></li>
<li><a href="#data-model">Designing the Data Model</a></li>
<li><a href="#page-views-controller">Preparing the Page Views and Controller Servlet</a></li>
<li><a href="#connect-db">Connecting the Application to the Database</a></li>
<li><a href="#entity-session">Adding Entity Classes and Session Beans</a></li>
<li><a href="#manage-sessions">Managing Sessions</a></li>
<li><strong>Integrating Transactional Business Logic</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#overview">Overview of the Transaction</a></li>
<li><a href="#projSnapshot">Examining the Project Snapshot</a></li>
<li><a href="#orderManager">Creating the <code>OrderManager</code> EJB</a></li>
<li><a href="#requestParam">Handling Request Parameters</a></li>
<li><a href="#placeOrder">Implementing <code>placeOrder</code> and Helper Methods</a></li>
<li><a href="#entityManager">Utilizing JPA's EntityManager</a></li>
<li><a href="#persistenceContext">Synchronizing the Persistence Context with the Database</a></li>
<li><a href="#transactionProgrammatically">Setting up the Transaction Programmatically</a></li>
<li><a href="#validate">Validating and Converting User Input</a></li>
<li><a href="#seeAlsoTransaction">See Also</a></li>
</ul></li>
<li><a href="#language">Adding Language Support</a></li>
<li><a href="#security">Securing the Application</a></li>
<li><a href="#test-profile">Testing and Profiling</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ol>
</div>
</div>
<p><img src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" class="stamp"
alt="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"
title="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"></p>
<p>The purpose of this tutorial unit is to demonstrate how you can use the object-relational
mapping (ORM) capabilities provided by EJB and JPA technologies to gather data
from a web request and write to a back-end database. Of particular interest is
EJB's support for <em>container-managed</em> transactions (refer to the
<a href="entity-session.html#gf-java-ee-container">GlassFish v3 Java EE Container
diagram</a>). By applying several non-intrusive annotations, you can transform
your EJB class into a transaction manager, thereby ensuring the integrity of the
data contained in the database. In other words, the transaction manager handles
multiple write actions to the database as a single unit of work. It ensures that
the work-unit is performed either in its entirety or, if failure occurs at some
point during the process, any changes made are rolled back to the database's
pre-transaction state.</p>
<p>Within the context of the <code>AffableBean</code> application, this tutorial unit
focuses on processing a customer order when data from the checkout form is received.
You create an <code>OrderManager</code> EJB to process the checkout form data
along with the session <code>cart</code> object. The <code>OrderManager</code>
performs a transaction that involves multiple write actions to the <code>affablebean</code>
database. If any of the actions fails, the transaction is rolled back.</p>
<p>You can view a live demo of the application that you build in this tutorial:
<a href="http://services.netbeans.org/AffableBean/" target="_blank">NetBeans
E-commerce Tutorial Demo Application</a>.</p>
<br style="clear:left;">
<br>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html" target="_blank">NetBeans IDE</a></td>
<td class="tbltd1">Java bundle, 6.8 or 6.9</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank">Java Development Kit (JDK)</a></td>
<td class="tbltd1">version 6</td>
</tr>
<tr>
<td class="tbltd1"><a href="#glassFishTransaction">GlassFish server</a></td>
<td class="tbltd1">v3 or Open Source Edition 3.0.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://dev.mysql.com/downloads/mysql/" target="_blank">MySQL database server</a></td>
<td class="tbltd1">version 5.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot7.zip">AffableBean
project</a></td>
<td class="tbltd1">snapshot 7</td>
</tr>
</tbody>
</table>
<p><strong class="notes">Notes:</strong></p>
<ul>
<li>The NetBeans IDE requires the Java Development Kit (JDK) to run properly.
If you do not have any of the resources listed above, the JDK should be
the first item that you download and install.</li>
<li>The NetBeans IDE Java Bundle includes Java Web and EE technologies, which are
required for the application you build in this tutorial.</li>
<li id="glassFishTransaction">The NetBeans IDE Java Bundle also includes the GlassFish server,
which you require for this tutorial. You could
<a href="http://glassfish.dev.java.net/public/downloadsindex.html" target="_blank">download
the GlassFish server independently</a>, but the version provided with the
NetBeans download has the added benefit of being automatically registered with
the IDE.</li>
<li>You can follow this tutorial unit without having completed previous units. To
do so, see the <a href="#setup">setup instructions</a>, which describe how
to prepare the database and establish connectivity between the IDE, GlassFish,
and MySQL.</li>
</ul>
<br>
<h2 id="overview">Overview of the Transaction</h2>
<p>In order to process the data from the checkout form as well as the items contained
in the customer's shopping cart, you create an <code>OrderManager</code> EJB. The
<code>OrderManager</code> uses the provided data and performs the following write
actions to the database:</p>
<ul style="margin: 5px 0 0 -.7em" class="toc">
<li>A new <code>Customer</code> record is added.</li>
<li>A new <code>CustomerOrder</code> record is added.</li>
<li>New <code>OrderedProduct</code> records are added, according to the items contained
in the <code>ShoppingCart</code>.</li>
</ul>
<p>We'll implement this by creating a <code>placeOrder</code> method which performs the
three write actions by sequentially calling private helper methods, <code>addCustomer</code>,
<code>addOrder</code>, and <code>addOrderedItems</code>. We'll also implement the
three helper methods in the class. To leverage EJB's container-managed transaction
service, we only require two annotations. These are:</p>
<ul style="margin: 5px 0 0 -.7em" class="toc">
<li><a href="http://java.sun.com/javaee/6/docs/api/javax/ejb/TransactionManagement.html" target="_blank"><code>@TransactionManagement</code></a><code>(</code><a href="http://java.sun.com/javaee/6/docs/api/javax/ejb/TransactionManagementType.html"><code>TransactionManagementType</code></a>.<code><em>CONTAINER</em>)</code>: Used to specify that any transactions occurring in the class are container-managed.</li>
<li><a href="http://java.sun.com/javaee/6/docs/api/javax/ejb/TransactionAttribute.html" target="_blank"><code>@TransactionAttribute</code></a><code>(</code><a href="http://java.sun.com/javaee/6/docs/api/javax/ejb/TransactionAttributeType.html"><code>TransactionAttributeType</code></a>.<code><em>REQUIRED</em>)</code>: Used on the method that invokes the transaction to specify that a new transaction should be created (if one does not already exist).</li>
</ul>
<div class="indent" id="transactionDiagram">
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/transaction-diagram.png"
alt="Diagram of transaction implemented in AffableBean" class="margin-around"
title="Several write actions are performed within a single transaction">
</div>
<p>Because we are implementing the transaction within a larger context, we'll approach this
exercise by dividing it into several easily-digestible tasks.</p>
<ul>
<li><a href="#projSnapshot">Examining the Project Snapshot</a></li>
<li><a href="#orderManager">Creating the OrderManager EJB</a></li>
<li><a href="#requestParam">Handling Request Parameters</a></li>
<li><a href="#placeOrder">Implementing <code>placeOrder</code> and Helper Methods</a></li>
<li><a href="#entityManager">Utilizing JPA's EntityManager</a></li>
<li><a href="#persistenceContext">Synchronizing the Persistence Context with the Database</a></li>
<li><a href="#transactionProgrammatically">Setting up the Transaction Programmatically</a></li>
</ul>
<br>
<h2 id="projSnapshot">Examining the Project Snapshot</h2>
<p>Begin by examining the project snapshot associated with this tutorial unit.</p>
<ol style="margin-top:0">
<li>Open the <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot7.zip">project
snapshot</a> for this tutorial unit in the IDE. Click the Open Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/open-project-btn.png"
alt="Open Project button"> ) button and use the wizard to navigate to the location
on your computer where you downloaded the project. If you are proceeding from the
<a href="#manage-sessions">previous tutorial unit</a>, note that this project
snapshot is identical to the state of the project after completing the previous unit,
but with the following exceptions:
<ul style="margin: 5px 0 0 -.7em">
<li>The <code>confirmation.jsp</code> page is fully implemented.</li>
<li>The <code>affablebean.css</code> stylesheet includes rules specific
to the <code>confirmation.jsp</code> page implementation.</li>
</ul></li>
<li>Run the project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) to ensure that it is properly configured with your database
and application server.
<br><br>
<p class="alert">If you receive an error when running the project, revisit the
<a href="#setup">setup instructions</a>, which describe how to prepare the
database and establish connectivity between the IDE, GlassFish, and MySQL.</p></li>
<li>Test the application's functionality in your browser. In particular, step through the
entire <a href="design.html#business">business process flow</a>. When you click the
submit an order from the checkout page, the confirmation page currently displays as
follows:
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/confirmation-page-start.png"
alt="Confirmation page displayed in browser" class="margin-around b-all" style="width:688px"
title="Confirmation page displays without any data relating to the processed order">
<br>
No data related to the order is displayed on the confirmation page. In fact, in its
current state the application doesn't do anything with the data from the checkout form.
By the end of this tutorial unit, the application will gather customer data and use
it to process an order. In its final state, the application will display a summary
of the processed order on the confirmation page, remove the user's <code>ShoppingCart</code>
and terminate the user session.
(<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot8.zip">Snapshot
8</a> completes the request-response cycle when a checkout form is submitted.)
</li>
</ol>
<br>
<h2 id="orderManager">Creating the OrderManager EJB</h2>
<ol>
<li>Click the New File (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/new-file-btn.png"
alt="New File button"> ) button in the IDE's toolbar. (Alternatively, press Ctrl-N;
&#8984;-N on Mac.) In the New File wizard, select the Java EE category, then select
Session Bean.</li>
<li>Click Next. Name the EJB '<code>OrderManager</code>', place the EJB in the <code>session</code>
package, and accept other default settings. (Create a stateless session bean, and do not
have the wizard generate an interface for the bean.)
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/ejb-wizard.png"
alt="Session Bean wizard" class="margin-around b-all"
title="Create a stateless EJB session bean using the Session Bean wizard"></li>
<li>Click Finish. The new <code>OrderManager</code> class is generated and opens in the editor.</li>
</ol>
<br>
<h2 id="requestParam">Handling Request Parameters</h2>
<ol>
<li>Open the project's <code>ControllerServlet</code>. (Either select it from the Projects
window, or press Alt-Shift-O (Ctrl-Shift-O on Mac) and use the Go to File dialog.)</li>
<li>Locate the area in the <code>doPost</code> method where the <code>/purchase</code> request
will be implemented (line 190).
<br><br>
<p class="tips">Press Ctrl-G to use the Go To Line dialog.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/go-to-line.png"
alt="Go to Line dialog" class="margin-around b-all"
title="Use the Go to Line dialog to quickly navigate to a specific line"></li>
<li>Implement code that extracts the parameters from a submitted checkout form. Locate
the <code>TODO: Implement purchase action</code> comment, delete it, and add the
following:
<pre class="examplecode">
// if purchase action is called
} else if (userPath.equals(&quot;/purchase&quot;)) {
<strong>if (cart != null) {
// extract user data from request
String name = request.getParameter(&quot;name&quot;);
String email = request.getParameter(&quot;email&quot;);
String phone = request.getParameter(&quot;phone&quot;);
String address = request.getParameter(&quot;address&quot;);
String cityRegion = request.getParameter(&quot;cityRegion&quot;);
String ccNumber = request.getParameter(&quot;creditcard&quot;);
}</strong>
userPath = &quot;/confirmation&quot;;
}</pre></li>
</ol>
<br>
<h2 id="placeOrder">Implementing placeOrder and Helper Methods</h2>
<ol>
<li>In the <code>ControllerServlet</code>, add a reference to the <code>OrderManager</code>
EJB. Scroll to the top of the class and add a reference beneath the session facade EJBs
that are already listed.
<pre class="examplecode">
public class ControllerServlet extends HttpServlet {
private String userPath;
private String surcharge;
private ShoppingCart cart;
@EJB
private CategoryFacade categoryFacade;
@EJB
private ProductFacade productFacade;
<strong>@EJB
private OrderManager orderManager;</strong></pre></li>
<li>Press Ctrl-Shift-I (�:-Shift-I on Mac) to allow the editor to add an import
statement for <code>session.OrderManager</code>.</li>
<li>Use the extracted parameters, as well as the session <code>cart</code> object, as
arguments for the <code>OrderManager.placeOrder</code> method. Add the following
code:
<pre class="examplecode">
// if purchase action is called
} else if (userPath.equals(&quot;/purchase&quot;)) {
if (cart != null) {
// extract user data from request
String name = request.getParameter(&quot;name&quot;);
String email = request.getParameter(&quot;email&quot;);
String phone = request.getParameter(&quot;phone&quot;);
String address = request.getParameter(&quot;address&quot;);
String cityRegion = request.getParameter(&quot;cityRegion&quot;);
String ccNumber = request.getParameter(&quot;creditcard&quot;);
<strong>int orderId = orderManager.placeOrder(name, email, phone, address, cityRegion, ccNumber, cart);</strong>
}
userPath = &quot;/confirmation&quot;;
}</pre>
Note that we haven't created the <code>placeOrder</code> method yet. This is why
the editor flags an error. You can use the tip that displays in the left margin,
which allows you to generate the method signature in the appropriate class.
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/transaction/tool-tip-create-method.png"
rel="lytebox" title="Use editor tips to generate method signatures in other classes">
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/tool-tip-create-method.png"
alt="Tip displayed in editor" class="margin-around b-all" style="width:688px"
title="Click to enlarge"></a></li>
<li>Click the tip. The IDE generates the <code>placeOrder</code> method in the
<code>OrderManager</code> class.
<pre class="examplecode">
@Stateless
public class OrderManager {
<strong>public int placeOrder(String name, String email, String phone, String address, String cityRegion, String ccNumber, ShoppingCart cart) {
throw new UnsupportedOperationException(&quot;Not yet implemented&quot;);
}</strong>
...
}</pre>
The import statement for <code>cart.ShoppingCart</code> is also automatically inserted at the
top of the file.</li>
<li>In the new <code>placeOrder</code> method, use the method arguments to make calls to the
(yet nonexistent) helper methods. Enter the following:
<pre class="examplecode">
public int placeOrder(String name, String email, String phone, String address, String cityRegion, String ccNumber, ShoppingCart cart) {
<strong>Customer customer = addCustomer(name, email, phone, address, cityRegion, ccNumber);
CustomerOrder order = addOrder(customer, cart);
addOrderedItems(order, cart);</strong>
}</pre>
Note that we need to follow a particular order due to database constraints. For example,
a <code>Customer</code> record needs to be created before the <code>CustomerOrder</code>
record, since the <code>CustomerOrder</code> requires a reference to a <code>Customer</code>.
Likewise, the <code>OrderedItem</code> records require a reference to an existing
<code>CustomerOrder</code>.</li>
<li>Press Ctrl-Shift-I (&#8984:-Shift-I on Mac) to fix imports. Import statements for
<code>entity.Customer</code> and <code>entity.CustomerOrder</code> are automatically
added to the top of the file.</li>
<li>Use the editor hints to have the IDE generate method signatures for <code>addCustomer</code>,
<code>addOrder</code>, and <code>addOrderedItems</code>. After utilizing the three hints,
the <code>OrderManager</code> class looks as follows.
<pre class="examplecode">
@Stateless
public class OrderManager {
public int placeOrder(String name, String email, String phone, String address, String cityRegion, String ccNumber, ShoppingCart cart) {
Customer customer = addCustomer(name, email, phone, address, cityRegion, ccNumber);
CustomerOrder order = addOrder(customer, cart);
addOrderedItems(order, cart);
}
<strong>private Customer addCustomer(String name, String email, String phone, String address, String cityRegion, String ccNumber) {
throw new UnsupportedOperationException(&quot;Not yet implemented&quot;);
}
private CustomerOrder addOrder(Customer customer, ShoppingCart cart) {
throw new UnsupportedOperationException(&quot;Not yet implemented&quot;);
}
private void addOrderedItems(CustomerOrder order, ShoppingCart cart) {
throw new UnsupportedOperationException(&quot;Not yet implemented&quot;);
}</strong>
}</pre>
Note that an error is still flagged in the editor, due to the fact that the method
is currently lacking a return statement. The <code>placeOrder</code> signature
indicates that the method returns an <code>int</code>. As will later be demonstrated,
the method returns the order ID if it has been successfully processed, otherwise
<code>0</code> is returned.</li>
<li>Enter the following return statement.
<pre class="examplecode">
public int placeOrder(String name, String email, String phone, String address, String cityRegion, String ccNumber, ShoppingCart cart) {
Customer customer = addCustomer(name, email, phone, address, cityRegion, ccNumber);
CustomerOrder order = addOrder(customer, cart);
addOrderedItems(order, cart);
<strong>return order.getId();</strong>
}</pre>
At this stage, all errors in the <code>OrderManager</code> class are resolved.</li>
<li>Begin implementing the three helper methods. For now, simply add code that
applies each method's input parameters to create new entity objects.
<br><br>
<h4>addCustomer</h4>
<p>Create a new <code>Customer</code> object and return the object.</p>
<pre class="examplecode">
private Customer addCustomer(String name, String email, String phone, String address, String cityRegion, String ccNumber) {
<strong>Customer customer = new Customer();
customer.setName(name);
customer.setEmail(email);
customer.setPhone(phone);
customer.setAddress(address);
customer.setCityRegion(cityRegion);
customer.setCcNumber(ccNumber);
return customer;</strong>
}</pre>
<br>
<h4>addOrder</h4>
<p>Create a new <code>CustomerOrder</code> object and return the object. Use the
<code>java.util.Random</code> class to generate a random confirmation number.</p>
<pre class="examplecode">
private CustomerOrder addOrder(Customer customer, ShoppingCart cart) {
<strong>// set up customer order
CustomerOrder order = new CustomerOrder();
order.setCustomer(customer);
order.setAmount(BigDecimal.valueOf(cart.getTotal()));
// create confirmation number
Random random = new Random();
int i = random.nextInt(999999999);
order.setConfirmationNumber(i);
return order;</strong>
}</pre>
<br>
<h4>addOrderedItems</h4>
<p>Iterate through the <code>ShoppingCart</code> and create
<code>OrderedProduct</code>s. In order to create an <code>OrderedProduct</code>,
you can use the <code>OrderedProductPK</code> entity class. The instantiated
<code>OrderedProductPK</code> can be passed to the <code>OrderedProduct</code>
constructor, as demonstrated below.</p>
<pre class="examplecode">
private void addOrderedItems(CustomerOrder order, ShoppingCart cart) {
<strong>List&lt;ShoppingCartItem&gt; items = cart.getItems();
// iterate through shopping cart and create OrderedProducts
for (ShoppingCartItem scItem : items) {
int productId = scItem.getProduct().getId();
// set up primary key object
OrderedProductPK orderedProductPK = new OrderedProductPK();
orderedProductPK.setCustomerOrderId(order.getId());
orderedProductPK.setProductId(productId);
// create ordered item using PK object
OrderedProduct orderedItem = new OrderedProduct(orderedProductPK);
// set quantity
orderedItem.setQuantity(scItem.getQuantity());
}</strong>
}</pre></li>
<li>Press Ctrl-Shift-I (&#8984;-Shift-I on Mac) to fix imports. A dialog
opens to display all classes that will be imported. Note that the dialog
correctly guesses for <code>java.util.List</code>.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/fix-all-imports.png"
alt="Fix All Imports dialog" class="margin-around b-all"
title="Press Ctrl-Shift-I to fix imports in a file"></li>
<li>Click OK. All necessary import statements are added, and the class becomes
free of any compiler errors.</li>
</ol>
<br>
<h2 id="entityManager">Utilizing JPA's EntityManager</h2>
<p>As was mentioned in <a href="#entity-session">Adding Entity Classes and Session
Beans</a>, the <code>EntityManager</code> API is included in JPA, and is responsible
for performing persistence operations on the database. In the <code>AffableBean</code>
project, all of the EJBs employ the <code>EntityManager</code>. To demonstrate,
open any of the session facade beans in the editor and note that the class uses
the <code>@PersistenceContext</code> annotation to express a dependency on a
container-managed <code>EntityManager</code> and its associated persistence context
(<code>AffableBeanPU</code>, as specified in the <code>persistence.xml</code> file).
For example, the <code>ProductFacade</code> bean looks as follows:</p>
<pre class="examplecode" style="width:720px">
@Stateless
public class ProductFacade extends AbstractFacade&lt;Product&gt; {
<strong>@PersistenceContext(unitName = &quot;AffableBeanPU&quot;)
private EntityManager em;</strong>
protected EntityManager getEntityManager() {
return em;
}
...
// manually created
public List&lt;Product&gt; findForCategory(Category category) {
return em.createQuery(&quot;SELECT p FROM Product p WHERE p.category = :category&quot;).
setParameter(&quot;category&quot;, category).getResultList();
}
}</pre>
<p>To be able to write to the database, the <code>OrderManager</code> EJB must
take similar measures. With an <code>EntityManager</code> instance, we can
then modify the helper methods (<code>addCustomer</code>, <code>addOrder</code>,
<code>addOrderedItems</code>) so that the entity objects they create are
written to the database.</p>
<ol>
<li>In <code>OrderManager</code>, apply the <code>@PersistenceContext</code>
annotation to express a dependency on a container-managed <code>EntityManager</code>
and the <code>AffableBeanPU</code> persistence context. Also declare
an <code>EntityManager</code> instance.
<pre class="examplecode">
@Stateless
public class OrderManager {
<strong>@PersistenceContext(unitName = &quot;AffableBeanPU&quot;)
private EntityManager em;</strong>
...
}</pre></li>
<li>Press Ctrl-Shift-I (&#8984:-Shift-I on Mac) to fix imports. Import statements
for <code>javax.persistence.EntityManager</code> and <code>javax.persistence.PersistenceContext</code>
are added to the top of the class.</li>
<li>Use the <code>EntityManager</code> to mark entity objects to be written to the
database. This is accomplished using the <code>persist</code> method in the
<code>EntityManager</code> API. Make the following modifications to the helper
methods.
<br><br>
<h4>addCustomer</h4>
<pre class="examplecode" style="margin-top:0">
private Customer addCustomer(String name, String email, String phone, String address, String cityRegion, String ccNumber) {
Customer customer = new Customer();
customer.setName(name);
customer.setEmail(email);
customer.setPhone(phone);
customer.setAddress(address);
customer.setCityRegion(cityRegion);
customer.setCcNumber(ccNumber);
<strong>em.persist(customer);</strong>
return customer;
}</pre>
<br>
<h4>addOrder</h4>
<pre class="examplecode" style="margin-top:0">
private CustomerOrder addOrder(Customer customer, ShoppingCart cart) {
// set up customer order
CustomerOrder order = new CustomerOrder();
order.setCustomer(customer);
order.setAmount(BigDecimal.valueOf(cart.getTotal()));
// create confirmation number
Random random = new Random();
int i = random.nextInt(999999999);
order.setConfirmationNumber(i);
<strong>em.persist(order);</strong>
return order;
}</pre>
<br>
<h4>addOrderedItems</h4>
<pre class="examplecode" style="margin-top:0">
private void addOrderedItems(CustomerOrder order, ShoppingCart cart) {
List&lt;ShoppingCartItem&gt; items = cart.getItems();
// iterate through shopping cart and create OrderedProducts
for (ShoppingCartItem scItem : items) {
int productId = scItem.getProduct().getId();
// set up primary key object
OrderedProductPK orderedProductPK = new OrderedProductPK();
orderedProductPK.setCustomerOrderId(order.getId());
orderedProductPK.setProductId(productId);
// create ordered item using PK object
OrderedProduct orderedItem = new OrderedProduct(orderedProductPK);
// set quantity
orderedItem.setQuantity(String.valueOf(scItem.getQuantity()));
<strong>em.persist(orderedItem);</strong>
}
}</pre>
The <code>EntityManager</code>'s <code>persist</code> method does not immediately
write the targeted object to the database. To describe this more accurately, the
<code>persist</code> method places the object in the <em>persistence context</em>.
This means that the <code>EntityManager</code> takes on the responsibility of ensuring
that the entity object is synchronized with the database. Think of the persistence
context as an intermediate state used by the <code>EntityManager</code> to pass
entities between the object realm and the relational realm (hence the term 'object-relational
mapping').
<br><br>
What is the scope of the persistence context? If you open the IDE's Javadoc Index Search
(Shift-F1; Shift-fn-F1 on Mac) and examine the Javadoc documentation for the
<a href="http://java.sun.com/javaee/6/docs/api/javax/persistence/PersistenceContext.html" target="_blank"><code>@PersistenceContext</code></a>
annotation, you'll note that the <code>type</code> element is used to &quot;specif[y]
whether a transaction-scoped persistence context or an extended persistence context
is to be used.&quot; A <em>transaction-scoped</em> persistence context is created at
the start of a transaction, and terminated when the transaction ends. An <em>extended</em>
persistence context applies to stateful session beans only, and spans multiple transactions.
The Javadoc documentation also informs us that <code>javax.persistence.PersistenceContextType.TRANSACTION</code>
is the default value for the <code>type</code> element. Therefore, although we didn't
specify that the <code>EntityManager</code> place objects in a transaction-scoped persistence
context, this is in fact how a container-managed <code>EntityManager</code> behaves by
default.</li>
</ol>
<br>
<h2 id="persistenceContext">Synchronizing the Persistence Context with the Database</h2>
<p>At this stage you might assume that, transaction or no transaction, the <code>OrderManager</code>
is now able to successfully write entity objects to the database. Run the project
and see how customer orders are currently being processed.</p>
<ol>
<li>Press F6 (fn-F6 on Mac) to run the project.</li>
<li>Step through the <a href="design.html#business">business process flow</a>.
When you arrive at the checkout page, be sure to enter data that you know
will not cause SQL errors to occur when the write actions are performed.
(Validation is discussed in a later tutorial unit.) For example, enter the
following into the checkout form:
<ul style="margin: 5px 0 0 -2em">
<li><strong>name:</strong> <code>Hugo Reyes</code></li>
<li><strong>email:</strong> <code>hurley@mrcluck.com</code></li>
<li><strong>phone:</strong> <code>606252924</code></li>
<li><strong>address:</strong> <code>Karlova 33</code></li>
<li><strong>prague:</strong> <code>1</code></li>
<li><strong>credit card number:</strong> <code>1111222233334444</code></li>
</ul>
<p class="tips">In the coming steps, you are going to examine the server log
in the IDE's Output window. Before submitting the checkout form, open the
Output window and clear the server log. You can accomplish this by right-clicking
in the server log and choosing Clear (Ctrl-L; &#8984;-L on Mac).</p></li>
<li>Click the 'submit purchase' button. The server responds with an HTTP status 500
message.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/gf-error-report.png"
alt="Browser window displaying HTTP status 500 message" class="margin-around b-all"
title="Server responds with an HTTP status 500 message" style="width:688px"></li>
<li>Switch to the IDE and examine the server log. The server log is located in the
Output window (Ctrl-4; &#8984;-4 on Mac) under the GlassFish server tab. You come
across the following text.
<pre class="examplecode">WARNING: A system exception occurred during an invocation on EJB OrderManager method
public int session.OrderManager.placeOrder(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,cart.ShoppingCart)
javax.ejb.EJBException
...
Caused by: java.lang.NullPointerException
<u>at session.OrderManager.addOrderedItems(OrderManager.java:75)</u>
<u>at session.OrderManager.placeOrder(OrderManager.java:33)</u></pre>
<p class="tips">Maximize the Output window by pressing Shift-Esc.</p>
The underlines displayed in the server log form links allowing you to navigate
directly to the lines in your source files where errors are occurring.</li>
<li>Click the link to <code>session.OrderManager.addOrderedItems</code>.
The editor displays the line that is causing the exception.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/null-pointer-exception.png"
alt="Editor displaying NullPointerException error" class="margin-around b-all"
title="Click links in server output window to navigate directly to offending lines in source files">
<br>
To understand why <code>order.getId</code> method returns <code>null</code>,
consider what the code is actually trying to accomplish. The <code>getId</code>
method attempts to get the ID of an order which is currently in the process
of being created. Since the ID is an auto-incrementing primary key, the database
automatically generates the value only when the record is added. One way to
overcome this is to manually synchronize the persistence context with the database.
This can be accomplished using the <code>EntityManager</code>'s
<a href="http://java.sun.com/javaee/6/docs/api/javax/persistence/EntityManager.html#flush%28%29" target="_blank"><code>flush</code></a>
method.</li>
<li>In the <code>addOrderedItems</code> method, add a call to flush the persistence
context to the database.
<pre class="examplecode">
private void addOrderedItems(CustomerOrder order, ShoppingCart cart) {
<strong>em.flush();</strong>
List&lt;ShoppingCartItem&gt; items = cart.getItems();
// iterate through shopping cart and create OrderedProducts
for (ShoppingCartItem scItem : items) {
int productId = scItem.getProduct().getId();
// set up primary key object
OrderedProductPK orderedProductPK = new OrderedProductPK();
orderedProductPK.setCustomerOrderId(order.getId());
orderedProductPK.setProductId(productId);
// create ordered item using PK object
OrderedProduct orderedItem = new OrderedProduct(orderedProductPK);
// set quantity
orderedItem.setQuantity(String.valueOf(scItem.getQuantity()));
em.persist(orderedItem);
}
}</pre></li>
<li>Rerun the project and step through the business process flow. This time,
when you submit the checkout form the confirmation page displays.</li>
<li>To confirm that the details have been recorded in the database, open
the IDE's Services window (Ctrl-5; &#8984;-5 on Mac). Locate the <code>affablebean</code>
connection node. If the node appears broken (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/connection-broken.png"
alt="Broken connection node"> ), right-click the node and choose Connect.</li>
<li>Drill into the connection and locate the <code>affablebean</code> database's
<code>customer</code> table. Right-click the table and choose View Data. A
graphical display of the <code>customer</code> table appears in the editor.
The customer details that you added in the checkout form display as a record
in the table.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/customer-record.png"
alt="Graphical display of affablebean customer table" class="margin-around b-all" style="width:688px"
title="View Data menu option performs a 'select *' query on the selected table">
<br>
In this manner, you can also examine the <code>customer_order</code> and
<code>ordered_product</code> tables to determine whether data has been recorded.</li>
</ol>
<br>
<h2 id="transactionProgrammatically">Setting up the Transaction Programmatically</h2>
<p>A transaction's primary function is to ensure that all operations are performed
successfully, and if not, then none of the individual operations are
performed.<sup><a href="#footnote1Transaction" id="1Transaction" style="text-decoration:none">[1]</a></sup>
The following steps demonstrate how to ensure that the write operations performed
in the <code>placeOrder</code> method are treated as a single transaction.</p>
<ol>
<li>Refer to the <a href="#transactionDiagram">transaction diagram</a> above. Add the
two transaction-related annotations to the <code>OrderManager</code> EJB.
<pre class="examplecode">
@Stateless
<strong>@TransactionManagement(TransactionManagementType.CONTAINER)</strong>
public class OrderManager {
@PersistenceContext(unitName = &quot;AffableBeanPU&quot;)
private EntityManager em;
<strong>@TransactionAttribute(TransactionAttributeType.REQUIRED)</strong>
public int placeOrder(String name, String email, String phone, String address, String cityRegion, String ccNumber, ShoppingCart cart) {
try {
...</pre>
The <code>@TransactionManagement</code> annotation is used to specify that any
transactions occurring in the <code>OrderManager</code> EJB are container-managed.
The <code>@TransactionAttribute</code> annotation placed on the <code>placeOrder</code>
method specifies that any operations occurring in the method must be treated as part
of a transaction.
<br><br>
<p class="tips">According to the <a href="http://jcp.org/aboutJava/communityprocess/final/jsr318/index.html" target="_blank">EJB
Specification</a>, container-managed transactions are enabled by default for
session beans. Furthermore, if you examine the Javadoc for both of the above
annotations, you will rightly point out that <code>CONTAINER</code> is the default
<code>TransactionManagementType</code>, and <code>REQUIRED</code> is the default
<code>TransactionAttributeType</code>. In other words, neither of the two annotations
is required for your code to run properly. However, it is often helpful to explicitly
include default settings in your sources to improve readability.</p></li>
<li>Currently, the <code>placeOrder</code> method returns the ID of the processed order.
In the event that the transaction fails and the order isn't processed, have the method
return '<code>0</code>'. Use a <code>try-catch</code> expression.
<pre class="examplecode">
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public int placeOrder(String name, String email, String phone, String address, String cityRegion, String ccNumber, ShoppingCart cart) {
<strong>try {</strong>
Customer customer = addCustomer(name, email, phone, address, cityRegion, ccNumber);
CustomerOrder order = addOrder(customer, cart);
addOrderedItems(order, cart);
return order.getId();
<strong>} catch (Exception e) {
return 0;
}</strong></pre>
<div class="feedback-box float-left" style="width: 683px;">
<h3>NetBeans Support for Code Templates</h3>
<p>When you work in the editor, take advantage of the IDE's support for
code templates. Becoming proficient in using code templates ultimately
enables you to work more efficiently and reliably.</p>
<br>
<p>For example, in the above step you can apply the <code>trycatch</code>
template by typing in '<code>trycatch</code>' then pressing Tab. The
template is added to your file.</p>
<div class="indent">
<pre class="examplecode" style="width:630px">
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public int placeOrder(String name, String email, String phone, String address, String cityRegion, String ccNumber, ShoppingCart cart) {
<strong>try {
} catch (Exception e) {
}</strong>
Customer customer = addCustomer(name, email, phone, address, cityRegion, ccNumber);
CustomerOrder order = addOrder(customer, cart);
addOrderedItems(order, cart);
return order.getId();</pre></div>
<p>You can then move the four existing lines into the <code>try</code> clause
by highlighting the lines, then holding Alt-Shift (Ctrl-Shift on Mac) and
pressing the up arrow key. When you are finished, press F while holding
Alt-Shift (Ctrl-Shift on Mac) to format the code.</p>
<div class="indent">
<pre class="examplecode" style="width:630px">
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public int placeOrder(String name, String email, String phone, String address, String cityRegion, String ccNumber, ShoppingCart cart) {
try {
<strong>Customer customer = addCustomer(name, email, phone, address, cityRegion, ccNumber);
CustomerOrder order = addOrder(customer, cart);
addOrderedItems(order, cart);
return order.getId();</strong>
} catch (Exception e) {
}</pre></div>
<p>It is also possible to view and edit existing code templates, and add
new templates in the IDE. Choose Tools &gt; Options (NetBeans &gt;
Preferences on Mac) to open the Options window. Select Editor &gt;
Code Templates.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/code-templates.png"
class="margin-around b-all" title="View default code templates and define new templates in the Options window"
alt="Options window - Code Templates" style="width:660px"/>
<br>
<p class="tips">If you'd like to see more templates, consult the Keyboard Shortcuts Card.
The Keyboard Shortcuts Card provides a list of commonly-used code templates
and keyboard shortcuts. Choose Help &gt; Keyboard Shortcuts Card from the
main menu.</p>
</div>
<br style="clear: both;"/></li>
<li>Add the following code. Explanation follows.
<pre class="examplecode">
@PersistenceContext(unitName = &quot;AffableBeanPU&quot;)
private EntityManager em;
<strong>@Resource
private SessionContext context;</strong>
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public int placeOrder(String name, String email, String phone, String address, String cityRegion, String ccNumber, ShoppingCart cart) {
try {
Customer customer = addCustomer(name, email, phone, address, cityRegion, ccNumber);
CustomerOrder order = addOrder(customer, cart);
addOrderedItems(order, cart);
return order.getId();
} catch (Exception e) {
<strong>context.setRollbackOnly();</strong>
return 0;
}
}</pre>
Unfortunately, placing the three methods in the <code>try</code> clause
means that if one of them fails during runtime, the engine immediately
jumps to the <code>catch</code> clause, thus skipping any rollback operations
that would normally follow.
<br><br>
<p class="tips">You can test this by commenting out the <code>em.flush()</code>
line you previously added. This way, you know that the first two methods
(<code>addCustomer</code> and <code>addOrder</code>) process successfully,
but the third method (<code>addOrderedItems</code>) fails. Run the project
and submit the checkout form in the browser. Since the transaction doesn't
roll back, the customer and order records are written to the database, but
any ordered items are not. This leads to a situation where the database is
corrupt.</p>
To overcome this, you explicitly set the transaction for rollback in the
<code>catch</code> clause. The above <code>@Resource</code> annotation is
applied to grab an instance of the EJB's current <code>SessionContext</code>.
The transaction is marked for rollback using the <code>setRollbackOnly</code>
method.</li>
<li>Run the project and step through the business process flow. When you submit
an order, return to the IDE and examine the server log. You'll see output
similar to the following:
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/transaction/transaction-output.png"
rel="lytebox" title="Persistence provider output can be examined in the server log">
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/transaction-output.png"
class="margin-around b-all" style="width:688px" alt="Output window - server output"
title="Click to enlarge"></a>
<p class="tips">Press Shift-Esc on the Output window to maximize it.</p>
As shown in the above image, the green text indicates output from EclipseLink.
Recall how in <a href="#entity-session">Adding Entity Classes and Session Beans</a>
you set EclipseLink's logging level to <code>FINEST</code> in the persistence unit.
Being able to examine this output is key to understanding how the persistence provider
interacts with the database and is a great help when you need to debug your project.</li>
</ol>
<p>You've now successfully integrated the transaction into the <code>AffableBean</code> project.
You can <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot8.zip">download
snapshot 8</a> to examine code that completes the request-response cycle when a checkout
form is submitted. The snapshot implements a <code>getOrderDetails</code> method in the
<code>OrderManager</code>, which gathers all details pertaining to the placed order. If
the transaction succeeds, the <code>ControllerServlet</code> places order details in the
request scope, destroys the user's <code>cart</code> object, terminates the session, and
forwards the request to the confirmation view. If the transaction fails, the <code>ControllerServlet</code>
flags an error and forwards the response to the checkout view, enabling the user to attempt
a resubmit.</p>
<div class="indent">
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/checkout-page.png"
alt="Checkout page displayed with process failure message" class="margin-around b-all" style="width:708px"
title="Upon transaction failure, the checkout page redisplays with error message">
</div>
<br>
<h2 id="validate">Validating and Converting User Input</h2>
<p>Also included in
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot8.zip">snapshot
8</a> are implementations for client and server-side validation for the checkout form.
Form validation is the process of checking that a form has been filled in correctly
before it is processed. This not only aids users by providing meaningful feedback for
fields with invalid entries, but it also serves to thwart any malicious attempts to
submit content that could adversely affect processing or storage.</p>
<p>There are two primary methods for validating forms: server-side (in our case, using Java),
and client-side (using JavaScript). Both methods are usually essential for providing
a pleasant user experience, as well as robust security for your application. Client-side
validation is useful for offering immediate feedback to the user without the need to
initiate a round-trip between the browser and server. As such, it can stem network traffic
and decrease the server load. Modern forms of client-side validation are often implemented
to provide immediate, &quot;as-you-type&quot;, field-specific feedback to the user. Client-side
JavaScript is run on the browser, and browsers generally allow JavaScript to be disabled.
For this reason alone, your application cannot rely on client-side validation as the sole
means of guarding against malformed or nefarious input. Server-side validation checks should
therefore be performed when form data reaches the server. Data is extracted from the request
and checked prior to being processed and/or stored. If a validation error is detected,
the server responds by returning the form to the user with an appropriate message. If all
data passes validation, data is converted to a different format if required.</p>
<ul>
<li><a href="#client">Client-Side Validation</a></li>
<li><a href="#server">Server-Side Validation</a></li>
<li><a href="#data">Data Conversion</a></li>
</ul>
<div class="indent">
<h3 id="client">Client-Side Validation</h3>
<p>For the <code>AffableBean</code> application, client-side validation is provided by a
popular <a href="http://plugins.jquery.com/project/validate" target="_blank">jQuery
plugin</a>. jQuery is a cross-browser JavaScript library designed to simplify client-side
scripting of HTML.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/client-side-validation.png"
alt="jQuery field validation displayed on checkout form" class="margin-around b-all"
title="Field validation messages appear upon clicking 'submit purchase'">
<p><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot8.zip">Snapshot
8</a> includes a <code>js</code> folder that contains the jQuery core library
(<code>jquery-1.4.2.js</code>) as well as the script for the validation plugin
(<code>jquery.validate.js</code>). The core library is referenced in the application
<code>header.jspf</code> file, while the validation plugin script is referenced
directly in <code>checkout.jsp</code> since it is only required by that file. Within
<code>checkout.jsp</code>, the plugin is customized to suit the checkout form based
on <a href="http://docs.jquery.com/Plugins/Validation/validate#toptions" target="_blank">available
documentation</a>.
<pre class="examplecode" style="margin-top: 0">
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function(){
$(&quot;#checkoutForm&quot;).validate({
rules: {
name: &quot;required&quot;,
email: {
required: true,
email: true
},
phone: {
required: true,
number: true,
minlength: 9
},
address: {
required: true
},
creditcard: {
required: true,
creditcard: true
}
}
});
});
&lt;/script&gt;</pre>
<p>The IDE provides support for jQuery by enabling you to invoke code completion and documentation
in the editor when pressing Ctrl-Space.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/jquery-editor-support.png"
alt="jQuery documentation popup window in editor" class="margin-around b-all" style="width:688px"
title="Press Ctrl-Space on JavaScript code to invoke jQuery documentation">
<p>When you code in JavaScript, the IDE lets you specify which browsers your application is
targeting. Open the Options window (Choose Tools &gt; Options; NetBeans &gt; Preferences
on Mac), select Miscellaneous, then select the JavaScript tab.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/javascript-window.png"
alt="Options window - JavaScript pane" class="margin-around b-all"
title="Specify targetted browsers for your application in the Options window">
<p>If the function you are calling documentation on does not support all of your targeted browsers,
the documentation popup flags a warning. For example in the image below, Internet Explorer version
5.5 has been included in the application's targeted browsers.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/ie-55.png"
alt="JavaScript documentation popup" class="margin-around b-all"
title="Documentation popup warns of method calls to non-compatible browser versions">
<h3 id="server">Server-Side Validation</h3>
<p>The purpose of server-side validation is to ensure that each piece of data is in a
format that is ready for further processing or is acceptable for storage. By &quot;format&quot;,
we mean both the data type as well as the size of the piece of data. The generated JPA
entity classes are guaranteed to map their properties to the appropriate data types of
the corresponding database table columns. When relying on these entity classes, we need
to not only make sure that user data can be applied to create (or update) entity classes,
but that the size of the data is appropriate for the data types of the database columns.</p>
<p>To illustrate an example, consider the checkout form's credit card number field. Client-side
validation checks that the entered data does not include letters.<sup><a href="#footnote2Transaction"
id="2Transaction" style="text-decoration:none">[2]</a></sup> Because the <code>maxlength</code>
attribute in the HTML markup is set to <code>19</code>, users cannot enter more than 19 characters
into this field. Server-side validation also places a limit at 19 characters. Keep in mind
that the data type of the <code>cc_number</code> column in the database's <code>customer</code>
table is: <code>VARCHAR(19)</code> (Refer to step 3 of <a href="data-model.html#addProperties">Designing
the Data Model: Adding Entity Properties</a>.) Now, consider what would happen if the data
type of the <code>cc_number</code> column is set to <code>VARCHAR(16)</code>, and a user
enters a number that is 19 characters long. When the checkout form is submitted, the
<code>creditcard</code> parameter is extracted from the request and converted into a
<code>String</code> so that it becomes the <code>ccNumber</code> property in a newly
created <code>Customer</code> object. Because 16 is the maximum number of characters
the database column will hold, the database server will either truncate the number to
16 characters or produce a <code>MysqlDataTruncation</code> error, depending on the SQL
mode set for the server. (For more information on the <code>VARCHAR</code> data type,
see <a href="http://dev.mysql.com/doc/refman/5.1/en/char.html" target="_blank">10.4.1.
The CHAR and VARCHAR Types</a>.) In this manner, by not having client and server-side
validation properly handle the size (i.e., length) of the data received for a credit
card number, we risk a failed attempt at placing an order, or perhaps even worse, a
truncated credit card number, which obviously won't allow payment.</p>
<p>Server-side validation in the <code>AffableBean</code> project is implemented by means of
a <code>Validator</code> class. The <code>ControllerServlet</code> creates a <code>Validator</code>
object and calls its <code>validateForm</code> method on the user data:</p>
<pre class="examplecode" style="margin-top: 0">
// validate user data
boolean validationErrorFlag = false;
validationErrorFlag = validator.validateForm(name, email, phone, address, cityRegion, ccNumber, request);
// if validation error found, return user to checkout
if (validationErrorFlag == true) {
request.setAttribute(&quot;validationErrorFlag&quot;, validationErrorFlag);
userPath = &quot;/checkout&quot;;
// otherwise, save order to database
} else {
...
}</pre>
<p>If a validation error is found (i.e., if <code>validateForm</code> returns <code>true</code>),
a flag is raised in the form of a request-scoped attribute, and the server sends the
checkout page back to the client. When the flag is detected in <code>checkout.jsp</code>,
a new table row is created to display error messages at the top of the table.</p>
<pre class="examplecode" style="margin-top: 0">
&lt;form id=&quot;checkoutForm&quot; action=&quot;&lt;c:url value='purchase'/&gt;&quot; method=&quot;post&quot;&gt;
&lt;table id=&quot;checkoutTable&quot;&gt;
&lt;c:if test=&quot;${!empty validationErrorFlag}&quot;&gt;
&lt;tr&gt;
&lt;td colspan=&quot;2&quot; style=&quot;text-align:left&quot;&gt;
&lt;span class=&quot;error smallText&quot;&gt;Please provide valid entries for the following field(s):
&lt;c:if test=&quot;${!empty nameError}&quot;&gt;
&lt;br&gt;&lt;span class=&quot;indent&quot;&gt;&lt;strong&gt;name&lt;/strong&gt; (e.g., Bilbo Baggins)&lt;/span&gt;
&lt;/c:if&gt;
&lt;c:if test=&quot;${!empty emailError}&quot;&gt;
&lt;br&gt;&lt;span class=&quot;indent&quot;&gt;&lt;strong&gt;email&lt;/strong&gt; (e.g., b.baggins@hobbit.com)&lt;/span&gt;
&lt;/c:if&gt;
&lt;c:if test=&quot;${!empty phoneError}&quot;&gt;
&lt;br&gt;&lt;span class=&quot;indent&quot;&gt;&lt;strong&gt;phone&lt;/strong&gt; (e.g., 222333444)&lt;/span&gt;
&lt;/c:if&gt;
&lt;c:if test=&quot;${!empty addressError}&quot;&gt;
&lt;br&gt;&lt;span class=&quot;indent&quot;&gt;&lt;strong&gt;address&lt;/strong&gt; (e.g., KorunnĂ­ 56)&lt;/span&gt;
&lt;/c:if&gt;
&lt;c:if test=&quot;${!empty cityRegionError}&quot;&gt;
&lt;br&gt;&lt;span class=&quot;indent&quot;&gt;&lt;strong&gt;city region&lt;/strong&gt; (e.g., 2)&lt;/span&gt;
&lt;/c:if&gt;
&lt;c:if test=&quot;${!empty ccNumberError}&quot;&gt;
&lt;br&gt;&lt;span class=&quot;indent&quot;&gt;&lt;strong&gt;credit card&lt;/strong&gt; (e.g., 1111222233334444)&lt;/span&gt;
&lt;/c:if&gt;
&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/c:if&gt;
...
&lt;/table&gt;
&lt;/form&gt;</pre>
<p>You can test server-side validation by temporarily disabling JavaScript in your browser.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/transaction/server-side-validation.png"
alt="Server-side validation displayed on checkout form" class="margin-around b-all"
title="Temporarily disable JavaScript in your browser to test server-side validation">
<p class="alert">The provided implementation of server-side validation here serves merely to
demonstrate how server-side validation can be set up in your project. The actual validation
logic contained in the <code>Validator</code> class does not perform anything beyond the
most basic of checks and should certainly not be used in a production environment!</p>
<h3 id="data">Data Conversion</h3>
<p>Sometimes, after data has passed validation, you may need to convert it into a different
format. For example, this might apply to dates when users are allowed to enter them manually,
or numbers that have been received as <code>String</code> objects but require calculation.
This important step is referred to as server-side <em>data conversion</em>.</p>
<p>Although not implemented in the <code>AffableBean</code> application, consider again the
checkout form's credit card number field. Both client and server-side validation allows
for both formats of the following number:</p>
<pre class="examplecode">1111222233334444</pre>
and:
<pre class="examplecode">1111-2222-3333-4444</pre>
<p>Because of the ambiguous nature in which this piece of user data is acquired, it might
be necessary to remove any hyphens ('<code>-</code>') or other non-numeric characters
prior to processing payment. This step would likely occur before the data is placed
in storage.</p>
</div>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans E-commerce Tutorial - Integrating Transactional Business Logic">Send
Us Your Feedback</a></div>
<br style="clear:both;">
<h2 id="seeAlsoTransaction">See Also</h2>
<div class="indent">
<h3>NetBeans Resources</h3>
<ul>
<li><a href="../javaee-intro.html" target="_blank">Introduction to Java EE Technology</a></li>
<li><a href="../javaee-gettingstarted.html" target="_blank">Getting Started with Java EE Applications</a></li>
<li><a href="https://netbeans.org/projects/www/downloads/download/shortcuts.pdf">Keyboard Shortcuts & Code Templates Card</a></li>
<li><a href="../../../trails/java-ee.html" target="_blank">Java EE & Java Web Learning Trail</a></li>
</ul>
<h3>External Resources</h3>
<ul>
<li><a href="http://jcp.org/aboutJava/communityprocess/final/jsr318/index.html" target="_blank">JSR 318: EJB 3.1 Final Release</a> [Specification Download]</li>
<li><a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/tutorial/doc/bncih.html" target="_blank">Java EE 6 Tutorial: Transactions</a></li>
<li><a href="http://www.manning.com/panda/" target="_blank">EJB 3 in Action</a> [Book]</li>
<li><a href="http://en.wikipedia.org/wiki/Database_transaction" target="_blank">Database Transaction</a> [Wikipedia]</li>
<li><a href="http://en.wikipedia.org/wiki/Ejb" target="_blank">Enterprise JavaBean</a> [Wikipedia]</li>
<li><a href="http://en.wikipedia.org/wiki/ACID" target="_blank">ACID</a> [Wikipedia]</li>
<li><a href="http://jquery.com/" target="_blank">jQuery</a></li>
<li><a href="http://en.wikipedia.org/wiki/Jquery" target="_blank">jQuery</a> [Wikipedia]</li>
</ul>
</div>
<br>
<h2>References</h2>
<ol>
<li id="footnote1Transaction"><a href="#1Transaction" style="text-decoration:none">^</a> This <em>all or nothing</em> concept
can be further extrapolated into the four defining characteristics of transactions: <em>atomicity</em>,
<em>consistency</em>, <em>isolation</em>, and <em>durability</em> (ACID). For more information, see:
<a href="http://en.wikipedia.org/wiki/ACID" target="_blank">ACID</a> [Wikipedia].</li>
<li id="footnote2Transaction"><a href="#2Transaction" style="text-decoration:none">^</a> Actually, for credit card number entries,
validation typically ensures that the entered string conforms to the Luhn algorithm, which is a simple
method of differentiating between valid numbers and a collection of random digits. This applies to the
<a href="http://plugins.jquery.com/project/validate" target="_blank">jQuery validation plugin</a> as
well. For more information, see
<a href="http://en.wikipedia.org/wiki/Luhn_algorithm" target="_blank">Luhn algorithm</a> [Wikipedia].</li>
</ol>
<br><br><br><br>
<h1 id="language">The NetBeans E-commerce Tutorial - Adding Language Support</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Tutorial Contents</h4>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#design">Designing the Application</a></li>
<li><a href="#setup-dev-environ">Setting up the Development Environment</a></li>
<li><a href="#data-model">Designing the Data Model</a></li>
<li><a href="#page-views-controller">Preparing the Page Views and Controller Servlet</a></li>
<li><a href="#connect-db">Connecting the Application to the Database</a></li>
<li><a href="#entity-session">Adding Entity Classes and Session Beans</a></li>
<li><a href="#manage-sessions">Managing Sessions</a></li>
<li><a href="#transaction">Integrating Transactional Business Logic</a></li>
<li><strong>Adding Language Support</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#resourceBundles">Understanding Resource Bundles</a></li>
<li><a href="#multilingual">Making Pages Multilingual</a></li>
<li><a href="#toggle">Implementing a Language Toggle</a></li>
<li><a href="#seeAlsoLanguage">See Also</a></li>
</ul></li>
<li><a href="#security">Securing the Application</a></li>
<li><a href="#test-profile">Testing and Profiling</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ol>
</div>
</div>
<p><img src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" class="stamp"
alt="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"
title="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"></p>
<p>The goal of this tutorial unit is to demonstrate how to enable language support
for a web application. &quot;Language support&quot; here refers to the ability
to display page views according to the customer-specified languages. Within the
context of the <code>AffableBean</code> application, we have agreed to provide
support for both English and Czech, as per the previously outlined
<a href="design.html#requirements">customer requirements</a>.</p>
<p>In order to accomplish this, you rely on Java's support for internationalization.
You create a <em>resource bundle</em> for each language and let the Java runtime
environment determine the appropriate language for incoming client requests. You
also implement a 'language toggle' to enable users to switch the languages manually.</p>
<p>The NetBeans IDE provides special support for localizing application content. This
includes a Customizer dialog that enables you to add new locales to an existing
resource bundle base name, as well as a special Properties editor that lets you
view and edit key-value pairs for all locales in a table layout. These are both
utilized in this tutorial.</p>
<p>You can view a live demo of the application that you build in this tutorial:
<a href="http://services.netbeans.org/AffableBean/" target="_blank">NetBeans
E-commerce Tutorial Demo Application</a>.</p>
<br style="clear:left;">
<br>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html" target="_blank">NetBeans IDE</a></td>
<td class="tbltd1">Java bundle, 6.8 or 6.9</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank">Java Development Kit (JDK)</a></td>
<td class="tbltd1">version 6</td>
</tr>
<tr>
<td class="tbltd1"><a href="#glassFishLanguage">GlassFish server</a></td>
<td class="tbltd1">v3 or Open Source Edition 3.0.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://dev.mysql.com/downloads/mysql/" target="_blank">MySQL database server</a></td>
<td class="tbltd1">version 5.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot8.zip">AffableBean
project</a></td>
<td class="tbltd1">snapshot 8</td>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot9.zip">AffableBean
project</a></td>
<td class="tbltd1">snapshot 9</td>
</tr>
</tbody>
</table>
<p><strong class="notes">Notes:</strong></p>
<ul>
<li>The NetBeans IDE requires the Java Development Kit (JDK) to run properly.
If you do not have any of the resources listed above, the JDK should be
the first item that you download and install.</li>
<li>The NetBeans IDE Java Bundle includes Java Web and EE technologies, which are
required for the application you build in this tutorial.</li>
<li id="glassFishLanguage">The NetBeans IDE Java Bundle also includes the GlassFish server,
which you require for this tutorial. You could
<a href="http://glassfish.dev.java.net/public/downloadsindex.html" target="_blank">download
the GlassFish server independently</a>, but the version provided with the
NetBeans download has the added benefit of being automatically registered with
the IDE.</li>
<li>You can follow this tutorial unit without having completed previous units. To
do so, see the <a href="#setup">setup instructions</a>, which describe how
to prepare the database and establish connectivity between the IDE, GlassFish,
and MySQL.</li>
</ul>
<br>
<h2 id="resourceBundles">Understanding Resource Bundles</h2>
<p>In Java, a resource bundle is a representation of the
<a href="http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/ResourceBundle.html" target="_blank"><code>java.util.ResourceBundle</code></a>
class. As stated in the Javadoc,</p>
<blockquote style="margin-top: 0">
<em>Resource bundles contain locale-specific objects. When your program needs
a locale-specific resource, a String for example, your program can load it
from the resource bundle that is appropriate for the current user's locale.
In this way, you can write program code that is largely independent of the
user's locale isolating most, if not all, of the locale-specific information
in resource bundles.
<br><br>
This allows you to write programs that can:</em>
<ul style="margin: 5px 0 0 -1em">
<li><em>be easily localized, or translated, into different languages</em></li>
<li><em>handle multiple locales at once</em></li>
<li><em>be easily modified later to support even more locales</em></li>
</ul>
</blockquote>
<p>From the Javadoc, you can also note that the <code>ResourceBundle</code> is parent
to both <a href="http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/ListResourceBundle.html" target="_blank"><code>ListResourceBundle</code></a>
and <a href="http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/PropertyResourceBundle.html" target="_blank"><code>PropertyResourceBundle</code></a>.
In this tutorial we utilize the <code>PropertyResourceBundle</code>, which manages
resources as text files that use the <code>.properties</code> extension and contain
locale-specific information in the form of key-value pairs. With new each translation,
a new version of the resource bundle is created by appending the locale identifier
to the base name using an underscore ('<code>_</code>'). For example, snippets from
two of the resource bundles you create in this tutorial look as follows:</p>
<p><strong>messages_en.properties</strong></p>
<pre class="examplecode" style="margin-top:0">
meats=meats
bakery=bakery</pre>
<p><strong>messages_cs.properties</strong></p>
<pre class="examplecode" style="margin-top:0">
meats=maso
bakery=peÄŤivo</pre>
<p>In the above example, '<code>messages</code>' represents the base name, and the locale
identifier is the two-letter code which is appended using an underscore. (i.e., '<code>en</code>'
for English, '<code>cs</code>' for Czech). The two-letter codes are derived from the
international <a href="http://en.wikipedia.org/wiki/ISO_639" target="_blank">ISO 639</a>
standard, which lists codes that represent the names of languages. The ISO 639 standard
is adopted by the <a href="http://www.w3.org/International/" target="_blank">W3C
Internationalization Activity</a> and is used by all major browsers (these are the codes
understood in the <code>Accept-Language</code> HTTP header). It is also internalized in the
<a href="http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/Locale.html" target="_blank"><code>java.util.Locale</code></a>
class.</p>
<br>
<h2 id="multilingual">Making Pages Multilingual</h2>
<p>Returning to the <code>AffableBean</code> application, after continued discussions with
the customer you've agreed on the following implementation details:</p>
<ul style="margin: 0 0 0 -.7em" id="impDeets">
<li>The website initially displays based on the preferred language of the user's
browser.</li>
<li>If the browser's preferred language is neither English nor Czech, the site
displays text in English.</li>
<li>The user has the option of changing the language by means of a 'language toggle'
in the page header.</li>
<li>When using the language toggle to change the language, the user remains in the
same page view.</li>
<li>The language toggle should not appear for the confirmation page, as a user will
already have selected his or her language prior to checkout.</li>
</ul>
<p>In order to implement the above points, divide the task into two parts. Start by
creating basic bilingual support for page views. Once bilingual support is in place,
implement the language toggle that enables users to manually switch languages.</p>
<p>There are three basic steps that you need to follow to incorporate multilingual support
into your web pages.</p>
<ol style="margin: 0">
<li>Create a resource bundle for each language you plan to support.</li>
<li>Register the resource bundle with the application by setting a context parameter
in the <code>web.xml</code> deployment descriptor.</li>
<li>In page views, replace 'hard-coded' text with <code>&lt;fmt:message&gt;</code> tags
that reference keys in the resource bundles.</li>
</ol>
<p>The following exercise demonstrates how to integrate English and Czech language support
into the <code>AffableBean</code> welcome page by applying the above three steps, and
finishes by showing how to test for browser language support using Firefox.</p>
<ol>
<li><a href="#createResource">Create Resource Bundles</a></li>
<li><a href="#register">Register the Resource Bundle with the Application</a></li>
<li><a href="#replace">Replace 'Hard-Coded' Text with <code>&lt;fmt:message&gt;</code> Tags</a></li>
<li><a href="#test">Test Supported Languages</a></li>
</ol>
<div class="indent">
<h3 id="createResource">Create Resource Bundles</h3>
<ol>
<li>Open the <code>AffableBean</code> project <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot8.zip">snapshot
8</a> in the IDE. Click the Open Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/open-project-btn.png"
alt="Open Project button"> ) button and use the wizard to navigate to the location
on your computer where you downloaded the project.</li>
<li>Click the Run Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) button to run the project and ensure that it is properly
configured with your database and application server.
<br><br>
<p class="alert">If you receive an error when running the project, revisit the
<a href="#setup">setup instructions</a>, which describe how to prepare the
database and establish connectivity between the IDE, GlassFish, and MySQL.</p></li>
<li>Begin by creating a default resource bundle to contain text used in page views. Click
the New File (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/new-file-btn.png"
alt="New File button"> ) button in the IDE's toolbar. (Alternatively, press Ctrl-N;
&#8984;-N on Mac.)</li>
<li>Under Categories select Other, then under File Types select Properties File.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/new-file-wzd.png"
class="margin-around b-all" alt="New File wizard"
title="Create a new resource bundle using the File wizard">
<br>
Note that the wizard provides a description for the selected file type:
<blockquote>
<em>Creates a resource bundle (<code>.properties</code>) file suitable for internationalizing
applications by separating out all human-visible text strings from your code. Resource
bundle files can also be used to collect other types of strings, such as properties for
Ant scripts. The created resource bundle contains only one locale, but you can add additional
locales from the created file's contextual menu. The bundle can be edited in a text file
(property-file format) for a specific locale or in a table that displays information for
all locales.</em>
</blockquote></li>
<li>Click Next. In the Name and Location step, name the file <code>messages</code> and type
in <code>src/java/resources</code> in the Folder field. This will instruct the wizard
to place the resource bundle in a new package named <code>resources</code>.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/new-properties-file-wzd.png"
class="margin-around b-all" alt="New Properties File wizard"
title="Specify the name and location of the resource bundle"></li>
<li>Click Finish. The <code>messages.properties</code> resource bundle is generated and opens
in the editor.
<br><br>
Note that the new <code>messages.properties</code> file name does not have a language
code appended to it, as was previously described. This is because this file will be used
as the <em>default</em> resource bundle. The default resource bundle is applied when the
Java runtime environment does not find a direct match for the requested locale.</li>
<li>Open the project's <code>index.jsp</code> file in the editor and note that the following
text is currently used:
<ul style="margin: 5px 0 0 -1em">
<li><strong>Greeting:</strong> <code>Welcome to the online home of the Affable Bean Green Grocer.</code></li>
<li><strong>Introductory Message:</strong> <code>Enjoy browsing and learning more about our
unique home delivery service bringing you fresh organic produce, dairy, meats, breads
and other delicious and healthy items to your doorstep.</code></li>
</ul>
Also, note that we'll need language-specific names for the four categories that display
when <code>index.jsp</code> renders in the browser. Since these names are currently taken
from the database, we can use them as keys in the resource bundle.
<br><br>
Recall that one of the <a href="#impDeets">implementation details</a> outlined above states
that &quot<em>if the browser's preferred language is neither English nor Czech, the site
displays text in English.</em>&quot; Therefore, the values that we apply to the
<code>messages.properties</code> file will be in English.</li>
<li>In the <code>messages.properties</code> file, begin adding key-value pairs for the text used
in the welcome page. Add the following content.
<pre class="examplecode">
# welcome page
greeting=Welcome to the online home of the Affable Bean Green Grocer.
introText=Our unique home delivery service brings you fresh organic produce, dairy, meats, breads and other delicious and healthy items direct to your doorstep.
# categories
dairy=dairy
meats=meats
bakery=bakery
fruit\ &\ veg=fruit & veg</pre>
Comments are added using a number sign ('<code>#</code>'). Also, because the <code>fruit & veg</code>
category name contains spaces, it is necessary to escape the space characters using a backslash
('<code>\</code>') in order to apply the name as a resource bundle key.
<br><br>
We are now finished with the default resource bundle for the application's welcome page.
Let's continue by creating resource bundles for the customer-specified languages.</li>
<li>In the Projects window, expand the Source Packages node, then right-click the <code>resources</code>
&gt; <code>messages.properties</code> file node and choose Customize. The Customizer dialog
opens.</li>
<li>In the Customizer dialog, click the Add Locale button. In the New Locale dialog that
displays, enter '<code>en</code>' in the Language Code combo box, then click OK.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/new-locale-dialog.png"
class="margin-around b-all" alt="New Locale dialog"
title="The New Locale dialog enables you to add a new locale to an existing resource bundle base name">
<br>
<p class="tips">A <em>locale</em> can be defined by both a language and a geographic region.
The optional country code which can be used to specify the region can be applied to define
formatting for dates, time, numbers, and currency. For more information, see the technical
article, <a href="http://java.sun.com/developer/technicalArticles/J2SE/locale/" target="_blank">Understanding
Locale in the Java Platform</a>.</p></li>
<li>Click the Add Locale button again, then enter '<code>cs</code>' in the Language Code combo
box and click OK. The Customizer dialog displays as follows.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/customizer-dialog.png"
class="margin-around b-all" alt="New Locale dialog"
title="The New Locale dialog enables you to add a new locale to an existing resource bundle base name"></li>
<li>Click Close. In the Projects window, note that your resource bundles look as follows. You can
expand a resource bundle to view the keys it contains.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/projects-window.png"
class="margin-around b-all" alt="Resource bundles displayed in Projects window"
title="View resource bundles and the keys they contain in the Projects window"></li>
<li>Right-click any of the three resource bundles and choose Open. The Properties editor opens,
enabling you to view and edit key-value pairs for all locales in a table layout.
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/language/properties-editor.png"
rel="lytebox" title="Use the Properties editor to view and edit key-value pairs for all locales"
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/properties-editor.png"
class="margin-around b-all" alt="Properties editor for resource bundles" style="width:688px"
title="Click to enlarge"></a>
<p class="tips">Press Shift-Esc to maximize the window in the IDE.</p>
Note that when you add a new locale using the Customizer dialog, as you did for English and
Czech in the previous steps, the keys and values of the default resource bundle are copied
to the new locale.</li>
<li>Modify the values for the Czech resource bundle. You can do this by <em>either</em> clicking
into the table cells for each row and typing your entries directly <em>or</em> selecting the
cell you want to edit and typing into the <strong>Value</strong> field located at the bottom
of the Properties editor.
<ul style="margin: 5px 0 0 -1em">
<li><strong>greeting:</strong> <code>Vítejte v našem domácím on-line obchodě Affable Bean Green Grocer.</code></li>
<li><strong>introText:</strong> <code>Naše jedinečná dodávková služba Vám zajistí dopravu čerstvých organických produktů, mléčných výrobků, uzenin, pečiva a dalších delikates a zdravých výroků až ke dveřím.</code></li>
<li><strong>dairy:</strong> <code>mléčné výrobky</code></li>
<li><strong>meats:</strong> <code>maso</code></li>
<li><strong>bakery:</strong> <code>peÄŤivo</code></li>
<li><strong>fruit & veg:</strong> <code>ovoce a zeleniny</code></li>
</ul>
<p class="tips">You can also add a comment to each key-value pair. Any text you enter into
the <strong>Comment</strong> field in the Properties editor is added to the resource
bundle text file above the key-value pair as a comment (i.e., following a '<code>#</code>'
sign).</p></li>
<li>Double-click the <code>messages_cs.properties</code> file node in the Projects window. Note
that the text file has been updated according to your changes in the Properties editor.
<pre class="examplecode">
# welcome page
greeting=Vítejte v našem domácím on-line obchodě Affable Bean Green Grocer.
introText=Naše jedinečná dodávková služba Vám zajistí dopravu čerstvých organických produktů, mléčných výrobků, uzenin, pečiva a dalších delikates a zdravých výroků až ke dveřím.
# categories
dairy=mléčné výrobky
meats=maso
bakery=peÄŤivo
fruit\ &\ veg=ovoce a zeleniny</pre></li>
</ol>
<p>We now have the following resource bundles defined:</p>
<ul style="margin: 5px 0 0 -1em">
<li>default (English)</li>
<li>Czech</li>
<li>English</li>
</ul>
<p>You might assume that if the default bundle is in English, then there is no need to
create a resource bundle explicitly for English. However, consider the following scenario:
a client browser's list of preferred languages includes both Czech and English, with
English taking precedence over Czech. If the application doesn't provide a resource
bundle for English but does for Czech, pages sent to that browser will be in Czech
(since a Czech bundle was defined). This is clearly not the desired behavior for that
browser.</p>
<h3 id="register">Register the Resource Bundle with the Application</h3>
<p>The purpose of this step is to inform JSTL's format (i.e.,
<a href="http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/jstl/1.1/docs/tlddocs/fmt/tld-summary.html" target="_blank"><code>fmt</code></a>)
tag library where it can locate any resource bundles existing in the application. You
accomplish this by instructing the application to create a
<a href="http://download.oracle.com/docs/cd/E17477_01/javaee/5/jstl/1.1/docs/api/javax/servlet/jsp/jstl/fmt/LocalizationContext.html" target="_blank"><code>LocalizationContext</code></a>
using the existing resource bundles. This can be done by setting a context parameter
in the application's <code>web.xml</code> deployment descriptor.</p>
<p class="tips">The topic of setting context parameters is also covered in
<a href="connect-db.html#param">Connecting the Application to the Database</a>.</p>
<ol>
<li>In the Projects window, expand the Configuration Files node, then double-click
<code>web.xml</code> to open it in the editor.</li>
<li>Under the deployment descriptor's General tab, expand the Context Parameters
category.</li>
<li>Click the Add button, then in the Add Context Parameter dialog enter the following
values.
<ul style="margin: 5px 0 0 -1em">
<li><strong>Parameter Name:</strong> <code>javax.servlet.jsp.jstl.fmt.localizationContext</code></li>
<li><strong>Parameter Value:</strong> <code>resources.messages</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/add-context-parameter.png"
class="margin-around b-all" alt="Add Context Parameter dialog"
title="Add context parameters under the General tab for web.xml">
<p class="tips">The <code>LocalizationContext</code> class belongs to the
<code>javax.servlet.jsp.jstl.fmt</code> package. You can verify this by viewing
the <a href="http://java.sun.com/products/jsp/jstl/1.1/docs/api/index.html" target="_blank">JSTL
1.1 API Reference</a> online.</p></li>
<li>Click OK. The new context parameter is added to the table of existing context parameters
under the General tab.</li>
<li>Click the deployment descriptor's XML tab. Note that the following entry has been
added to the file:
<pre class="examplecode">
&lt;context-param&gt;
&lt;param-name&gt;javax.servlet.jsp.jstl.fmt.localizationContext&lt;/param-name&gt;
&lt;param-value&gt;resources.messages&lt;/param-value&gt;
&lt;/context-param&gt;</pre></li>
</ol>
<h3 id="replace">Replace Hard-Coded Text with <code>&lt;fmt:message&gt;</code> Tags</h3>
<p>In order to apply the localized text of resource bundles to your web pages, you reference
the keys from the key-value pairs you created. You can reference the keys using JSTL's
<code>&lt;fmt:message&gt;</code> tags.</p>
<ol>
<li>Open the project's <code>index.jsp</code> page in the editor. (If already opened,
press Ctrl-Tab to switch to the file.)</li>
<li>Delete instances of hard-coded text that display in the page's left column, and
in their place enter <code>&lt;fmt:message&gt;</code> tags using the <code>key</code>
attribute to specify the resource bundle key. The page's left column will look as
follows.
<pre class="examplecode">
&lt;div id=&quot;indexLeftColumn&quot;&gt;
&lt;div id=&quot;welcomeText&quot;&gt;
&lt;p style=&quot;font-size: larger&quot;&gt;<strong>&lt;fmt:message key='greeting'/&gt;</strong>&lt;/p&gt;
&lt;p&gt;<strong>&lt;fmt:message key='introText'/&gt;</strong>&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</pre></li>
<li>Add <code>&lt;fmt:message&gt;</code> tags for the four category names, but use
the <code>${category.name}</code> expression as the value for the <code>key</code>
attribute. Since the category name is also used as the value for the <code>&lt;img&gt;</code>
tag's <code>alt</code> attribute, follow the same procedure. The page's right
column will look as follows.
<pre class="examplecode">
&lt;div id=&quot;indexRightColumn&quot;&gt;
&lt;c:forEach var=&quot;category&quot; items=&quot;${categories}&quot;&gt;
&lt;div class=&quot;categoryBox&quot;&gt;
&lt;a href=&quot;&lt;c:url value='category?${category.id}'/&gt;&quot;&gt;
&lt;span class=&quot;categoryLabel&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;categoryLabelText&quot;&gt;<strong>&lt;fmt:message key='${category.name}'/&gt;</strong>&lt;/span&gt;
&lt;img src=&quot;${initParam.categoryImagePath}${category.name}.jpg&quot;
alt=&quot;<strong>&lt;fmt:message key='${category.name}'/&gt;</strong>&quot; class=&quot;categoryImage&quot;&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/c:forEach&gt;
&lt;/div&gt;</pre></li>
<li>Finally, ensure that you have the <code>fmt</code> tag library declared in the
web page. Enter the following at the top of the file:
<pre class="examplecode">&lt;%@ taglib prefix=&quot;fmt&quot; uri=&quot;http://java.sun.com/jsp/jstl/fmt&quot; %&gt;</pre>
<p class="notes"><strong>Note:</strong> Here you add the tag library declaration
to the top of the <code>index.jsp</code> file. However, when you begin using
<code>&lt;fmt&gt;</code> tags elsewhere in the project, it may make more sense
to remove the tag library declaration from individual page views, and add it
to the header (<code>header.jspf</code>) file. This practice is adopted in
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot9.zip">snapshot
9</a> (and later snapshots).</p>
</li>
</ol>
<p>You've now completed the tasks necessary for providing bilingual support for the
application's welcome page. The following step demonstrates how to test the language
support in your browser.</p>
<h3 id="test">Test Supported Languages</h3>
<p>You could theoretically test for the following scenarios involving the application's
supported languages, as well as an unsupported language (e.g., Korean):</p>
<div class="indent">
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Use-case</th>
<th class="tblheader" scope="col">Outcome</th>
</tr>
<tr>
<td class="tbltd1">&nbsp;1. Browser has no preferred language</td>
<td class="tbltd1">English displays</td>
</tr>
<tr>
<td class="tbltd1">&nbsp;2. Browser prefers only English</td>
<td class="tbltd1">English displays</td>
</tr>
<tr>
<td class="tbltd1">&nbsp;3. Browser prefers only Czech</td>
<td class="tbltd1">Czech displays</td>
</tr>
<tr>
<td class="tbltd1">&nbsp;4. Browser prefers only Korean</td>
<td class="tbltd1">English displays</td>
</tr>
<tr>
<td class="tbltd1">&nbsp;5. Browser prefers Korean and English; Korean takes precedence</td>
<td class="tbltd1">English displays</td>
</tr>
<tr>
<td class="tbltd1">&nbsp;6. Browser prefers Korean and English; English takes precedence</td>
<td class="tbltd1">English displays</td>
</tr>
<tr>
<td class="tbltd1">&nbsp;7. Browser prefers Korean and Czech; Korean takes precedence</td>
<td class="tbltd1">Czech displays</td>
</tr>
<tr>
<td class="tbltd1">&nbsp;8. Browser prefers Korean and Czech; Czech takes precedence</td>
<td class="tbltd1">Czech displays</td>
</tr>
<tr>
<td class="tbltd1">&nbsp;9. Browser prefers English and Czech; English takes precedence</td>
<td class="tbltd1">English displays</td>
</tr>
<tr>
<td class="tbltd1">10. Browser prefers English and Czech; Czech takes precedence</td>
<td class="tbltd1">Czech displays</td>
</tr>
<tr>
<td class="tbltd1">11. Browser prefers, in the following order, English, Czech, Korean</td>
<td class="tbltd1">English displays</td>
</tr>
<tr>
<td class="tbltd1">12. Browser prefers, in the following order, English, Korean, Czech</td>
<td class="tbltd1">English displays</td>
</tr>
<tr>
<td class="tbltd1">13. Browser prefers, in the following order, Czech, English, Korean</td>
<td class="tbltd1">Czech displays</td>
</tr>
<tr>
<td class="tbltd1">14. Browser prefers, in the following order, Czech, Korean, English</td>
<td class="tbltd1">Czech displays</td>
</tr>
<tr>
<td class="tbltd1">15. Browser prefers, in the following order, Korean, English, Czech</td>
<td class="tbltd1">English displays</td>
</tr>
<tr>
<td class="tbltd1">16. Browser prefers, in the following order, Korean, Czech, English</td>
<td class="tbltd1">Czech displays</td>
</tr>
</tbody>
</table>
</div>
<br>
<p>Rather than stepping through all 16 scenarios, we'll demonstrate how to examine scenario 3 above, in which
the browser's preferred language is Czech, using the Firefox browser.</p>
<ol>
<li>In Firefox, choose Tools &gt; Options (Firefox &gt; Preferences on Mac). In the window that
displays, click the Content tab.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/firefox-content.png"
class="margin-around b-all" alt="Firefox options - Content tab"
title="Examine your browser's preferred languages"></li>
<li>Under the Languages heading, click Choose.</li>
<li>Select any language that is currently listed in the provided text area, then click Remove.
(You should remember your language list and reinstate languages after completing this tutorial.)</li>
<li>Click the 'Select Language to Add' drop-down and select <code>Czech [cs]</code>. Then
click the Add button. The Czech language is added to the text area.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/firefox-languages.png"
class="margin-around b-all" alt="Firefox options - General tab"
title="Specify your browser's preferred languages"></li>
<li>Click OK, then press Esc to close Firefox' Options window.</li>
<li>Run the project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ). When the welcome page opens in your browser, note
that text is displayed in Czech.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/czech-text.png"
class="margin-around b-all" alt="Czech text displayed in welcome page" style="width:688px"
title="The displayed language is determined by your browser's language preferences"></li>
</ol>
</div>
<br>
<h2 id="toggle">Implementing a Language Toggle</h2>
<p>Now that basic Czech-English language support is in place, continue by implementing the language
toggle in the application's page views. We can divide this task into three parts:</p>
<ul>
<li><a href="#toggleDisplay">Create Toggle Display and Synchronize with the Browser's Preferred Language</a></li>
<li><a href="#handleRequest">Implement Functionality to Handle a Request from the Language Toggle</a></li>
<li><a href="#keepTrack">Enable the Application to Keep Track of the Originating Page View</a></li>
</ul>
<div class="indent">
<h3 id="toggleDisplay">Create Toggle Display and Synchronize with the Browser's Preferred Language</h3>
<ol>
<li>Use the Go to File dialog to open the <code>header</code> JSP fragment in the editor. Press
Alt-Shift-O (Ctrl-Shift-O on Mac), then type '<code>h</code>' in the dialog and click OK.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/go-to-file-dialog.png"
class="margin-around b-all" alt="Go to File dialog"
title="Use the Go to File dialog to quickly open project resources in the editor"></li>
<li>In the <code>header.jspf</code> file, locate the first <code>&lt;div class=&quot;headerWidget&quot;&gt;</code>
tag (line 56), and replace the <code>[ language toggle ]</code> placeholder text with the
following HTML markup.
<pre class="examplecode">
&lt;div class=&quot;headerWidget&quot;&gt;
<strong>&lt;%-- language selection widget --%&gt;
english | &lt;div class=&quot;bubble&quot;&gt;&lt;a href=&quot;chooseLanguage?language=cs&quot;&gt;česky&lt;/a&gt;&lt;/div&gt;</strong>
&lt;/div&gt;</pre>
This markup implements the language toggle's appearance when English is the displayed
language. In other words, the toggle provides a link allowing the user to select the
Czech (i.e., '<code>ÄŤesky</code>') option. The link is used to send a request for
<code>chooseLanguage</code>, and creates a query string (<code>?language=cs</code>) that
specifies the requested language code.
<br><br>
<p class="notes"><strong>Note:</strong> Recall that in Unit 5, <a href="page-views-controller.html#controller">Preparing
the Page Views and Controller Servlet</a>, you set the <code>ControllerServlet</code>
to handle the <code>/chooseLanguage</code> URL pattern.</p>
<p class="tips">Snapshot 8 includes the <a href="http://jquery.com/" target="_blank">jQuery</a>
JavaScript library and takes advantage of various UI effects to enhance the appearance
and behavior of the website. Aside from a
<a href="http://plugins.jquery.com/project/validate" target="_blank">jQuery plugin
for client-side validation</a> (discussed in the <a href="transaction.html#client">previous
tutorial unit</a>), the snapshot implements an easing effect for category headings in
the welcome page, as well as for category buttons in the category page. Configuration
is included in <code>header.jspf</code> of the project snapshot. Rounded corners are
implemented using CSS3's <a href="http://www.w3.org/TR/css3-background/#corners"
target="_blank">border-radius</a> property (applied in <code>affablebean.css</code>).</p></li>
<li>Run the project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) to see what the toggle looks like in the browser.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/language-toggle.png"
class="margin-around b-all" alt="Language toggle in browser"
title="Run the project to view the language toggle">
<br>
Currently, the language toggle appears as in the above image regardless of what language
the page displays in. In the next step, you integrate JSTL logic into the toggle so that
it renders according to the language displayed on the page.</li>
<li id="step4">Modify the toggle implementation as follows.
<pre class="examplecode">
&lt;div class=&quot;headerWidget&quot;&gt;
&lt;%-- language selection widget --%&gt;
<strong>&lt;c:choose&gt;
&lt;c:when test=&quot;${pageContext.request.locale.language ne 'cs'}&quot;&gt;
english
&lt;/c:when&gt;
&lt;c:otherwise&gt;
&lt;c:url var=&quot;url&quot; value=&quot;chooseLanguage&quot;&gt;
&lt;c:param name=&quot;language&quot; value=&quot;en&quot;/&gt;
&lt;/c:url&gt;
&lt;div class=&quot;bubble&quot;&gt;&lt;a href=&quot;${url}&quot;&gt;english&lt;/a&gt;&lt;/div&gt;
&lt;/c:otherwise&gt;
&lt;/c:choose&gt; |
&lt;c:choose&gt;
&lt;c:when test=&quot;${pageContext.request.locale.language eq 'cs'}&quot;&gt;
ÄŤesky
&lt;/c:when&gt;
&lt;c:otherwise&gt;
&lt;c:url var=&quot;url&quot; value=&quot;chooseLanguage&quot;&gt;
&lt;c:param name=&quot;language&quot; value=&quot;cs&quot;/&gt;
&lt;/c:url&gt;
&lt;div class=&quot;bubble&quot;&gt;&lt;a href=&quot;${url}&quot;&gt;česky&lt;/a&gt;&lt;/div&gt;
&lt;/c:otherwise&gt;
&lt;/c:choose&gt;</strong>
&lt;/div&gt;</pre>
In the above implementation, you rely on conditional tags from JSTL's <code>core</code>
tag library to display the left and right portions of the toggle according to the language
used by the request locale. What is the &quot;language used by the request locale&quot;?
When a request is made, the browser passes a list of preferred locales in the <code>Accept-Language</code>
HTTP header. The Java runtime environment on the server reads the list and determines
the best match based on the locales defined by the application's resource bundles. This
match is then recorded in the <code>ServletRequest</code> object, and can be accessed
using the <code>getLocale</code> method. For example, you could access the preferred
locale from a servlet with the following statement.
<pre class="examplecode">request.getLocale();</pre>
<p class="tips">You can use the IDE's HTTP Monitor (Window &gt; Debugging &gt; HTTP
Server Monitor) to examine HTTP headers for client requests. In order to use the
HTTP Monitor, you need to first activate it for the server you are using. Unit 8,
<a href="#manage-sessions">Managing Sessions</a> provides a demonstration
under the sub-section, <a href="manage-sessions.html#http-monitor">Examining
Client-Server Communication with the HTTP Monitor</a>.</p>
<p>To determine the language of the preferred locale, you use the <code>Locale</code>
class' <code>getLanguage</code> method. Again, from a servlet you could access the
language of the client request's preferred locale with the following.</p>
<pre class="examplecode">request.getLocale().getLanguage();</pre>
<p>Returning to the code you just added to the <code>header.jspf</code> fragment,
you utilize the <code>pageContext.request</code> implicit object to access the
<code>ServletRequest</code> for the given client request. Using dot notation, you
then proceed to call the same methods as you would from a servlet. In the above
example, accessing the &quot;language used by the request locale&quot; is as simple
as:</p>
<pre class="examplecode">${pageContext.request.locale.language}</pre>
<p class="notes"><strong>Note:</strong> The above implementation uses <code>&lt;c:url&gt;</code>
tags to set up the toggle link. This is done in order to properly encode the request
URL in the event that URL rewriting is used as a means for session tracking. Unit 8,
<a href="manage-sessions.html#encodeUrl">Managing Sessions</a> provides a brief
explanation of how the <code>&lt;c:url&gt;</code> tags can be used.</p></li>
<li>Add a basic language test to the <code>header.jspf</code> file. This will enable us to
check whether the toggle is properly rendering according to the client request's preferred
language. Enter the following after the page's <code>&lt;body&gt;</code> tag.
<pre class="examplecode">
&lt;body&gt;
<strong>&lt;%-- Language test --%&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&lt;strong&gt;tests:&lt;/strong&gt;
&lt;br&gt;
&lt;code&gt;\${pageContext.request.locale.language}&lt;/code&gt;: ${pageContext.request.locale.language}
&lt;/p&gt;</strong>
&lt;div id=&quot;main&quot;&gt;</pre></li>
<li>Ensure that you have set Czech as your browser's preferred language. (If you are
following this tutorial unit sequentially, you've already done this. If not, refer
to the steps outlined above in <a href="#test">Test Supported Languages</a>.)</li>
<li>Run the project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) and examine the application welcome page in the browser.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/language-test.png"
class="margin-around b-all" style="width:688px" alt="Language test and welcome page displayed in browser"
title="Language toggle displays according to request's preferred language">
<br>
If your browser's preferred language is set to Czech, you can note the following:
<ul style="margin: 5px 0 0 -1em">
<li>The test that we introduced in the previous step indicates that '<code>cs</code>'
is the preferred language.</li>
<li>Czech text is displayed in the page.</li>
<li>The language toggle provides a link enabling the user to select English.</li>
</ul>
</li>
</ol>
<h3 id="handleRequest">Implement Functionality to Handle a Request from the Language Toggle</h3>
<p>Now that the toggle is in place and it appears according to the language displayed
in the page, let's continue by adding code to the <code>ControllerServlet</code>
that handles the request sent when a user clicks the link in the language toggle.</p>
<p>As indicated in the current language toggle implementation from <a href="#step4">step 4</a>
above, the requested URL with query string looks as follows:</p>
<ul style="margin: 5px 0 0 -1em">
<li><strong>English:</strong> <code>chooseLanguage?language=en</code></li>
<li><strong>Czech:</strong> <code>chooseLanguage?language=cs</code></li>
</ul>
<p>Our goal is to register the language choice, and then display both the page view and
language toggle based on the chosen language. We can accomplish this by extracting
the <code>language</code> parameter from the query string and creating a session-scoped
<code>language</code> attribute that remembers the language selected by the user. Then
we'll return to the <code>header.jspf</code> fragment and apply the
<a href="http://download-llnw.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/fmt/setLocale.html" target="_blank"><code>&lt;fmt:setLocale&gt;</code></a>
tag to set the page language based on the user's choice. With the <code>&lt;fmt:setLocale&gt;</code>
tag we can manually switch the language used in the page display. We'll also modify
the language toggle so that if the <code>language</code> attribute has been set, the
toggle's appearance is determined according to the <code>language</code> attribute's
value.</p>
<ol>
<li>Open the <code>ControllerServlet</code> in the editor. Use the Go To File dialog
- press Alt-Shift-O (Ctrl-Shift-O on Mac), then type '<code>controller</code>' and
click OK. In the opened file, locate the portion of the <code>doGet</code> method
that handles the <code>chooseLanguage</code> request (line 126).</li>
<li>Delete the <code>// TODO: Implement language request</code> comment and enter code
to extract the <code>language</code> parameter from the request query string.
<pre class="examplecode">
// if user switches language
} else if (userPath.equals(&quot;/chooseLanguage&quot;)) {
<strong>// get language choice
String language = request.getParameter(&quot;language&quot;);</strong>
}</pre></li>
<li>Place the <code>language</code> parameter in the request scope. Add the following.
<pre class="examplecode">
// if user switches language
} else if (userPath.equals(&quot;/chooseLanguage&quot;)) {
// get language choice
String language = request.getParameter(&quot;language&quot;);
<strong>// place in request scope
request.setAttribute(&quot;language&quot;, language);</strong>
}</pre></li>
<li>As a temporary measure, have the application forward the response to the
<code>index.jsp</code> welcome page when the language toggle link is clicked.
Add the following code.
<pre class="examplecode">
// if user switches language
} else if (userPath.equals("/chooseLanguage")) {
// get language choice
String language = request.getParameter("language");
// place in request scope
request.setAttribute("language", language);
<strong>// forward request to welcome page
try {
request.getRequestDispatcher("/index.jsp").forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}
return;</strong>
}</pre>
Naturally, forwarding the user to the welcome page regardless of what page
he or she is on is not an ideal way to handle the language toggle's behavior.
We'll return to this matter in the next sub-section, <a href="#keepTrack">Enable
the Application to Keep Track of the Originating Page View</a>. For the meantime
however, this will allow us to examine the results of the current language
toggle implementation when running the project.</li>
<li>Switch to the <code>header.jspf</code> fragment (If the file is already opened
in the editor, press Ctrl-Tab and choose the file.) and apply the
<a href="http://download-llnw.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/fmt/setLocale.html" target="_blank"><code>&lt;fmt:setLocale&gt;</code></a>
tag to set the page language based on the new <code>language</code> variable.
Add the following.
<pre class="examplecode">
&lt;%@taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot; %&gt;
&lt;%@taglib prefix=&quot;fn&quot; uri=&quot;http://java.sun.com/jsp/jstl/functions&quot; %&gt;
<strong>&lt;%@taglib prefix=&quot;fmt&quot; uri=&quot;http://java.sun.com/jsp/jstl/fmt&quot; %&gt;
&lt;%-- Set language based on user's choice --%&gt;
&lt;c:if test=&quot;${!empty language}&quot;&gt;
&lt;fmt:setLocale value=&quot;${language}&quot; scope=&quot;session&quot; /&gt;
&lt;/c:if&gt;</strong>
&lt;%@page contentType=&quot;text/html; charset=UTF-8&quot; pageEncoding=&quot;UTF-8&quot;%&gt;
&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;
&quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;</pre>
Since the <code>language</code> variable is only created when the user clicks the
link in the language toggle, you perform a test using
<a href="http://download-llnw.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/c/if.html" target="_blank"><code>&lt;c:if&gt;</code></a>
tags to determine whether the variable exists before attempting to set the language.
When applying the <code>&lt;fmt:setLocale&gt;</code> tag, you set its scope to
<code>session</code> as you want the user-selected language to take precedence
for the remainder of his or her session on the website. Also, since this is the
first time the <code>fmt</code> library is used in the header, you declare the tag
library.
<br><br>
<p class="tips">You can read the EL expression <code>${!empty language}</code> as,
&quot;False if the <code>language</code> variable is null or an empty string.&quot;
See the
<a href="http://download-llnw.oracle.com/javaee/5/tutorial/doc/bnahq.html#bnaim" target="_blank">Java
EE 5 Tutorial: Examples of EL Expressions</a> for other available examples.</p></li>
<li>Modify the language toggle implementation so that if a value has been set by the
<code>&lt;fmt:setLocale&gt;</code> tag, the toggle displays according to the language
specified by that value. (You can determine this value using the
<code>${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session']}</code> expression.)
<br><br>
Enclose the current implementation within <code>&lt;c:choose&gt;</code> tags, and
create logic similar to the current implementation in the event that the locale has
been manually set. (Changes are displayed in <strong>bold</strong>.)
<pre class="examplecode">
&lt;div class=&quot;headerWidget&quot;&gt;
&lt;%-- language selection widget --%&gt;
<strong>&lt;c:choose&gt;
&lt;%-- When user hasn't explicitly set language,
render toggle according to browser's preferred locale --%&gt;
&lt;c:when test=&quot;${empty sessionScope['javax.servlet.jsp.jstl.fmt.locale.session']}&quot;&gt;</strong>
&lt;c:choose&gt;
&lt;c:when test=&quot;${pageContext.request.locale.language ne 'cs'}&quot;&gt;
english
&lt;/c:when&gt;
&lt;c:otherwise&gt;
&lt;c:url var=&quot;url&quot; value=&quot;chooseLanguage&quot;&gt;
&lt;c:param name=&quot;language&quot; value=&quot;en&quot;/&gt;
&lt;/c:url&gt;
&lt;div class=&quot;bubble&quot;&gt;&lt;a href=&quot;${url}&quot;&gt;english&lt;/a&gt;&lt;/div&gt;
&lt;/c:otherwise&gt;
&lt;/c:choose&gt; |
&lt;c:choose&gt;
&lt;c:when test=&quot;${pageContext.request.locale.language eq 'cs'}&quot;&gt;
ÄŤesky
&lt;/c:when&gt;
&lt;c:otherwise&gt;
&lt;c:url var=&quot;url&quot; value=&quot;chooseLanguage&quot;&gt;
&lt;c:param name=&quot;language&quot; value=&quot;cs&quot;/&gt;
&lt;/c:url&gt;
&lt;div class=&quot;bubble&quot;&gt;&lt;a href=&quot;${url}&quot;&gt;česky&lt;/a&gt;&lt;/div&gt;
&lt;/c:otherwise&gt;
&lt;/c:choose&gt;
<strong>&lt;/c:when&gt;
&lt;%-- Otherwise, render widget according to the set locale --%&gt;
&lt;c:otherwise&gt;
&lt;c:choose&gt;
&lt;c:when test=&quot;${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session'] ne 'cs'}&quot;&gt;
english
&lt;/c:when&gt;
&lt;c:otherwise&gt;
&lt;c:url var=&quot;url&quot; value=&quot;chooseLanguage&quot;&gt;
&lt;c:param name=&quot;language&quot; value=&quot;en&quot;/&gt;
&lt;/c:url&gt;
&lt;div class=&quot;bubble&quot;&gt;&lt;a href=&quot;${url}&quot;&gt;english&lt;/a&gt;&lt;/div&gt;
&lt;/c:otherwise&gt;
&lt;/c:choose&gt; |
&lt;c:choose&gt;
&lt;c:when test=&quot;${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session'] eq 'cs'}&quot;&gt;
ÄŤesky
&lt;/c:when&gt;
&lt;c:otherwise&gt;
&lt;c:url var=&quot;url&quot; value=&quot;chooseLanguage&quot;&gt;
&lt;c:param name=&quot;language&quot; value=&quot;cs&quot;/&gt;
&lt;/c:url&gt;
&lt;div class=&quot;bubble&quot;&gt;&lt;a href=&quot;${url}&quot;&gt;česky&lt;/a&gt;&lt;/div&gt;
&lt;/c:otherwise&gt;
&lt;/c:choose&gt;
&lt;/c:otherwise&gt;
&lt;/c:choose&gt;</strong>
&lt;/div&gt;</pre></li>
<li>Before examining the project in a browser, add another test that displays the
value set by the <code>&lt;fmt:setLocale&gt;</code> tag. Add the following code
beneath the test you created earlier.
<pre class="examplecode">
&lt;p style=&quot;text-align: left;&quot;&gt;&lt;strong&gt;tests:&lt;/strong&gt;
&lt;br&gt;
&lt;code&gt;\${pageContext.request.locale.language}&lt;/code&gt;: ${pageContext.request.locale.language}
<strong>&lt;br&gt;
&lt;code&gt;\${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session']}&lt;/code&gt;: ${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session']}</strong>
&lt;/p&gt;</pre>
<p class="tips"><code>javax.servlet.jsp.jstl.fmt.locale.session</code> is the <em>string
literal</em> key for the <code>Locale</code> set by the <code>&lt;fmt:setLocale&gt;</code>
tag. You can verify this by clicking in the editor's left margin to set a breakpoint (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/breakpoint-badge.png"
alt="Breakpoint badge"> ) on the new test, then running the debugger (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/debug-project-btn.png"
alt="Debug Project button"> ) on the project. When you click the toggle link to change
languages in the browser, examine the Variables window (Alt-Shift-1; Ctrl-Shift-1 on
Mac) when the debugger suspends on the breakpoint.
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/language/variables-window.png"
rel="lytebox" title="Run debugger and view variable and expression values in the Variables window"
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/variables-window.png"
class="margin-around b-all" style="width:654px" alt="Variables window"
title="Click to enlarge"></a>
<br>
EL expressions presented in this tutorial primarily use dot (<code>.</code>) notation. The
format depicted in the expression above is known as <em>bracket</em> (<code>[]</code>) notation
whereby you enter the string literal key within quotes in order to extract the object's value:
<div style="margin:-10px 0 0 43px">
<pre class="examplecode" style="width:637px">${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session']}</pre>
</div>
<p style="margin-left:34px">Numerous EL resolver classes exist for the purpose of resolving expressions.
For example, when the above expression is encountered at runtime, the
<a href="http://download-llnw.oracle.com/javaee/6/api/javax/servlet/jsp/el/ImplicitObjectELResolver.html" target="_blank"><code>ImplicitObjectResolver</code></a>
first returns a <code>Map</code> that maps session-scoped attribute names to their values. (In the
above image of the Variables window, you can verify that session attributes are maintained in a
<a href="http://download-llnw.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentHashMap.html" target="_blank"><code>ConcurrentHashMap</code></a>.)
In order to resolve the remainder of the expression, the
<a href="http://download-llnw.oracle.com/javaee/6/api/javax/el/MapELResolver.html" target="_blank"><code>MapELResolver</code></a>
is used to get the value of the key named '<code>javax.servlet.jsp.jstl.fmt.locale.session</code>'.
<br><br>
For more information, refer to the Java EE 5 Tutorial:
<a href="http://download-llnw.oracle.com/javaee/5/tutorial/doc/bnahq.html#bnaif" target="_blank">Unified
Expression Language: Resolving Expressions</a>.</li>
<li>Run the project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) and examine the application welcome page in the browser.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/toggle-page1.png"
class="margin-around b-all" style="width:688px" alt="Welcome page displayed in browser"
title="Welcome page displays according to browser's preferred language">
<br>
In the above image, the server identifies Czech (<code>cs</code>) as the browser's preferred
language from the <code>Accept-Language</code> HTTP header. This is indicated from the first
test. The page displays in Czech, and the language toggle enables the user to choose English.
The second test remains blank as the <code>&lt;fmt:setLocale&gt;</code> tag has not yet been
called.</li>
<li>Click the toggle link for English.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/toggle-page2.png"
class="margin-around b-all" style="width:688px" alt="Welcome page displayed in browser"
title="Welcome page displays in English, according to toggle selection">
<br>
When clicking the toggle link, the default Czech language is overridden by means of the
<code>&lt;fmt:setLocale&gt;</code> tag implemented in the <code>header.jspf</code> file.
Although the browser's preferred language remains Czech, you see that the page now displays
according to the new language made available by the language toggle.</li>
<li>Click the toggle link for Czech.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/toggle-page3.png"
class="margin-around b-all" style="width:688px" alt="Welcome page displayed in browser"
title="Welcome page displays in Czech, according to toggle selection">
<br>
Changing the language back to the browser's preferred language works as expected, however
note that the deciding factor is no longer the language detected from the <code>Accept-Language</code>
HTTP header, but is the language specified from the <code>&lt;fmt:setLocale&gt;</code> tag.</li>
<li>Before continuing, remove the tests you added to the <code>header.jspf</code> file.
(Deleted code in <strong><strike>strike-through</strike></strong> text.)
<pre class="examplecode">
&lt;body&gt;
<strong><strike>&lt;%-- Language tests --%&gt;</strike>
<strike>&lt;p style=&quot;text-align: left;&quot;&gt;&lt;strong&gt;tests:&lt;/strong&gt;</strike>
<strike>&lt;br&gt;</strike>
<strike>&lt;code&gt;\${pageContext.request.locale.language}&lt;/code&gt;: ${pageContext.request.locale.language}</strike>
<strike>&lt;br&gt;</strike>
<strike>&lt;code&gt;\${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session']}&lt;/code&gt;: ${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session']}</strike>
<strike>&lt;/p&gt;</strike></strong>
&lt;div id=&quot;main&quot;&gt;</pre></li>
</ol>
<h3 id="keepTrack">Enable the Application to Keep Track of the Originating Page View</h3>
<p>One of the <a href="#impDeets">implementation details</a> which you have agreed on with
the Affable Bean staff is that when the language toggle is used to change the language,
the user remains in the same page view. In our current implementation, the welcome page
is returned whenever the language toggle is clicked. A more user-friendly approach would
be to provide the application with a means of tracking the request page view, and forwarding
the request to that page view when the language toggle link is clicked.</p>
<p>We can accomplish this by setting a session-scoped <code>view</code> attribute within each
of the page views, then referencing this attribute in the <code>ControllerServlet</code>
in order to determine where to forward the request. There are however several caveats
to consider when dealing with the language toggle in the confirmation page. These are
discussed and dealt with in steps 7-11 below.</p>
<p>Begin this exercise with <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot9.zip">snapshot
9</a> of the <code>AffableBean</code> project. This snapshot includes completed English
and Czech resource bundles for all page views, all page views have been modified to use
text from the resource bundles, and the language toggle is presented in a state corresponding
to this point in the tutorial.</p>
<ol>
<li>Open <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot9.zip">snapshot
9</a> in the IDE. Click the Open Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/open-project-btn.png"
alt="Open Project button"> ) button and use the wizard to navigate to the location
on your computer where you downloaded the project.</li>
<li>Click the Run Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) button to run the project. When navigating through the site,
note that when you click the language toggle from any of the page views, you are returned
to the application's welcome page.
<br><br>
<p class="alert">If you receive an error when running the project, revisit the
<a href="#setup">setup instructions</a>, which describe how to prepare the
database and establish connectivity between the IDE, GlassFish, and MySQL.</p></li>
<li>Use <a href="http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/jstl/1.1/docs/tlddocs/c/set.html" target="_blank"><code>&lt;c:set&gt;</code></a>
tags to set a session-scoped <code>view</code> attribute for each of the page views.
Open each of the page views in the editor and add the following code to the top of
each file.
<h4>index.jsp</h4>
<pre class="examplecode">
&lt;%-- Set session-scoped variable to track the view user is coming from.
This is used by the language mechanism in the Controller so that
users view the same page when switching between English and Czech. --%&gt;
&lt;c:set var='view' value='/index' scope='session' /&gt;</pre>
<h4>category.jsp</h4>
<pre class="examplecode">
&lt;%-- Set session-scoped variable to track the view user is coming from.
This is used by the language mechanism in the Controller so that
users view the same page when switching between English and Czech. --%&gt;
&lt;c:set var='view' value='/category' scope='session' /&gt;</pre>
<h4>cart.jsp</h4>
<pre class="examplecode">
&lt;%-- Set session-scoped variable to track the view user is coming from.
This is used by the language mechanism in the Controller so that
users view the same page when switching between English and Czech. --%&gt;
&lt;c:set var='view' value='/cart' scope='session' /&gt;</pre>
<h4>checkout.jsp</h4>
<pre class="examplecode">
&lt;%-- Set session-scoped variable to track the view user is coming from.
This is used by the language mechanism in the Controller so that
users view the same page when switching between English and Czech. --%&gt;
&lt;c:set var='view' value='/checkout' scope='session' /&gt;</pre>
Based on customer-agreed <a href="#impDeets">implementation details</a>, we
do not need to provide a means of switching languages on the confirmation page
view. From a usability perspective, a user will have already selected his or
her preferred language prior to checkout. From an implementation perspective,
recall that we destroy the user session upon a successfully completed order.
(Refer back to the final paragraph in <a href="#manage-sessions">Managing
Sessions</a>, which describes how to apply the <code>invalidate</code> method
to explicitly terminate a user session.) If the Affable Bean staff were to insist
on allowing customers to view their orders bilingually, you would need to consider
the following scenarios, dependent on whether you destroy the user session
upon displaying the confirmation page:
<ol style="margin: 5px 0 0 0em; list-style-type:lower-alpha">
<li><strong>Session destroyed:</strong> Would be necessary to take
extra measures to ensure that a <code>chooseLanguage</code> request
from the confirmation page refers to the appropriate order, and can
display customer-sensitive details in a secure fashion.</li>
<li><strong>Session maintained:</strong> Would risk enabling users
to mistakenly place double orders on their shopping cart. Also, by
not terminating user sessions when they are no longer needed, an
unnecessary load may be placed on the server.</li>
</ol></li>
<li>Open the <code>ControllerServlet</code> in the editor. (If already opened,
press Ctrl-Tab and choose the file.) In the opened file, locate the portion
of the <code>doGet</code> method that handles the <code>chooseLanguage</code>
request (line 126).
<br><br>
Note that currently <code>chooseLanguage</code> requests are forwarded to
the <code>index.jsp</code> welcome page.
<pre class="examplecode">
// if user switches language
} else if (userPath.equals(&quot;/chooseLanguage&quot;)) {
// get language choice
String language = request.getParameter(&quot;language&quot;);
// place in session scope
session.setAttribute(&quot;language&quot;, language);
<strong>// forward request to welcome page
try {
request.getRequestDispatcher(&quot;/index.jsp&quot;).forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}
return;</strong>
}</pre></li>
<li>Use the <code>view</code> session attribute to forward the request back
to the originating page view. Make the following changes (in <strong>bold</strong>).
<pre class="examplecode">
// if user switches language
} else if (userPath.equals(&quot;/chooseLanguage&quot;)) {
// get language choice
String language = request.getParameter(&quot;language&quot;);
// place in request scope
request.setAttribute(&quot;language&quot;, language);
<strong>String userView = (String) session.getAttribute(&quot;view&quot;);
if ((userView != null) &&
(!userView.equals(&quot;/index&quot;))) { // index.jsp exists outside 'view' folder
// so must be forwarded separately
userPath = userView;
} else {
// if previous view is index or cannot be determined, send user to welcome page</strong>
try {
request.getRequestDispatcher(&quot;/index.jsp&quot;).forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}
return;
<strong>}</strong>
}</pre>
In the above implementation, you extract the value of the <code>view</code> attribute
and, provided that the view:
<ul style="margin: 5px 0 0 -1em">
<li>can be identified (i.e., the value is not null),</li>
<li>does not originate from the welcome page (<code>index.jsp</code> does not
reside in the same location as other page views, and therefore cannot be
resolved using the <code>doGet</code> method's way of forwarding requests)</li>
</ul>
<span class="indent">...you set it to the <code>doGet</code> method's <code>userPath</code>
variable, and forward the request using the method's existing <code>RequestDispatcher</code>:</span>
<pre class="examplecode">
// use RequestDispatcher to forward request internally
String url = &quot;/WEB-INF/view&quot; + userPath + &quot;.jsp&quot;;
try {
request.getRequestDispatcher(url).forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}</pre></li>
<li>Run the project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) to test it in the browser. When you navigate to the
category, cart or checkout pages, switch languages using the language toggle.
When you do so, you now remain within the same page view.</li>
<li>In the browser, complete an order so that the application forwards you to the
confirmation page. When you click the language toggle from the confirmation page,
note that you are sent back to the website's welcome page.
<br><br>
Implementation-wise, you may consider this to be sufficient. However, the Affable
Bean staff have explicitly asked you to remove the language toggle from this page
view. One way to accomplish this is to perform a test to determine whether the request
<em>servlet path</em> contains '<code>/confirmation</code>'.
<br><br>
Switch to the <code>header.jspf</code> file in the editor and surround the language
toggle with the following test. You can use JSTL's functions (i.e.,
<a href="http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/jstl/1.1/docs/tlddocs/fn/tld-summary.html" target="_blank"><code>fn</code></a>)
library to perform string operations.
<pre class="examplecode">
&lt;div class=&quot;headerWidget&quot;&gt;
<strong>&lt;%-- If servlet path contains '/confirmation', do not display language toggle --%&gt;
&lt;c:if test=&quot;${!fn:contains(pageContext.request.servletPath,'/confirmation')}&quot;&gt;</strong>
&lt;%-- language selection widget --%&gt;
&lt;c:choose&gt;
...
&lt;/c:choose&gt;
<strong>&lt;/c:if&gt;</strong>
&lt;/div&gt;</pre>
Examine the above code snippet and note the following points:
<ul style="margin: 5px 0 0 -1em">
<li>The servlet path can be accessed from the <code>HttpServletRequest</code>
using the <a href="http://download.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#getServletPath%28%29" target="_blank"><code>getServletPath</code></a>
method. Because we use a <code>RequestDispatcher</code> to forward the request
to the confirmation page (<code>ControllerServlet</code>, line 158), the servlet
path becomes:
<pre class="examplecode" style="width: 651px">/WEB-INF/view/confirmation.jsp</pre></li>
<li>Using the <code>pageContext.request.servletPath</code> EL expression is
comparable to calling <code>request.getServletPath()</code> from a servlet.</li>
<li>The <a href="http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/jstl/1.1/docs/tlddocs/fn/contains.fn.html" target="_blank"><code>fn:contains()</code></a>
function allows you to test if an input string contains the specified substring.</li>
<li>The <code>fn</code> tag library has already been declared for you at the top of
in the <code>header.jspf</code> file in snapshot 9:
<pre class="examplecode" style="width: 651px">&lt;%@taglib prefix=&quot;fn&quot; uri=&quot;http://java.sun.com/jsp/jstl/functions&quot; %&gt;</pre></li>
</ul></li>
<li>Run the project again and step through to the confirmation page. Note that the page
no longer displays the language toggle.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/language/confirmation-page.png"
class="margin-around b-all" style="width:688px" alt="Confirmation page displayed in browser"
title="Language toggle no longer displays in confirmation page"></li>
<li>In the browser, step through to the confirmation page but switch languages once along the
way using the language toggle. Note that when you complete an order, the confirmation page
inadvertently switches back to the originally displayed language. You may rightly identify
the cause: upon a successfully completed order, the <code>ControllerServlet</code> destroys
the user session and consequently the session-scoped locale that was set using the
<code>&lt;fmt:setLocale&gt;</code> tag is also lost.
<br><br>
To remedy this, open the <code>ControllerServlet</code> and locate the <code>invalidate()</code>
method which is used to destroy user sessions (approximately line 259).
<br><br>
<p class="tips">Use the editor's quick search facility: press Ctrl-F (&#8984;-F on Mac)
and type in '<code>invalidate</code>'.</p></li>
<li>Add code that extracts the session-scoped locale value prior to destroying the user session
and resets the request-scoped <code>language</code> attribute to the locale value after the
session has been destroyed. (Changes in <strong>bold</strong>.)
<pre class="examplecode">
// if order processed successfully send user to confirmation page
if (orderId != 0) {
<strong>// in case language was set using toggle, get language choice before destroying session
Locale locale = (Locale) session.getAttribute(&quot;javax.servlet.jsp.jstl.fmt.locale.session&quot;);
String language = &quot;&quot;;
if (locale != null) {
language = (String) locale.getLanguage();
}</strong>
// dissociate shopping cart from session
cart = null;
// end session
session.invalidate();
<strong>if (!language.isEmpty()) { // if user changed language using the toggle,
// reset the language attribute - otherwise
request.setAttribute(&quot;language&quot;, language); // language will be switched on confirmation page!
}</strong>
// get order details
Map orderMap = orderManager.getOrderDetails(orderId);
...
userPath = &quot;/confirmation&quot;;
}</pre></li>
<li>Run the project and again, step through to the confirmation page but switch languages
once along the way using the language toggle. Note that when you complete an order,
the confirmation page now displays in the language you selected.</li>
</ol>
</div>
<p>You have now successfully integrated language support into the <code>AffableBean</code>
application according to customer specification. You've factored out all text from page views,
placed it into resource bundles, and have applied JSTL's <code>fmt</code> tag library to
use resource bundle content based on the user's preferred language. You also implemented
a language toggle that enables users to switch between English and Czech, and override their
browser's default language choice. Download and examine
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot10.zip">snapshot
10</a> to compare your work with the state of the project at the end of this tutorial unit.</p>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans E-commerce Tutorial - Adding Language Support">Send
Us Your Feedback</a></div>
<br style="clear:both;">
<br>
<h2 id="seeAlsoLanguage">See Also</h2>
<div class="indent">
<h3>NetBeans Resources</h3>
<ul>
<li><a href="../javaee-intro.html" target="_blank">Introduction to Java EE Technology</a></li>
<li><a href="../javaee-gettingstarted.html" target="_blank">Getting Started with Java EE Applications</a></li>
<li><a href="https://netbeans.org/projects/www/downloads/download/shortcuts.pdf">Keyboard Shortcuts & Code Templates Card</a></li>
<li><a href="../../../trails/java-ee.html" target="_blank">Java EE & Java Web Learning Trail</a></li>
</ul>
<h3>External Resources</h3>
<ul>
<li><a href="http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/i18n/index.html" target="_blank">The Java Tutorials: Internationalization</a></li>
<li><a href="http://download.oracle.com/docs/cd/E17477_01/javaee/5/tutorial/doc/bnaxu.html" target="_blank">Java EE 5 Tutorial: Internationalizing and Localizing Web Applications</a></li>
<li><a href="http://java.sun.com/developer/technicalArticles/Intl/MultilingualJSP/index.html" target="_blank">Developing Multilingual Web Applications Using JavaServer Pages Technology</a></li>
<li><a href="http://java.sun.com/developer/technicalArticles/J2SE/locale/" target="_blank">Internationalization: Understanding Locale in the Java Platform</a></li>
<li><a href="http://java.sun.com/developer/technicalArticles/Intl/ResourceBundles/" target="_blank">Java Internationalization: Localization with ResourceBundles</a></li>
<li><a href="http://www.ibm.com/developerworks/java/library/j-jstl0415/" target="_blank">A JSTL primer, Part 3: Presentation is everything</a></li>
<li><a href="http://java.sun.com/javase/technologies/core/basic/intl/" target="_blank">Java Internationalization</a> [Technology Homepage]</li>
<li><a href="http://en.wikipedia.org/wiki/Internationalization_and_localization" target="_blank">Internationalization and localization</a> [Wikipedia]</li>
<li><a href="http://www.loc.gov/standards/iso639-2/php/code_list.php" target="_blank">ISO 639-2 Language Code List</a> [Library of Congress]</li>
<li><a href="http://www.w3.org/International/articlelist#language" target="_blank">W3C Internationalization Activity: Articles, best practices & tutorials: Language</a></li>
<li><a href="http://jquery.com/" target="_blank">jQuery</a></li>
</ul>
</div>
<br><br><br><br>
<h1 id="security">The NetBeans E-commerce Tutorial - Securing the Application</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Tutorial Contents</h4>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#design">Designing the Application</a></li>
<li><a href="#setup-dev-environ">Setting up the Development Environment</a></li>
<li><a href="#data-model">Designing the Data Model</a></li>
<li><a href="#page-views-controller">Preparing the Page Views and Controller Servlet</a></li>
<li><a href="#connect-db">Connecting the Application to the Database</a></li>
<li><a href="#entity-session">Adding Entity Classes and Session Beans</a></li>
<li><a href="#manage-sessions">Managing Sessions</a></li>
<li><a href="#transaction">Integrating Transactional Business Logic</a></li>
<li><a href="#language">Adding Language Support</a></li>
<li><strong>Securing the Application</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#examineSnapshot">Examining the Project Snapshot</a></li>
<li><a href="#formBased">Setting up Form-Based Authentication</a></li>
<li><a href="#usersGroups">Creating Users, Groups and Roles</a></li>
<li><a href="#secureTransport">Configuring Secure Data Transport</a></li>
<li><a href="#seeAlsoSecurity">See Also</a></li>
</ul></li>
<li><a href="#test-profile">Testing and Profiling</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ol>
</div>
</div>
<p><img src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" class="stamp"
alt="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"
title="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"></p>
<p>This tutorial unit focuses on web application security. When securing web applications,
there are two primary concerns that need to be addressed:</p>
<ol style="margin: 0 0 0 325px">
<li>Preventing unauthorized users from gaining access to protected content.</li>
<li>Preventing protected content from being read while it is being transmitted.</li>
</ol>
<p>The first concern, <em>access control</em>, is typically a two-step process that
involves (1) determining whether a user is who he or she claims to be (i.e.,
<em>authentication</em>), and then (2) either granting or denying the user
access to the requested resource (i.e., <em>authorization</em>). A simple and
common way to implement access control for web applications is with a login
form that enables the server to compare user credentials with a pre-existing list
of authenticated users.</p>
<p>The second concern, protecting data while it is in transit, typically involves
using Transport Layer Security (TLS), or its predecessor, Secure Sockets Layer
(SSL), in order to encrypt any data communicated between the client and server.</p>
<p>Upon reviewing the Affable Bean staff's <a href="design.html#requirements">list of
requirements</a>, we'll need to secure the application in the following ways:</p>
<ul style="margin-left: 320px">
<li>Set up a login form for the administration console that enables staff
members access to the console's services, and blocks unauthorized users.</li>
<li>Configure secure data transport for both the customer checkout process, and
for any data transmitted to and from the administration console.</li>
</ul>
<p>In order to implement the above, we'll take advantage of NetBeans' visual editor
for the <code>web.xml</code> deployment descriptor. We'll also work in the
GlassFish Administration Console to configure a &quot;user group&quot; that
corresponds to Affable Bean staff members, and verify SSL support.</p>
<p>You can view a live demo of the application that you build in this tutorial:
<a href="http://services.netbeans.org/AffableBean/" target="_blank">NetBeans
E-commerce Tutorial Demo Application</a>.</p>
<br style="clear:left;">
<br>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html" target="_blank">NetBeans IDE</a></td>
<td class="tbltd1">Java bundle, 6.8 or 6.9</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank">Java Development Kit (JDK)</a></td>
<td class="tbltd1">version 6</td>
</tr>
<tr>
<td class="tbltd1"><a href="#glassFishSecurity">GlassFish server</a></td>
<td class="tbltd1">v3 or Open Source Edition 3.0.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://dev.mysql.com/downloads/mysql/" target="_blank">MySQL database server</a></td>
<td class="tbltd1">version 5.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot10.zip">AffableBean
project</a></td>
<td class="tbltd1">snapshot 10</td>
</tr>
</tbody>
</table>
<p><strong class="notes">Notes:</strong></p>
<ul>
<li>The NetBeans IDE requires the Java Development Kit (JDK) to run properly.
If you do not have any of the resources listed above, the JDK should be
the first item that you download and install.</li>
<li>The NetBeans IDE Java Bundle includes Java Web and EE technologies, which are
required for the application you build in this tutorial.</li>
<li id="glassFishSecurity">The NetBeans IDE Java Bundle also includes the GlassFish server,
which you require for this tutorial. You could
<a href="http://glassfish.dev.java.net/public/downloadsindex.html" target="_blank">download
the GlassFish server independently</a>, but the version provided with the
NetBeans download has the added benefit of being automatically registered with
the IDE.</li>
<li>You can follow this tutorial unit without having completed previous units. To
do so, see the <a href="#setup">setup instructions</a>, which describe how
to prepare the database and establish connectivity between the IDE, GlassFish,
and MySQL.</li>
<li>Java EE security is an expansive topic that spans well beyond the scope of this
tutorial unit. In order to fully appreciate the range of implementation options
that are available to you, refer to the <a href="http://download.oracle.com/javaee/6/tutorial/doc/gijrp.html"
target="_blank">Java EE 6 Tutorial, Part VII: Security</a>. This unit provides
ample references to relevant sub-sections within the Java EE Tutorial.</li>
</ul>
<br>
<h2 id="examineSnapshot">Examining the Project Snapshot</h2>
<p>The beginning state of the snapshot helps to illustrate the need for security
in the application.</p>
<ol style="margin-top:0">
<li>Open the <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot10.zip">project
snapshot</a> for this tutorial unit in the IDE. Click the Open Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/open-project-btn.png"
alt="Open Project button"> ) button and use the wizard to navigate to the location
on your computer where you downloaded the project.</li>
<li>Run the project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) to ensure that it is properly configured with your database
and application server.
<br><br>
<p class="alert">If you receive an error when running the project, revisit the
<a href="#setup">setup instructions</a>, which describe how to prepare the
database and establish connectivity between the IDE, GlassFish, and MySQL.</p></li>
<li>Test the application's functionality in your browser. This snapshot provides an
implementation of the administration console, as specified in the
<a href="design.html#requirements">customer requirements</a>. To examine the
administration console, enter the following URL in your browser:
<pre class="examplecode">http://localhost:8080/AffableBean<strong>/admin/</strong></pre>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/admin-console.png"
class="margin-around b-all" style="width:688px" alt="AffableBean administration console displayed in a browser"
title="Append the application's default URL with '/admin' to view the administration console in a browser">
<br>
The administration console enables you to view all customers and orders contained
in the database. When you click either of the links in the left panel, the page will
update to display a table listing customers or orders, depending on your choice. (The
'log out' link currently does not &quot;log out&quot; an authenticated user.)
<br><br>
<p class="notes"><strong>Note:</strong> The customers and orders that you see displayed
in the administration console are dependent on the data stored in your database. You can
create new records by stepping through the checkout process in the website. Alternatively,
you can run the <a href="https://netbeans.org/project_downloads/samples/Samples/JavaEE/ecommerce/affablebean_sample_data.sql">affablebean_sample_data.sql</a>
script on your <code>affablebean</code> database to have your data correspond to the
records displayed in the following screenshots. (If you need help with this task, refer
to step 2 in the <a href="#setup">setup instructions</a>.)</p>
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/admin-console-customers.png"
class="margin-around b-all" style="width:688px" alt="AffableBean administration console displaying all customer records"
title="Click the 'view all customers' link to view all customer records in a table">
<br>
You can view details for each customer record by hovering your mouse and selecting an individual
record.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/customer-selected.png"
class="margin-around b-all" alt="Customer record selected in administration console"
title="Hover your mouse over a customer record and click to view customer details">
<br>
Likewise, you can view an order summary for each customer either by selecting an order from the
administration console's &quot;orders&quot; table, or by clicking the &quot;view order summary&quot;
link in a &quot;customer details&quot; display.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/view-order-summary.png"
class="margin-around" alt="'view order summary' link being hovered over in a 'customer details' view"
title="Click 'view order summary' from a customer details display in order to view a customer's order details">
<br>
Naturally, none of this information should be available to an anonymous site visitor. In the
coming steps, you'll create login and error pages, so that when an unauthenticated user attempts
to access the administration console, he or she will be directed to the login page. Upon successful
login, the user is then redirected to the administration console's menu; upon login failure, the
error page is displayed.</li>
<li id="adminConsole">Examine the project snapshot in the Projects window.
<table>
<tr>
<td>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/projects-window.png"
class="margin-around b-all" alt="Projects window displaying resources for administration console"
title="The AdminServlet forwards requests to resources within the web/admin folder"></td>
<td class="valign-top">
<p style="margin: 20px 0 0 5px">This implementation of the administration console
primarily relies on the following project resources:
<ul style="margin: 5px 0 0 -.7em">
<li>An <strong><code>admin</code></strong> directory within the project's webroot,
which contains all page view files.</li>
<li>An <strong><code>AdminServlet</code></strong>, contained in the <code>controller</code>
package, which forwards requests to page views within the <code>admin</code>
directory.</li>
</ul>
<p style="margin: 20px 0 0 5px">Also, the following files have been modified from the previous snapshot:</p>
<ul style="margin: 10px 0 0 -.7em">
<li><strong><code>WEB-INF/web.xml</code>:</strong> Contains a new <code>&lt;jsp-property-group&gt;</code>
that includes the header and footer fragments for page views contained in the <code>admin</code>
directory.</li>
<li><strong><code>css/affablebean.css</code>:</strong> Includes new style definitions for
elements in the administration console</li>
</ul>
<p style="margin-left:5px">If you have been following the NetBeans E-commerce Tutorial
sequentially, you'll find that there is nothing contained in the implementation for
the administration console which hasn't already been covered in previous units.
Essentially, the <code>AdminServlet</code> processes requests from the <code>admin/index.jsp</code>
page, EJBs and entity classes are employed to retrieve information from the database,
and the information is then forwarded back to the <code>admin/index.jsp</code> page
to be displayed.</p>
</td>
</tr>
</table>
</li>
<li style="margin-top:-10px">In the browser, return to the customer website by clicking the Affable Bean
logo in the upper left corner of the web page. Step through the entire <a href="design.html#business">business
process flow</a> of the application and note that the checkout process is handled over a non-secure channel.
<br><br>
When customers reach the checkout page, they are expected to submit sensitive personal information
in order to complete their orders. Part of your task in this tutorial unit is to ensure that this
data is sent over a secure channel. Because the administration console also enables authenticated
users to view customers' personal information, it too needs to be configured so that data is sent
over the Internet securely.</li>
</ol>
<br>
<h2 id="formBased">Setting up Form-Based Authentication</h2>
<p>In this section, you set up <em>form-based authentication</em> for the <code>AffableBean</code>
administration console. Form-based authentication enables the server to authenticate users based
on the credentials they enter into a login form. With these credentials, the server is able to
make a decision on whether to grant the user access to protected resources. In order to implement
this, you'll create login and error pages, and will rely on <em>declarative security</em> by
entering security settings in the application's <code>web.xml</code> deployment descriptor.</p>
<p>Before you begin implementing a form-based authentication mechanism for the <code>AffableBean</code>
application, the following background information is provided to help clarify the security terms
relevant to our scenario.</p>
<ul>
<li><a href="#declarativeSecurity">Declarative and Programmatic Security</a></li>
<li><a href="#authenticationMech">Choosing an Authentication Mechanism</a></li>
</ul>
<div class="indent">
<h3 id="declarativeSecurity">Declarative and Programmatic Security</h3>
<p>With <em>declarative security</em>, you specify all security settings for your
application, including authentication requirements, access control, and security
roles, using annotations and/or deployment descriptors. In other words, the security
for your application is in a form that is external to the application, and relies
on the mechanisms provided by the Java EE container for its management.</p>
<p>With <em>programmatic security</em>, your classes, entities, servlets, and page views
manage security themselves. In this case, security logic is integrated directly
into your application, and is used to handle authentication and authorization, and
ensure that data is sent over a secure network protocol when necessary.</p>
<p>For the <code>AffableBean</code> application, we'll use declarative security by
declaring all security information in the <code>web.xml</code> deployment descriptor.</p>
<p class="tips">For more information on declarative and programmatic security types,
see the <a href="http://download.oracle.com/javaee/6/tutorial/doc/bncat.html"
target="_blank">Java EE 6 Tutorial: Overview of Web Application Security</a>.</p>
<h3 id="authenticationMech">Choosing an Authentication Mechanism</h3>
<p>An <em>authentication mechanism</em> is used to determine how a user gains access to
restricted content. The Java EE platform supports various authentication mechanisms,
such as <em>HTTP basic authentication</em>, <em>form-based authentication</em>, and
<em>client authentication</em>. The authentication mechanism behind our login form
will be <em>form-based authentication</em>. You'll learn what form-based authentication
is when you begin <a href="#loginForm">setting up the login form</a> for the
<code>AffableBean</code> administration console below.</p>
<p class="tips">See the Java EE 6 Tutorial:
<a href="http://download.oracle.com/javaee/6/tutorial/doc/gkbaa.html#gkbsa"
target="_blank">Specifying Authentication Mechanisms</a> for further information.</p>
</div>
<br>
<p>Form-based authentication has the advantage of enabling the developer to design the
appearance of the login form so that it better suits the application which it belongs to.
Our implementation for the form-based authentication mechanism can be divided into two
steps. Begin by creating page views for the required login form and error message. Then
add entries to the <code>web.xml</code> deployment descriptor to inform the servlet
container that the application requires form-based authentication for access to the
resources that comprise the administration console.</p>
<ol style="margin: 0 0 0 -.7em">
<li><a href="#createPages">Create Pages for Login and Login Failure</a></li>
<li><a href="#addSecurity">Add Security Entries to the Deployment Descriptor</a></li>
</ol>
<div class="indent">
<h3 id="createPages">Create Pages for Login and Login Failure</h3>
<p>In form-based authentication, the process of authentication and authorization is
shown in the following four steps:</p>
<ol style="margin: 0 0 0 -.7em">
<li>The client sends a request to the server for a protected resource.</li>
<li>The server recognizes that a protected resource has been requested, and returns
the login page to the client.</li>
<li>The client sends username and password credentials using the provided form.</li>
<li>The server processes the credentials, and if an authorized user is identified
the protected resource is returned, otherwise the error page is returned.</li>
</ol>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/form-based-authentication.png"
class="margin-around"
alt="Diagram depicting process flow of form-based authentication"
title="Authentication and authorization take place in a four-step process using form-based authentication">
<p class="tips">For more information on form-based authentication, see the Java EE 6 Tutorial:
<a href="http://download.oracle.com/javaee/6/tutorial/doc/gkbaa.html#bncbq" target="_blank">Form-Based
Authentication</a>.</p>
<br>
<p id="template">The <code>j_security_check</code> keyword represents the destination in
the servlet container that handles authentication and authorization. When implementing
the HTML login form, you apply it as the value for the form's <code>action</code> attribute.
You also apply the &quot;<code>j_username</code>&quot; and &quot;<code>j_password</code>&quot;
keywords, as in the following template:</p>
<pre class="examplecode">
&lt;form action=&quot;<strong>j_security_check</strong>&quot; method=post&gt;
&lt;p&gt;username: &lt;input type=&quot;text&quot; name=&quot;<strong>j_username</strong>&quot;&gt;&lt;/p&gt;
&lt;p&gt;password: &lt;input type=&quot;password&quot; name=&quot;<strong>j_password</strong>&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;submit&quot;&gt;&lt;/p&gt;
&lt;/form&gt;</pre>
<br>
<p>Perform the following steps.</p>
<ol style="margin-top: 0">
<li>In the Projects window, right-click the <code>admin</code> folder node and choose New &gt; JSP.</li>
<li>Name the file <code>login</code>, then click Finish. The new <code>login.jsp</code> file is created
and opens in the editor.</li>
<li>Repeat the previous two steps to create a new <code>error.jsp</code> file. In the New JSP wizard,
name the file <code>error</code>. When you finish, you'll have two new files listed in the Projects
window.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/projects-window-jsp.png"
class="margin-around b-all" alt="New login and error JSP files displayed in Projects window"
title="New JSP file nodes displayed in Projects window"></li>
<li>Open the project's web deployment descriptor. Press Alt-Shift-O (Ctrl-Shift-O on Mac)
and in the Go to File dialog, type '<code>web</code>', then click OK.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/go-to-file.png"
class="margin-around b-all" alt="Go to File dialog"
title="Use the Go to File dialog to quickly open files in the editor"></li>
<li>In the editor, scroll to the bottom of the <code>web.xml</code> file and note the
<code>&lt;jsp-property-group&gt;</code> entry created for JSP pages in the administration
console. Add the new login and error JSP pages as <code>&lt;url-pattern&gt;</code>
entries. (Changes in <strong>bold</strong>.)
<pre class="examplecode">
&lt;jsp-property-group&gt;
&lt;description&gt;JSP configuration for the admin console&lt;/description&gt;
&lt;url-pattern&gt;/admin/index.jsp&lt;/url-pattern&gt;
<strong>&lt;url-pattern&gt;/admin/login.jsp&lt;/url-pattern&gt;
&lt;url-pattern&gt;/admin/error.jsp&lt;/url-pattern&gt;</strong>
&lt;include-prelude&gt;/admin/jspf/header.jspf&lt;/include-prelude&gt;
&lt;include-coda&gt;/admin/jspf/footer.jspf&lt;/include-coda&gt;
&lt;/jsp-property-group&gt;</pre>
This step ensures that when these two pages are returned to a client, they
will be prepended and appended with the defined <code>header.jspf</code> and
<code>footer.jspf</code> fragments, respectively.
<br><br>
<p class="tips">You can equally configure the <code>&lt;jsp-property-group&gt;</code>
entry from the <code>web.xml</code>'s visual editor. Click the Pages tab along
the top of the editor, and enter the URL patterns into the respective JSP
Property Group.</p></li>
<li>Press Ctrl-Tab to switch to the <code>login.jsp</code> file in the editor.
Delete the entire template contents for the file, then enter the following
HTML form.
<pre class="examplecode">
&lt;form action=&quot;<strong>j_security_check</strong>&quot; method=post&gt;
&lt;div id=&quot;loginBox&quot;&gt;
&lt;p&gt;&lt;strong&gt;username:&lt;/strong&gt;
&lt;input type=&quot;text&quot; size=&quot;20&quot; name=&quot;<strong>j_username</strong>&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;password:&lt;/strong&gt;
&lt;input type=&quot;password&quot; size=&quot;20&quot; name=&quot;<strong>j_password</strong>&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;submit&quot;&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/form&gt;</pre>
Note that the HTML form is based on the <a href="#template">template provided above</a>.
Here, you use the &quot;<code>j_security_check</code>&quot; keyword as the value for the
form's <code>action</code> attribute, and the &quot;<code>j_username</code>&quot; and
&quot;<code>j_password</code>&quot; keywords as the values for the <code>name</code>
attribute of the username and password text fields. The style of the form is implemented
by encapsulating the form widgets within a <code>&lt;div&gt;</code> element, then defining
a set of rules for the <code>loginBox</code> ID in <code>affablebean.css</code>.</li>
<li>Press Ctrl-Tab and switch to the <code>error.jsp</code> file in the editor. Delete the
entire template contents for the file, then enter the following.
<pre class="examplecode">
&lt;div id=&quot;loginBox&quot;&gt;
&lt;p class=&quot;error&quot;&gt;Invalid username or password.&lt;/p&gt;
&lt;p&gt;Return to &lt;strong&gt;&lt;a href=&quot;login.jsp&quot;&gt;admin login&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;</pre>
The above content includes a simple message indicating that login has failed, and
provides a link that allows the user to return to the login form.</li>
</ol>
<h3 id="addSecurity">Add Security Entries to the Deployment Descriptor</h3>
<p>In order to instruct the servlet container that form-based authentication is to be
used, you add entries to the <code>web.xml</code> deployment descriptor. This is
essentially a three-step process, which can be followed by specifying settings under
the three headings in the <code>web.xml</code> file's Security tab. These are: (1)
Login Configuration, (2) Security Roles, and (3) Security Constraints.</p>
<ol>
<li>Open the project's <code>web.xml</code> file in the editor. (If it is already opened,
you can press Ctrl-Tab and select it.)</li>
<li>Click the Security tab along the top of the editor. The IDE's visual editor enables
you to specify security settings under the Security tab.</li>
<li>Expand the Login Configuration heading, select Form, then enter the following
details:
<ul style="margin: 10px 0 0 -.7em">
<li><strong>Form Login Page:</strong> <code>/admin/login.jsp</code></li>
<li><strong>Form Error Page:</strong> <code>/admin/error.jsp</code></li>
<li><strong>Realm Name:</strong> <code>file</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/login-configuration.png"
class="margin-around b-all" style="width:688px"
alt="Visual editor for web.xml - Security tab"
title="Specify security settings for the application using the IDE's web.xml visual editor"></li>
<li>Click the XML tab along the top of the editor and verify the changes made to
the deployment descriptor. The following entry has been added to the bottom of
the file:
<pre class="examplecode">
&lt;login-config&gt;
&lt;auth-method&gt;FORM&lt;/auth-method&gt;
&lt;realm-name&gt;file&lt;/realm-name&gt;
&lt;form-login-config&gt;
&lt;form-login-page&gt;/admin/login.jsp&lt;/form-login-page&gt;
&lt;form-error-page&gt;/admin/error.jsp&lt;/form-error-page&gt;
&lt;/form-login-config&gt;
&lt;/login-config&gt;</pre>
This entry informs the servlet container that form-based authentication is used,
the realm named <code>file</code> should be checked for user credentials, and specifies
the whereabouts of the login and error pages.</li>
<li id="securityRole">Click the Security tab again, then expand the Security Roles heading
and click Add.</li>
<li>In the Add Security Role dialog, type in <code>affableBeanAdmin</code> for the role
name, then click OK. The new role entry is added beneath Security Roles.</li>
<li>Click the XML tab to examine how the file has been affected. Note that the following
entry has been added:
<pre class="examplecode">
&lt;security-role&gt;
&lt;description/&gt;
&lt;role-name&gt;affableBeanAdmin&lt;/role-name&gt;
&lt;/security-role&gt;</pre>
Here we've specified the name of a security role used with the application. We'll
need to associate this role with the protected resources that define the administration
console (under the Security Constraints heading below), and later we'll
<a href="#defineRoles">create this role on the GlassFish server</a>.</li>
<li>Click the Security tab again, then click the Add Security Constraint button.</li>
<li>Type in <code>Admin</code> for the Display Name, then under Web Resource Collection
click the Add button. Enter the following details, then when you are finished, click OK.
<ul style="margin: 10px 0 0 -.7em">
<li><strong>Resource Name:</strong> <code>Affable Bean Administration</code></li>
<li><strong>URL Pattern(s):</strong> <code>/admin/*</code></li>
<li><strong>HTTP Method(s):</strong> <code>All HTTP Methods</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/add-web-resource.png"
class="margin-around b-all" alt="Add Web Resource dialog"
title="Specify which resources need to be protected using the Add Web Resource dialog"></li>
<li id="enableAuthConstraint">Under the new Admin security constraint, select the Enable
Authentication Constraint option and click the Edit button next to the Role Name(s)
text field.</li>
<li>In the dialog that displays, select the <code>affableBeanAdmin</code> role in the
left column, then click Add. The role is moved to the right column.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/edit-role-names.png"
class="margin-around b-all" alt="Edit Role Names dialog"
title="Specify roles to be associated with an authentication constraint"></li>
<li>Click OK. The role is added to the Role Name(s) text field.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/security-tab.png"
class="margin-around b-all" style="width:688px" alt="Visual editor for web.xml - Security tab"
title="Security constraints include specifying the web resource collection, and role(s) that are granted access to the collection"></li>
<li>Click the XML tab to examine how the file has been affected. Note that the following
entry has been added:
<pre class="examplecode">
&lt;security-constraint&gt;
&lt;display-name&gt;Admin&lt;/display-name&gt;
&lt;web-resource-collection&gt;
&lt;web-resource-name&gt;Affable Bean Administration&lt;/web-resource-name&gt;
&lt;description/&gt;
&lt;url-pattern&gt;/admin/*&lt;/url-pattern&gt;
&lt;/web-resource-collection&gt;
&lt;auth-constraint&gt;
&lt;description/&gt;
&lt;role-name&gt;affableBeanAdmin&lt;/role-name&gt;
&lt;/auth-constraint&gt;
&lt;/security-constraint&gt;</pre>
In these previous six steps, you've created a security constraint that specifies which
resources need to be protected, and identifies the role(s) that are granted access to them.
Since the administration console implementation is essentially everything contained
within the application's <code>admin</code> folder, you use a wildcard (<code>*</code>).
Although you've specified that all HTTP methods should be protected, you could have
equally selected just GET and POST, since these are the only two that are handled by
the <code>AdminServlet</code>. As previously mentioned, the <code>affableBeanAdmin</code>
role that we declared still needs to be created on the GlassFish server.</li>
<li>Run the project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) to examine how the application now handles access to the
administration console.</li>
<li>When the application opens in the browser, attempt to access the administration console
by entering the following URL into the browser's address bar:
<pre class="examplecode">http://localhost:8080/AffableBean<strong>/admin/</strong></pre>
When you attempt to access the administration console, the login page is now presented.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/login-form.png"
class="margin-around b-all" style="width:688px" alt="Browser display of login page"
title="Unauthenticated attempts to access the administration console are redirected to the login page"></li>
<li>Click the 'submit' button to attempt login. You see the error page displayed.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/error-page.png"
class="margin-around b-all" style="width:688px" alt="Browser display of error page"
title="Error page is displayed when the server is unable to authenticate a user">
</li>
</ol>
</div>
<br>
<h2 id="usersGroups">Setting up Users, Groups and Roles</h2>
<p>Much of our security implementation is dependent on configuration between the application
and the GlassFish server we are using. This involves setting up <em>users</em>, <em>groups</em>,
and <em>roles</em> between the two, and using one of the preconfigured security policy
domains, or <em>realms</em>, on the server. Start by reading some background information
relevant to our scenario, then proceed by configuring users, groups and roles between
the application and the GlassFish server.</p>
<ul>
<li><a href="#understandUsers">Understanding Users, Groups, and Roles</a></li>
<li><a href="#understandRealms">Understanding Realms on the GlassFish Server</a></li>
</ul>
<div class="indent">
<h3 id="understandUsers">Understanding Users, Groups, and Roles</h3>
<p>A <em>user</em> is a unique identity recognized by the server. You define users on the
server so that it can be able to determine who should have access to protected resources.
You can optionally cluster users together into a <em>group</em>, which can be understood
as a set of authenticated users. In order to specify which users and/or groups have access
to protected resources, you create <em>roles</em>. As stated in the Java EE 6 Tutorial,</p>
<blockquote style="margin-top: 0">
<em>A role is an abstract name for the permission to access a particular set of resources
in an application. A role can be compared to a key that can open a lock. Many people
might have a copy of the key. The lock doesn’t care who you are, only that you have
the right key.</em>
</blockquote>
<p>The role that a user or group is assigned to is what specifically allows the server to
determine whether protected resources can be accessed. Users and groups can be assigned
to multiple roles. As will be demonstrated below, you accomplish this by defining the
role in the application, then mapping it to users and groups on the server. </p>
<p>The relationship between users, groups, and roles, and the process in which you establish
them in the application and on the server, is presented in the following diagram.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/groups-users-roles.png"
id="usersRolesGroupsDiagram" class="margin-around"
alt="Diagram depicting relationship of users, groups and roles between the application and server"
title="Users, groups, and roles need to be set up and mapped between the application and server">
<p class="tips">For more information on groups, users, and roles, see
<a href="http://download.oracle.com/javaee/6/tutorial/doc/bnbxj.html" target="_blank">Working
with Realms, Users, Groups, and Roles</a> in the Java EE 6 Tutorial.</p>
<h3 id="understandRealms">Understanding Realms on the GlassFish Server</h3>
<p>When you define users and groups on the server, you do so by entering details into
a security policy domain, otherwise known as a <em>realm</em>. A realm protects user
credentials (e.g., user names and passwords) through an authentication scheme. For
example, user credentials can be stored in a local text file, or maintained in a
certificate database.</p>
<p>The GlassFish server provides three preconfigured realms by default. These are the
<code>file</code>, <code>admin-realm</code>, and <code>certificate</code> realms.
Briefly, the <code>file</code> realm stores user credentials in a local text file
named <code>keyfile</code>. The <code>admin-realm</code> also stores credentials
in a local text file, and is reserved for server administrator users. The
<code>certificate</code> realm, the server stores user credentials in a certificate
database.</p>
<p>When defining users, groups and roles for the <code>AffableBean</code> administration
console, we'll use the server's preconfigured <code>file</code> realm.</p>
</div>
<br>
<p>In order to set up users, groups and roles to satisfy the form-based authentication
mechanism we've created, perform the following three steps corresponding to the
<a href="#usersRolesGroupsDiagram">diagram above</a>.</p>
<ol style="margin: 0 0 0 -.7em">
<li><a href="#createUsers">Create Users and/or Groups on the Server</a></li>
<li><a href="#defineRoles">Define Roles in the Application</a></li>
<li><a href="#mapApplication">Map Roles to Users and/or Groups</a></li>
</ol>
<div class="indent">
<h3 id="createUsers">Create Users and/or Groups on the Server</h3>
<p>In this step, we'll use the GlassFish Administration Console to create a user named
<code>nbuser</code> within the preexisting <code>file</code> security realm. We'll
also assign the new <code>nbuser</code> to a <em>group</em> that we'll create called
<code>affableBeanAdmin</code>.</p>
<ol>
<li>Open the Services window (Ctrl-5; &#8984;-5 on Mac) and expand the Servers node
so that the GlassFish server node is visible.</li>
<li>Ensure that the GlassFish server is running. If the server is running, a small green
arrow is displayed next to the GlassFish icon (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/gf-server-running-node.png"
alt="GlassFish server node in Services window"> ). If you need to start it, right-click
the server node and choose Start.</li>
<li>Right-click the GlassFish server node and choose View Admin Console. The login form
for the GlassFish Administration Console opens in a browser.</li>
<li>Log into the Administration Console by typing <code>admin</code> / <code>adminadmin</code>
for the username / password.</li>
<li>In the Tree which displays in the left column of the Administration Console, expand
the Configuration &gt; Security &gt; Realms nodes, then click the <code>file</code> realm.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/file-realm.png"
class="margin-around b-all" alt="Tree displayed in GlassFish Administration Console"
title="Expand the Configuration > Security > Realms nodes to view existing security realms"></li>
<li>In the main panel of the GlassFish Administration Console, under Edit Realm, click
the Manage Users button.</li>
<li>Under File Users, click the New button.</li>
<li>Under New File Realm User, enter the following details:
<ul style="margin: 10px 0 0 -.7em">
<li><strong>User ID:</strong> <code>nbuser</code></li>
<li><strong>Group List:</strong> <code>affableBeanAdmin</code></li>
<li><strong>New Password:</strong> <code>secret</code></li>
<li><strong>Confirm New Password:</strong> <code>secret</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/new-file-realm-user.png"
class="margin-around b-all" alt="New File Realm User panel in GlassFish Administration Console"
title="Enter new user and group details in the New File Realm User panel">
<br>
Here, we are creating a user for the <code>file</code> security realm, which
we've randomly named <code>nbuser</code>. We have also assigned the new user
to a randomly named <code>affableBeanAdmin</code> group. Remember the <code>secret</code>
password you set, as you will require it to later log into the <code>AffableBean</code>
administration console.</li>
<li>Click OK. The new <code>nbuser</code> user is now listed under File Users in the
GlassFish Administration Console.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/nbuser-file-realm.png"
class="margin-around b-all" alt="File Users panel displaying newly created user and group"
title="All users and groups pertaining to the 'file' realm are displayed under File Users">
<br>
Optionally close the browser window for the GlassFish Administration Console, or
leave it open for the time being. You will need to return to the Administration Console
in the <a href="#mapApplication">Map Roles to Users and/or Groups</a> step below.
</li>
</ol>
<h3 id="defineRoles">Define Roles in the Application</h3>
<p>By &quot;defining roles in the application,&quot; you specify which roles have access
to EJB session beans, servlets, and/or specific methods that they contain. You can accomplish this
declaratively by creating entries in the deployment descriptor, or using annotations.
For the <code>AffableBean</code> administration console, we've actually already
completed this step when we <a href="#enableAuthConstraint">added the <code>affableBeanAdmin</code>
role to the security constraint</a> that we created when implementing form-based
authentication. However, in more complicated scenarios you may have multiple roles,
each with varying degrees of access. In such cases, implementation requires a more
fine-grained access control.</p>
<p>The Java EE 6 API includes various security annotations that you can use in place of the
XML entries you add to deployment descriptors. The availability of annotations primarily
aims to offer ease of development and flexibility when coding. One common method is to use
annotations within classes, but override them when necessary using deployment descriptors.</p>
<ul>
<li><a href="#secureServlet">Using Security Annotations in Servlets</a></li>
<li><a href="#secureEJB">Using Security Annotations in EJBs</a></li>
</ul>
<h4 id="secureServlet">Using Security Annotations in Servlets</h4>
<p>The following table lists some of the annotations available to you when applying roles
to servlets.</p>
<div class="indent">
<table style="width:722px">
<tbody>
<tr>
<th class="tblheader" colspan="3">Servlet 3.0 Security Annotations (specified in <a href="http://www.jcp.org/en/jsr/detail?id=315" target="_blank">JSR 315</a>)</th>
</tr>
<tr>
<td class="tbltd1"><code><a href="http://download.oracle.com/javaee/6/api/javax/servlet/annotation/ServletSecurity.html" target="_blank">@ServletSecurity</a></code></td>
<td class="tbltd1">Used to specify security constraints to be enforced by a Servlet container on HTTP protocol messages.</td>
</tr>
<tr>
<td class="tbltd1"><code><a href="http://download.oracle.com/javaee/6/api/javax/servlet/annotation/HttpConstraint.html" target="_blank">@HttpConstraint</a></code></td>
<td class="tbltd1">Used within the <code>ServletSecurity</code> annotation to represent the security constraints to be applied to all HTTP protocol methods.</td>
</tr>
</tbody>
</table>
</div>
<br>
<p>If we wanted to apply the Servlet 3.0 annotations to declare the <code>affableBeanAdmin</code> role
on the <code>AdminServlet</code>, we could do so as follows. (Changes in <strong>bold</strong>.)</p>
<div class="indent">
<pre class="examplecode" style="margin-top:0; width:700px">
@WebServlet(name = &quot;AdminServlet&quot;,
urlPatterns = {&quot;/admin/&quot;,
&quot;/admin/viewOrders&quot;,
&quot;/admin/viewCustomers&quot;,
&quot;/admin/customerRecord&quot;,
&quot;/admin/orderRecord&quot;,
&quot;/admin/logout&quot;})
<strong>@ServletSecurity( @HttpConstraint(rolesAllowed = {&quot;affableBeanAdmin&quot;}) )</strong>
public class AdminServlet extends HttpServlet { ... }</pre></div>
<p>In this case, we could then remove the corresponding entry in the <code>web.xml</code>
deployment descriptor. (Removed content displayed as <strike><strong>strike-through</strong></strike> text.)</p>
<div class="indent">
<pre class="examplecode" style="margin-top:0; width:700px">
&lt;login-config&gt;
&lt;auth-method&gt;FORM&lt;/auth-method&gt;
&lt;realm-name&gt;file&lt;/realm-name&gt;
&lt;form-login-config&gt;
&lt;form-login-page&gt;/admin/login.jsp&lt;/form-login-page&gt;
&lt;form-error-page&gt;/admin/error.jsp&lt;/form-error-page&gt;
&lt;/form-login-config&gt;
&lt;/login-config&gt;
<strike><strong>&lt;security-constraint&gt;</strong></strike>
<strike><strong>&lt;display-name&gt;Admin&lt;/display-name&gt;</strong></strike>
<strike><strong>&lt;web-resource-collection&gt;</strong></strike>
<strike><strong>&lt;web-resource-name&gt;Affable Bean Administration&lt;/web-resource-name&gt;</strong></strike>
<strike><strong>&lt;description/&gt;</strong></strike>
<strike><strong>&lt;url-pattern&gt;/admin/*&lt;/url-pattern&gt;</strong></strike>
<strike><strong>&lt;/web-resource-collection&gt;</strong></strike>
<strike><strong>&lt;auth-constraint&gt;</strong></strike>
<strike><strong>&lt;description/&gt;</strong></strike>
<strike><strong>&lt;role-name&gt;affableBeanAdmin&lt;/role-name&gt;</strong></strike>
<strike><strong>&lt;/auth-constraint&gt;</strong></strike>
<strike><strong>&lt;/security-constraint&gt;</strong></strike>
<strike><strong>&lt;security-role&gt;</strong></strike>
<strike><strong>&lt;description/&gt;</strong></strike>
<strike><strong>&lt;role-name&gt;affableBeanAdmin&lt;/role-name&gt;</strong></strike>
<strike><strong>&lt;/security-role&gt;</strong></strike></pre></div>
<h4 id="secureEJB">Using Security Annotations in EJBs</h4>
<p>The following table lists some of the annotations available to you when applying roles to EJBs.</p>
<div class="indent">
<table style="width:722px">
<tbody>
<tr>
<th class="tblheader" colspan="3">EJB Security Annotations (specified in <a href="http://www.jcp.org/en/jsr/detail?id=250" target="_blank">JSR 250</a>)</th>
</tr>
<tr>
<td class="tbltd1"><code><a href="http://download.oracle.com/javaee/6/api/javax/annotation/security/DeclareRoles.html" target="_blank">@DeclareRoles</a></code></td>
<td class="tbltd1">Used by application to declare roles. It can be specified on a class.</td>
</tr>
<tr>
<td class="tbltd1"><code><a href="http://download.oracle.com/javaee/6/api/javax/annotation/security/RolesAllowed.html" target="_blank">@RolesAllowed</a></code></td>
<td class="tbltd1">Specifies the list of roles permitted to access method(s) in an application.</td>
</tr>
</tbody>
</table>
</div>
<br>
<p>To demonstrate the use of EJB security annotations, we'll apply the <code>@RolesAllowed</code>
annotation to a method that should only be called when a user has been identified as belonging
to the <code>affableBeanAdmin</code> role.</p>
<ol>
<li>Reexamine the <a href="#adminConsole">snapshot implementation for the <code>AffableBean</code>
administration console</a>. Note that in the <code>CustomerOrderFacade</code> session bean,
a new <code>findByCustomer</code> method enables the <code>AdminServlet</code> to access a
specified <code>Customer</code>.</li>
<li>Open the <code>CustomerOrderFacade</code> bean in the editor, then add the <code>@RolesAllowed</code>
annotation to the <code>findByCustomer</code> method.
<pre class="examplecode" style="width:680px">
<strong>@RolesAllowed(&quot;affableBeanAdmin&quot;)</strong>
public CustomerOrder findByCustomer(Object customer) { ... }</pre></li>
<li>Press Ctrl-Shift-I (&#8984;-Shift-I on Mac) to fix imports. An import statement
for <code>javax.annotation.security.RolesAllowed</code> is added to the top of
the class.
<br><br>
The <code>findByCustomer</code> method is only called by the <code>AdminServlet</code>,
which is previously authenticated into the <code>affableBeanAdmin</code> role using
our implementation of form-based authentication. The use of the <code>@RolesAllowed</code>
annotation here is not strictly necessary - its application simply guarantees that the
method can only be called by a user who has been authenticated in the <code>affableBeanAdmin</code>
role.</li>
</ol>
<h3 id="mapApplication">Map Roles to Users and/or Groups</h3>
<p>We have so far accomplished the following:</p>
<ul>
<li>Defined the <code>affableBeanAdmin</code> role for our form-based authentication
mechanism (either in the <code>web.xml</code> deployment descriptor, or as an
annotation in the <code>AdminServlet</code>).</li>
<li>Created a user named <code>nbuser</code> on the GlassFish server, and associated
it with a group named <code>affableBeanAdmin</code>.</li>
</ul>
<p>It is no coincidence that the group and role names are the same. While it is not
necessary that these names be identical, this makes sense if we are only creating
one-to-one matching between roles and groups. In more complicated scenarios, you
can map users and groups to multiple roles providing access to different resources.
In such cases, you would give unique names to groups and roles.</p>
<p>In order to map the <code>affableBeanAdmin</code> role to the <code>affableBeanAdmin</code>
group, you have a choice of performing one of two actions. You can either create a
<code>&lt;security-role-mapping&gt;</code> entry in GlassFish' <code>sun-web.xml</code>
deployment descriptor. (In the Projects window, <code>sun-web.xml</code> is located
within the project's Configuration Files). This would look as follows:</p>
<div class="indent">
<pre class="examplecode" style="margin-top:0; width:700px">
&lt;security-role-mapping&gt;
&lt;role-name&gt;affableBeanAdmin&lt;/role-name&gt;
&lt;group-name&gt;affableBeanAdmin&lt;/group-name&gt;
&lt;/security-role-mapping&gt;</pre>
</div>
<p>This action explicitly maps the <code>affableBeanAdmin</code> role to the
<code>affableBeanAdmin</code> group. Otherwise, you can enable GlassFish' Default
Principal To Role Mapping service so that roles are automatically assigned to groups
of the same name.</p>
<p>The following steps demonstrate how to enable the Default Principal To Role Mapping
service in the GlassFish Administration Console.</p>
<ol style="margin-top: 0">
<li>Open the Services window (Ctrl-5; &#8984;-5 on Mac) and expand the Servers node
so that the GlassFish server node is visible.</li>
<li>Ensure that the GlassFish server is running. If the server is running, a small green
arrow is displayed next to the GlassFish icon (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/gf-server-running-node.png"
alt="GlassFish server node in Services window"> ). If you need to start it, right-click
the server node and choose Start.</li>
<li>Right-click the GlassFish server node and choose View Admin Console. The login form
for the GlassFish Administration Console opens in a browser.</li>
<li>Log into the Administration Console by typing <code>admin</code> / <code>adminadmin</code>
for the username / password.</li>
<li>In the Tree which displays in the left column of the Administration Console, expand
the Configuration node, then click the Security node.</li>
<li>In the main panel of the Administration Console, select the Default Principal To Role
Mapping option.
<br>
<a href="../../../../images_www/articles/73/javaee/ecommerce/security/gf-admin-console-security.png" rel="lytebox"
title="With the Default Principal To Role Mapping option enabled, roles and groups of the same name are automatically mapped"
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/gf-admin-console-security.png"
class="margin-around b-all" style="width: 688px" title="Click to enlarge" alt="GlassFish Administration Console - Security panel">
</a>
<br>
<p class="tips">The Java EE 6 Tutorial defines the term <em>principal</em> as, &quot;An
entity that can be authenticated by an authentication protocol in a security service
that is deployed in an enterprise. A principal is identified by using a principal
name and authenticated by using authentication data.&quot; See
<a href="http://download.oracle.com/javaee/6/tutorial/doc/bnbxj.html#bnbxq" target="_blank">Working
with Realms, Users, Groups, and Roles: Some Other Terminology</a> for more information.</p></li>
<li>Click the Save button.
<br><br>
At this stage, you have taken the necessary steps to enable you to log into the
<code>AffableBean</code> administration console using the <code>nbuser</code> /
<code>secret</code> username / password combination that you set earlier.</li>
<li>Run the project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ). When the application opens in the browser, attempt
the access the administration console by entering the following URL into the browser's
address bar:
<pre class="examplecode">http://localhost:8080/AffableBean<strong>/admin/</strong></pre></li>
<li>When the login page displays, enter the username and password you set earlier in the
GlassFish Administration Console (<code>nbuser</code> / <code>secret</code>), then click
'submit'.
<br><br>
Using form-based authentication, the server authenticates the client using the username
and password credentials sent from the form. Because the <code>nbuser</code> belongs to
the <code>affableBeanAdmin</code> group, and that group is associated with the
<code>affableBeanAdmin</code> role, access is granted to the administration console.</li>
<li>Click the 'log out' link provided in the administration console. The <code>nbuser</code>
is logged out of the administration console, and you are returned to the login page.
<br><br>
The <code>AdminServlet</code> handles the '<code>/logout</code>' URL pattern by invalidating
the user session:
<pre class="examplecode">
// if logout is requested
if (userPath.equals(&quot;/admin/logout&quot;)) {
session = request.getSession();
<strong>session.invalidate();</strong> // terminate session
response.sendRedirect(&quot;/AffableBean/admin/&quot;);
return;
}</pre>
Calling <code>invalidate()</code> terminates the user session. As a consequence, the
authenticated user is dissociated from the active session and would need to login in
again in order to access protected resources.</li>
</ol>
</div>
<br>
<h2 id="secureTransport">Configuring Secure Data Transport</h2>
<p>There are two instances in the <code>AffableBean</code> application that require a secure connection
when data is transmitted over the Internet. The first is when a user initiates the checkout process.
On the checkout page, a user must fill in his or her personal details to complete an order. This
sensitive data must be protected while it is sent to the server. The second instance occurs when
a user logs into the administration console, as the console is used to access sensitive data, i.e.,
customer and order details.</p>
<p>Secure data transport is typically implemented using Transport Layer Security (TLS) or Secure Sockets
Layer (SSL). HTTP is applied on top of the TLS/SSL protocol to provide both encrypted communication
and secure identification of the server. The combination of HTTP with TLS or SSL results in an HTTPS
connection, which can readily be identified in a browser's address bar (e.g.,
<code><strong>https</strong>://</code>).</p>
<p>The GlassFish server has a secure (HTTPS) service enabled by default. This service uses a self-signed
digital certificate, which is adequate for development purposes. Your production server however would
require a certificate signed by a trusted third-party Certificate Authority (CA), such as
<a href="http://www.verisign.com" target="_blank">VeriSign</a> or <a href="http://www.thawte.com/"
target="_blank">Thawte</a>.</p>
<p class="tips">You can find the generated certificate in:
<code><em>&lt;gf-install-dir&gt;</em>/glassfish/domains/domain1/config/keystore.jks</code></p>
<p>Begin this section by verifying that GlassFish' HTTPS service is enabled. Then configure the application
so that a secure HTTPS connection is applied to the checkout process and administration console.</p>
<ul>
<li><a href="#verifyHTTPS">Verify HTTPS Support on the Server</a></li>
<li><a href="#configureSecure">Configure Secure Connection in the Application</a></li>
</ul>
<div class="indent">
<h3 id="verifyHTTPS">Verify HTTPS Support on the Server</h3>
<ol>
<li>Open the Services window (Ctrl-5; &#8984;-5 on Mac) and expand the Servers node
so that the GlassFish server node is visible.</li>
<li>Ensure that the GlassFish server is running. If the server is running, a small green
arrow is displayed next to the GlassFish icon (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/gf-server-running-node.png"
alt="GlassFish server node in Services window"> ). If you need to start it, right-click
the server node and choose Start.</li>
<li>Switch to your browser and type the following URL into the browser's address bar:
<pre class="examplecode">https://localhost:8181/</pre>
The browser displays a warning, indicating that the server is presenting you with
a self-signed certificate. In Firefox for example, the warning looks as follows.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/ff-untrusted-connection.png"
class="margin-around b-all" title="Firefox provides warnings for self-signed certificates"
alt="Firefox warning for self-signed certificates"></li>
<li>Enable your browser to accept the self-signed certificate. With Firefox, click the Add
Exception button displayed in the warning. The following pane displays, allowing you to
view the certificate.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/ff-confirm-security-exception.png"
class="margin-around b-all" alt="Firefox window for confirming a security exception"
title="Firefox enables you to view the digital certificate before confirming the security exception">
<br>
Click Confirm Security Exception. A secure connection is established on port 8181, and
your local development server, GlassFish, is then able to display the following page.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/gf-https.png"
class="margin-around b-all" title="GlassFish provides a secure connection by default on port 8181"
alt="Browser welcome message for GlassFish webroot" id="serverWelcomePage">
<br>
<p class="tips">Aside from the HTTPS protocol displayed in the browser's address bar, Firefox
indicates that a secure connection is established with the blue background behind
<code>localhost</code> in the address bar. Also, a lock (
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/firefox-lock-icon.png"
alt="Firefox lock icon"> ) icon displays in the lower right corner of the browser.
You can click the lock icon for secure pages to review certificate details.</p>
The following optional steps demonstrate how you can identify this security support in
the GlassFish Administration Console.</li>
<li>Open the GlassFish Administration Console in the browser. (Either type '<code>http://localhost:4848/</code>'
in your browser, or click the '<code>go to the Administration Console</code>' link in the GlassFish
server's welcome page, as displayed in the <a href="#serverWelcomePage">image above</a>.)</li>
<li>In the Tree which displays in the left column of the Administration Console, expand the
Configuration &gt; Network Config nodes, then click the Network Listeners node.
<br><br>
The main panel displays the three network listeners enabled by default on the GlassFish server.
<code>http-listener-2</code>, which has been configured to listen over port 8181, is the network
listener used for secure connections.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/network-listeners.png"
class="margin-around b-all" alt="Network Listeners panel displayed in GlassFish Administration Console"
title="View all HTTP listeners from the Network Listeners panel">
<br>
<p class="tips">For more information on network listeners, see the Oracle GlassFish Server 3.0.1
Administration Guide:
<a href="http://docs.sun.com/app/docs/doc/821-1751/giuri?l=en&a=view" target="_blank">About
HTTP Network Listeners</a>.</p></li>
<li>Under the Name column, click the link for <code>http-listener-2</code>. In the main panel, note
that the Security checkbox is selected.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/edit-network-listener.png"
class="margin-around b-all" alt="Edit Network Listener panel in GlassFish Administration Console"
title="Security is enabled for the 'http-listener-2' network listener"></li>
<li>Click the SSL tab. Note that TLS is selected. In the lower portion of the SSL panel, you see the
Cipher Suites that are available for the connection. As stated in the Oracle GlassFish Server 3.0.1
Administration Guide, <a href="http://docs.sun.com/app/docs/doc/821-1751/ablnk" target="_blank">Chapter
11: Administering System Security</a>,
<blockquote>
<em>A cipher is a cryptographic algorithm used for encryption or decryption. SSL and TLS
protocols support a variety of ciphers used to authenticate the server and client to
each other, transmit certificates, and establish session keys. Some ciphers are stronger
and more secure than others. Clients and servers can support different cipher suites.
During a secure connection, the client and the server agree to use the strongest cipher
that they both have enabled for communication, so it is usually sufficient to enable
all ciphers.</em>
</blockquote>
At this stage, you have an understanding of how the GlassFish server supports secure connections
out-of-the-box. Naturally, you could set up your own network listener, have it listen on a port
other than 8181, enable SSL 3 instead of TLS (or both), or generate and sign your own digital
certificates using Java's <a href="http://download.oracle.com/javase/6/docs/technotes/tools/solaris/keytool.html"
target="_blank"><code>keytool</code></a> management utility. You can find instructions on how to
accomplish all of these tasks from the following resources:
<ul style="margin: 10px 0 0 -.7em">
<li>The Java EE 6 Tutorial, <a href="http://download.oracle.com/javaee/6/tutorial/doc/bnbxw.html" target="_blank">Establishing a Secure Connection Using SSL</a></li>
<li>Oracle GlassFish Server 3.0.1 Administration Guide, <a href="http://docs.sun.com/app/docs/doc/821-1751/ablnk" target="_blank">Chapter 11: Administering System Security</a></li>
<li>Oracle GlassFish Server 3.0.1 Administration Guide, <a href="http://docs.sun.com/app/docs/doc/821-1751/ablsw" target="_blank">Chapter 16: Administering Internet Connectivity</a></li>
</ul>
</li>
</ol>
<h3 id="configureSecure">Configure Secure Connection in the Application</h3>
<p>This example demonstrates how to specify a secure connection using both XML in the web deployment
descriptor, as well as Servlet 3.0 annotations directly in a servlet. You begin by creating an
<code>&lt;security-constraint&gt;</code> entry in <code>web.xml</code> for the customer checkout
process. Then, to create a secure connection for access to the administration console, you specify
a <code>TransportGuarantee</code> constraint for the <code>@HttpConstraint</code> annotation in
the <code>AdminServlet</code>.</p>
<ol>
<li>Open the project's <code>web.xml</code> file in the editor. (If it is already opened,
you can press Ctrl-Tab and select it.)</li>
<li>Click the Security tab along the top of the editor, then click the Add Security Constraint button.</li>
<li>Type in <code>Checkout</code> for the Display Name, then under Web Resource Collection
click the Add button. Enter the following details, then when you are finished, click OK.
<ul style="margin: 10px 0 0 -.7em">
<li><strong>Resource Name:</strong> <code>Checkout</code></li>
<li><strong>URL Pattern(s):</strong> <code>/checkout</code></li>
<li><strong>HTTP Method(s):</strong> <code>Selected HTTP Methods</code> (<code>GET</code>)</li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/add-web-resource2.png"
class="margin-around b-all" alt="Add Web Resource dialog"
title="Specify which resources need to be protected using the Add Web Resource dialog">
<p class="notes"><strong>Note:</strong> Recall that the <code>/checkout</code> URL pattern is
handled by the <code>ControllerServlet</code>'s <code>doGet</code> method, and forwards the
user to the checkout page.</p></li>
<li>Under the new Checkout security constraint, select the Enable User Data Constraint option,
then in the Transport Guarantee drop-down, select <code>CONFIDENTIAL</code>.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/checkout-security-constraint.png"
class="margin-around b-all" style="width:688px" alt="Checkout security constraint displayed under Security tab"
title="Use the web.xml visual editor to specify security settings for the application">
<p class="tips">When you choose <code>CONFIDENTIAL</code> as a security constraint, you are
instructing the server to encrypt data using TLS/SSL so that it cannot be read while in
transit. For more information, see the Java EE 6 Tutorial,
<a href="http://download.oracle.com/javaee/6/tutorial/doc/gkbaa.html#bncbm"
target="_blank">Specifying a Secure Connection</a>.</p></li>
<li>Click the XML tab along the top of the editor. Note that the following
<code>&lt;security-constraint&gt;</code> entry has been added.
<pre class="examplecode">
&lt;security-constraint&gt;
&lt;display-name&gt;Checkout&lt;/display-name&gt;
&lt;web-resource-collection&gt;
&lt;web-resource-name&gt;Checkout&lt;/web-resource-name&gt;
&lt;url-pattern&gt;/checkout&lt;/url-pattern&gt;
&lt;http-method&gt;GET&lt;/http-method&gt;
&lt;/web-resource-collection&gt;
&lt;user-data-constraint&gt;
&lt;description/&gt;
&lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;
&lt;/user-data-constraint&gt;
&lt;/security-constraint&gt;</pre>
Configuration for the customer checkout process is now complete. To ensure that a
secure connection is applied for access to the administration console, simply specify
that any requests handled by the <code>AdminServlet</code> are transmitted over a
secure channel.</li>
<li>Open the <code>AdminServlet</code>. Press Alt-Shift-O (Ctrl-Shift-O on Mac)
and in the Go to File dialog, type '<code>admin</code>', then click OK.</li>
<li>Use the <a href="http://download.oracle.com/javaee/6/api/javax/servlet/annotation/HttpConstraint.html"
target="_blank"><code>@HttpConstraint</code></a> annotation's <code>transportGuarantee</code>
element to specify a <code>CONFIDENTIAL</code> security constraint. Make the following
change (in <strong>bold</strong>).
<pre class="examplecode">
@WebServlet(name = &quot;AdminServlet&quot;,
urlPatterns = {&quot;/admin/&quot;,
&quot;/admin/viewOrders&quot;,
&quot;/admin/viewCustomers&quot;,
&quot;/admin/customerRecord&quot;,
&quot;/admin/orderRecord&quot;,
&quot;/admin/logout&quot;})
@ServletSecurity(
@HttpConstraint(<strong>transportGuarantee = TransportGuarantee.CONFIDENTIAL,</strong>
rolesAllowed = {&quot;affableBeanAdmin&quot;})
)
public class AdminServlet extends HttpServlet { ... }</pre></li>
<li>Press Ctrl-Shift-I (&#8984;-Shift-I on Mac) to fix imports. An import statement
for <code>javax.servlet.annotation.ServletSecurity.TransportGuarantee</code> is
added to the top of the class.</li>
<li>Run the project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) to examine the application's behavior in a browser.</li>
<li>In the browser, step through the <code>AffableBean</code> website by selecting
a product category and adding several items to your shopping cart. Then click the
'proceed to checkout' button. The website now automatically switches to a secure
channel when presenting the checkout page. You see the HTTPS protocol displayed
in the browser's address bar, and the port is changed to 8181.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/secure-checkout.png"
class="margin-around b-all" alt="Browser address bar showing HTTPS protocol for checkout request"
title="The browser address bar indicates that a secure connection is established for customer checkout">
<br>
Also, in Firefox, note the lock (
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/firefox-lock-icon.png"
alt="Firefox lock icon"> ) icon displayed in the lower right corner of the browser.</li>
<li>Investigate security for the administration console. Type in the following URL into the browser's
address bar:
<pre class="examplecode">http://localhost:8080/AffableBean/admin/</pre>
The website now automatically switches to a secure
channel when presenting the checkout page. You see the HTTPS protocol displayed
in the browser's address bar, and the port is changed to 8181.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/secure-admin.png"
class="margin-around b-all" alt="Browser address bar showing HTTPS protocol for checkout request"
title="The browser address bar indicates that a secure connection is established for customer checkout">
<p class="notes"><strong>Note:</strong> You way wonder at this point how it is possible
to switch from a secure connection back to a normal, unsecured one. This practice
however is not recommended. The <a href="http://download.oracle.com/javaee/6/tutorial/doc/gkbaa.html#bncbm"
target="_blank">Java EE 6 Tutorial</a> explains as follows:</p>
<blockquote style="margin-top: 0">
<em>If you are using sessions, after you switch to SSL you should never accept any
further requests for that session that are non-SSL. For example, a shopping site
might not use SSL until the checkout page, and then it might switch to using SSL
to accept your card number. After switching to SSL, you should stop listening to
non-SSL requests for this session. The reason for this practice is that the session
ID itself was not encrypted on the earlier communications. This is not so bad when
you’re only doing your shopping, but after the credit card information is stored
in the session, you don’t want a bad guy trying to fake the purchase transaction
against your credit card. This practice could be easily implemented using a filter.</em>
</blockquote></li>
</ol>
</div>
<p>You have now successfully secured the <code>AffableBean</code> application according to the defined
customer requirements. You've set up a login form for the administration console to authorize or deny
access based on user credentials, and you configured the application and server to create a secure
connection for access to the administration console, as well as the customer checkout process.</p>
<p>You can compare your work with the <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_complete.zip">completed
<code>AffableBean</code> project</a>. The completed project includes the security implementation
demonstrated in this unit, and also provides a basic implementation for web page error customization,
such as when a request for a nonexistent resource is made, and the server returns an HTTP 404
'Not Found' error message.</p>
<div class="indent">
<img src="../../../../images_www/articles/73/javaee/ecommerce/security/http-404.png"
class="margin-around b-all" style="width:728px" alt="Browser address bar showing HTTPS protocol for checkout request"
title="The browser address bar indicates that a secure connection is established for customer checkout">
</div>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans E-commerce Tutorial - Securing the Application">Send
Us Your Feedback</a></div>
<br style="clear:both;">
<br>
<h2 id="seeAlsoSecurity">See Also</h2>
<div class="indent">
<h3>NetBeans Resources</h3>
<ul>
<li><a href="../../web/security-webapps.html" target="_blank">Securing a Web Application</a></li>
<li><a href="../javaee-intro.html" target="_blank">Introduction to Java EE Technology</a></li>
<li><a href="../javaee-gettingstarted.html" target="_blank">Getting Started with Java EE Applications</a></li>
<li><a href="https://netbeans.org/projects/www/downloads/download/shortcuts.pdf">Keyboard Shortcuts & Code Templates Card</a></li>
<li><a href="../../../trails/java-ee.html" target="_blank">Java EE & Java Web Learning Trail</a></li>
</ul>
<h3>External Resources</h3>
<ul>
<li><a href="http://download.oracle.com/javaee/6/tutorial/doc/bnbwj.html" target="_blank">The Java EE 6 Tutorial, Chapter 24: Introduction to Security in the Java EE Platform</a></li>
<li><a href="http://download.oracle.com/javaee/6/tutorial/doc/bncas.html" target="_blank">The Java EE 6 Tutorial, Chapter 25: Getting Started Securing Web Applications</a></li>
<li><a href="http://download.oracle.com/javaee/6/tutorial/doc/bnbyk.html" target="_blank">The Java EE 6 Tutorial, Chapter 26: Getting Started Securing Enterprise Applications</a></li>
<li><a href="http://docs.sun.com/app/docs/doc/821-1751" target="_blank">Oracle GlassFish Server 3.0.1 Administration Guide</a></li>
<li><a href="http://java.sun.com/developer/technicalArticles/J2EE/security_annotation/" target="_blank">Security Annotations and Authorization in GlassFish and the Java EE 5 SDK</a></li>
<li><a href="http://www.infoq.com/news/2010/07/javaee6-security" target="_blank">Java EE 6: Application Security Enhancements</a></li>
<li><a href="http://refcardz.dzone.com/refcardz/getting-started-java-ee" target="_blank">Getting Started with Java EE Security</a> [RefCard]</li>
<li><a href="http://en.wikipedia.org/wiki/Https" target="_blank">HTTP Secure</a> [Wikipedia]</li>
<li><a href="http://en.wikipedia.org/wiki/Digital_certificate" target="_blank">Public key certificate</a> [Wikipedia]</li>
</ul>
</div>
<br><br><br><br>
<h1 id="test-profile">The NetBeans E-commerce Tutorial - Testing and Profiling</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Tutorial Contents</h4>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#design">Designing the Application</a></li>
<li><a href="#setup-dev-environ">Setting up the Development Environment</a></li>
<li><a href="#data-model">Designing the Data Model</a></li>
<li><a href="#page-views-controller">Preparing the Page Views and Controller Servlet</a></li>
<li><a href="#connect-db">Connecting the Application to the Database</a></li>
<li><a href="#entity-session">Adding Entity Classes and Session Beans</a></li>
<li><a href="#manage-sessions">Managing Sessions</a></li>
<li><a href="#transaction">Integrating Transactional Business Logic</a></li>
<li><a href="#language">Adding Language Support</a></li>
<li><a href="#security">Securing the Application</a></li>
<li><strong>Testing and Profiling</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#test">Testing with JMeter</a></li>
<li><a href="#profile">Using the NetBeans Profiler</a></li>
<li><a href="#glassFishTune">Tuning the GlassFish Server</a></li>
<li><a href="#seeAlsoTestProfile">See Also</a></li>
</ul></li>
<li><a href="#conclusion">Conclusion</a></li>
</ol>
</div>
</div>
<p><img src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" class="stamp"
alt="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"
title="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"></p>
<p>Before delivering any application, it is important to ensure that it functions
properly, and that it can perform acceptably for the demands expected of it. Web
applications, especially e-commerce applications, by their very nature provide
concurrent access to shared resources. In other words, the servers on which they
are hosted must be able to respond to multiple users requesting the same resources
over the same period of time. Be mindful of this fact when during development
your application appears to behave correctly as you click through web pages in
your browser. How will the application perform when handling 100 users simultaneously?
Are there memory leaks that will degrade the server's performance after the
application has been running for long periods of time? What steps can you take
to ensure that your production server best handles traffic to your application?</p>
<p>This tutorial unit is designed to introduce you to the IDE's support for testing
and profiling. You begin by installing the JMeter Kit plugin, which enables you to
create test plans and open them in <a href="http://jakarta.apache.org/jmeter/"
target="_blank">Apache JMeter</a> from the IDE. You then create a basic test plan
in JMeter, and proceed by exploring the tool's capacity for functional and
performance testing. Finally, you explore the IDE's Profiler, and use it to
examine GlassFish' memory consumption while you run the JMeter test plan against
the <code>AffableBean</code> application over an extended period of time. This unit
concludes by presenting various tips that enable you to tune the GlassFish server
for your application in a production environment.</p>
<p>You can view a live demo of the application that you build in this tutorial:
<a href="http://services.netbeans.org/AffableBean/" target="_blank">NetBeans
E-commerce Tutorial Demo Application</a>.</p>
<br style="clear:left;">
<br>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html" target="_blank">NetBeans IDE</a></td>
<td class="tbltd1">Java bundle, 6.8 or 6.9</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank">Java Development Kit (JDK)</a></td>
<td class="tbltd1">version 6</td>
</tr>
<tr>
<td class="tbltd1"><a href="#glassFishTestProfile">GlassFish server</a></td>
<td class="tbltd1">v3 or Open Source Edition 3.0.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="#jmeter">JMeter</a></td>
<td class="tbltd1">2.2 or more recent</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://dev.mysql.com/downloads/mysql/" target="_blank">MySQL database server</a></td>
<td class="tbltd1">version 5.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_complete.zip">AffableBean
project</a></td>
<td class="tbltd1">complete version</td>
</tr>
</tbody>
</table>
<p><strong class="notes">Notes:</strong></p>
<ul>
<li>The NetBeans IDE requires the Java Development Kit (JDK) to run properly.
If you do not have any of the resources listed above, the JDK should be
the first item that you download and install.</li>
<li>The NetBeans IDE Java Bundle includes Java Web and EE technologies, which are
required for the application you build in this tutorial.</li>
<li id="glassFishTestProfile">The NetBeans IDE Java Bundle also includes the GlassFish server,
which you require for this tutorial. You could
<a href="http://glassfish.dev.java.net/public/downloadsindex.html" target="_blank">download
the GlassFish server independently</a>, but the version provided with the
NetBeans download has the added benefit of being automatically registered with
the IDE.</li>
<li>You can follow this tutorial unit without having completed previous units. To
do so, see the <a href="#setup">setup instructions</a>, which describe how
to prepare the database and establish connectivity between the IDE, GlassFish,
and MySQL.</li>
<li id="jmeter"><strong>You do not need to download JMeter for its use in this tutorial.</strong>
Instead, you install the NetBeans JMeter Kit plugin, which includes the JMeter
distribution. You will therefore require an Internet connection at the point
when you install the plugin in the tutorial. JMeter can be downloaded independently
from <a href="http://jakarta.apache.org/site/downloads/downloads_jmeter.cgi"
target="_blank">http://jakarta.apache.org/site/downloads/downloads_jmeter.cgi</a>.</li>
<li>The JMeter Kit plugin for NetBeans 6.8 installs JMeter version 2.2 (released
June 2006). The plugin for NetBeans 6.9 installs JMeter version 2.4 (released
July 2010). There is a significant difference between these two versions.</li>
</ul>
<h2 id="test">Testing with JMeter</h2>
<p>Begin by examining the <code>AffableBean</code> tutorial application. Then install the
JMeter Kit plugin using the IDE's Plugins Manager. Launch JMeter from the IDE, and
proceed by creating a test plan based on the tutorial <a href="design.html#mockups">use-case</a>.
Finally, explore some of JMeter's facilities for functional and load testing.</p>
<ul>
<li><a href="#install">Install the JMeter Kit Plugin</a></li>
<li><a href="#createTestPlan">Create a Test Plan</a></li>
<li><a href="#loadTest">Load Testing</a></li>
<li><a href="#stressTest">Stress Testing</a></li>
</ul>
<div class="indent">
<h3 id="install">Install the JMeter Kit Plugin</h3>
<ol>
<li>Open the <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_complete.zip"><code>AffableBean</code>
project</a> in the IDE. Click the Open Project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/open-project-btn.png"
alt="Open Project button"> ) button and use the wizard to navigate to the location
on your computer where you downloaded the project.</li>
<li>Run the project (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) to ensure that it is properly configured with your database
and application server.
<br>
<p class="alert margin-around">If you receive an error when running the project, revisit the
<a href="#setup">setup instructions</a>, which describe how to prepare the
database and establish connectivity between the IDE, GlassFish, and MySQL.
If you want to log into the project's administration console (not required in
this tutorial unit), you'll need to create a user named <code>nbuser</code> on
the GlassFish server. This task is described in Unit 11,
<a href="security.html#createUsers">Securing the Application: Create Users and/or
Groups on the Server</a>.</p></li>
<li>Open the IDE's Plugins Manager by choosing Tools &gt; Plugins from the main menu.
Select the Available Plugins tab, then type in '<code>jmeter</code>' into the Search
field. When you see JMeter Kit displayed from the filtered results, select it by
clicking the checkbox under the Install column.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/plugins-manager.png"
class="margin-around b-all" style="width:688px" alt="JMeter Kit displayed under Available Plugins in the Plugins Manager"
title="JMeter Kit is a NetBeans certified plugin available in the Plugins Manager"></li>
<li>Click Install. The IDE's installer informs you that two plugins will be installed:
The JMeter Kit and the Load Generator, which provides a generic infrastructure for
load generator engines registered in the IDE.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/ide-installer.png"
class="margin-around b-all" alt="JMeter Kit and Load Generator listed in the IDE's Plugin Installer"
title="Plugins dependencies are automatically included during installation"></li>
<li>Click Next. Accept the license agreement, then click Install.
<br>
<p class="alert margin-around">You require an Internet connection to download the selected plugins.</p>
The installer downloads, verifies, and installs the plugins. When installation
has successfully completed, click Finish to exit the installer, then click Close
to close the Plugins Manager.</li>
<li>In the Projects window, note that a new Load Generator Scripts node displays in
your project.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/load-generator-scripts.png"
class="margin-around b-all" alt="Projects window displaying Load Generator Scripts node"
title="The Load Generator plugin enables you to access scripts from the Projects window">
<br>
If you open the Files window (Ctrl-2; &#8984;-2 on Mac), you'll see a new <code>jmeter</code>
folder added to the project. (Recall that the Files window provides a directory-based view of
projects, i.e., it displays the folder structure of projects as they exist on your computer's
file system.) The <code>jmeter</code> folder corresponds to the Project window's Load Generator
Scripts node, and will contain any load scripts that you later add to the project.</li>
</ol>
<h3 id="createTestPlan">Create a Test Plan</h3>
<p>To demonstrate how to create a test plan in JMeter, we'll base our plan on the
tutorial use-case, which was presented in <a href="design.html#mockups">Designing
the Application</a>. A list of user-initiated requests to the server, based on
the given use-case, might look something like the following:</p>
<table id="useCase" style="width:742px">
<tr>
<th width="558px" class="tblheader" scope="col">Use-Case</th>
<th class="tblheader" scope="col">Server Request</th>
</tr>
<tr class="tbltd0">
<td><em>Customer visits the welcome page...</em></td>
<td><code>/AffableBean/</code></td>
</tr>
<tr class="tbltd1">
<td><em>...and selects a product category.</em></td>
<td><code>/AffableBean/category</code></td>
</tr>
<tr class="tbltd0">
<td><em>Customer browses products within the selected category page,
then adds a product to his or her shopping cart.</em></td>
<td><code>/AffableBean/addToCart</code></td>
</tr>
<tr class="tbltd1">
<td><em>Customer continues shopping and selects a different category.</em></td>
<td><code>/AffableBean/category</code></td>
</tr>
<tr class="tbltd0">
<td><em>Customer adds several products from this category to shopping cart.</em></td>
<td><code>/AffableBean/addToCart</code><br><code>/AffableBean/addToCart</code></td>
</tr>
<tr class="tbltd1">
<td><em>Customer selects 'view cart' option...</em></td>
<td><code>/AffableBean/viewCart</code></td>
</tr>
<tr class="tbltd0">
<td><em>...and updates quantities for cart products in the cart page.</em></td>
<td><code>/AffableBean/updateCart</code></td>
</tr>
<tr class="tbltd1">
<td><em>Customer verifies shopping cart contents and proceeds to checkout.</em></td>
<td><code>/AffableBean/checkout</code></td>
</tr>
<tr class="tbltd0">
<td><em>In the checkout page, customer views the cost of the order and other
information, fills in personal data, then submits his or her details.</em></td>
<td><code>/AffableBean/purchase</code></td>
</tr>
<tr class="tbltd1">
<td><em>The order is processed and customer is taken to a confirmation page.
The confirmation page provides a unique reference number for tracking
the customer order, as well as a summary of the order.</em></td>
<td>(n/a)</td>
</tr>
</table>
<p>Let's proceed by creating a JMeter test plan that follows the above list of requests.</p>
<ol style="margin-top:0">
<li>Click the New File (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/new-file-btn.png"
alt="New File button"> ) button in the IDE's toolbar. (Alternatively, press Ctrl-N;
&#8984;-N on Mac.)</li>
<li>Under Categories, select <strong>Load Testing Scripts</strong>.
<br><br>
<p class="tips">Instead of scrolling to the bottom of the list, simply begin typing
'<code>load</code>'. As shown in the image below, the Load Testing Scripts
category displays.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/file-wizard-load.png"
class="margin-around b-all" alt="Load Generator Scripts category displayed in File wizard"
title="You can filter category entries by typing the category you are searching for"></p></li>
<li>Expand the Load Testing Scripts category and select <strong>JMeter Plans</strong>.
Under File Types, select <strong>New JMeter Plan</strong>, then click Next.</li>
<li>Name the plan <code>useCaseTest</code>, then click Finish. The new test plan
displays in the Projects window.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/use-case-test.png"
class="margin-around b-all" alt="New 'useCaseTest' test plan displayed in Projects window"
title="JMeter test plans display under Load Testing Scripts in the Projects window"></li>
<li>To begin customizing the plan in JMeter, right-click the <code>useCaseTest.jmx</code>
node and choose External Edit. JMeter opens.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/jmeter.png"
class="margin-around b-all" style="width:688px" alt="NetBeans template plan displayed in JMeter"
title="NetBeans template plan is provided when opening JMeter" id="testPlanPanel">
<p class="notes"><strong>Note:</strong> The NetBeans template plan includes various
user-defined variables, as shown in the above image. Usage of several of these
variables will become clear as we work with the test plan. For more information,
see the Apache JMeter User's Manual:
<a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#User_Defined_Variables"
target="_blank">18.4.13 User Defined Variables</a>.</li>
<li>Click the HTTP Request Defaults node in the left column. The
<a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#HTTP_Request_Defaults"
target="_blank">HTTP Request Defaults</a> panel enables you to set default values for
all HTTP requests invoked from your test plan. Note that the entries for Server Name
and Port Number are <code>${nb.server}</code> and <code>${nb.port}</code>, respectively.
From the image above, you see that these equate to <code>localhost</code> and
<code>8080</code>, which you typically use when deploying NetBeans projects to
GlassFish.</li>
<li>Click the Thread Group node in the left column. In JMeter, a &quot;thread&quot; refers
to a user. Let's rename the Thread Group to <code>AffableBean</code> <code>Users</code>.
Type '<code>AffableBean</code> <code>Users</code>' into the Name field under Thread Group.
<br><br>
Let's begin recording requests for the test plan. To do so, we'll use JMeter's
<a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#HTTP_Proxy_Server"
target="_blank">HTTP Proxy Server</a>. Instead of entering test plan requests
manually, we'll run the proxy server and have it record requests sent from the
browser. For large test plans this technique is invaluable.</li>
<li>In the left column, right-click WorkBench and choose Add &gt; Non-Test Elements &gt;
HTTP Proxy Server.</li>
<li>In the HTTP Proxy Server panel, change the port number from <code>8080</code> to another,
random number, for example <code>9090</code>. JMeter provides <code>8080</code> as
its default port number for the proxy server. However, the GlassFish server also occupies
the <code>8080</code> port, so we're modifying the proxy server's port number to avoid
a port conflict.</li>
<li>In the Grouping drop-down list, select 'Put each group in a new controller'. Also, deselect
the 'Capture HTTP Headers' option. We do not require header information for each recorded
request.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/http-proxy-server.png"
class="margin-around b-all" style="width:688px" alt="JMeter HTTP Proxy Server - top panes"
title="Configure the proxy server">
<br>
Note that the 'Use Recording Controller' option is selected by default for the Target Controller
field. When you begin recording requests, they will be stored in the Recording Controller
that is listed in the left column. </li>
<li>Switch to your browser and temporarily change its port number to <code>9090</code>.
<br>
<p class="alert margin-around">If you have previously configured your browser's proxy, remember your settings
so that you may be able to reenter them after completing this exercise.</p>
In Firefox, you can do this from the Options window (Preferences window on Mac).
<ul style="margin-top:8px; list-style-type:lower-alpha">
<li>Choose Tools &gt; Options (Firefox &gt; Preferences on Mac).</li>
<li>Select the Advanced &gt; Network tabs.</li>
<li>Under the Connection heading, click Settings.</li>
<li>Select the 'Manual proxy configuration' option, then type in <code>localhost</code>
and <code>9090</code> for the HTTP Proxy and Port fields, respectively.</li>
<li>Remove the <code>127.0.0.1</code> and <code>localhost</code> entries in the
'No Proxy for' field.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/firefox-proxy.png"
class="margin-around b-all" alt="Firefox Preferences window - proxy settings" id="ff-proxy-config"
title="Specify 'localhost:9090' and remove entries in the 'No Proxy for' field"></li>
<li>Click OK.</li>
</ul>
</li>
<li>Clear your browser's cache before you begin recording requests. You want to make sure
that the HTTP Proxy Server is able to record all resources required for displaying
pages in the Affable Bean website, including images, JavaScript scripts and CSS stylesheets.
<br><br>
In Firefox, you can do this by pressing Ctrl-Shift-Del (&#8984;-Shift-Del on Mac) to
open the Clear Recent History dialog. Under 'Time range to clear', ensure that you've
selected a range that extends to the first time the browser accessed the Affable Bean
website. Select Cache, then click Clear Now.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/ff-clear-recent-history.png"
class="margin-around b-all" alt="Firefox Clear Recent History dialog"
title="Clear your browser's cache before proceeding with recording"></li>
<li>Return to the JMeter Test Plan panel (<a href="#testPlanPanel">shown above</a>) and
change the values for <code>nb.users</code> and <code>nb.rampup</code> to <code>99</code>.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/user-defined-variables.png"
class="margin-around b-all" alt="User-defined variables in JMeter"
title="Double-click into User Defined Variables table to modify variables">
<br>
The reason this is recommended is that JMeter automatically inserts user-defined variables
throughout the test plan, wherever their values occur. So, for example, when the URL for
<code>/AffableBean/js/jquery-1.4.2.js</code> is encountered, it will be recorded as:
<code>AffableBean/js/jquery-1.4.<strong>${nb.users}</strong>.js</code>. Later, when we
modify the value and rerun the test plan, URLs such as this will also change, which is
not desired behavior. Here, we enter a random value (<code>99</code>), since we don't
expect it to occur in the URLs that we are about to record.</li>
<li>Return to the HTTP Proxy Server panel, then at the bottom of the panel, click the Start
button. JMeter's proxy server is now listening on port 9090.</li>
<li>Run the project ( <img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"
alt="Run Project button"> ) from the IDE. The project is deployed to GlassFish, and the
welcome page opens in the browser.</li>
<li>Switch to JMeter and inspect the Recording Controller in the left column. All of the
requests generated for accessing the welcome page are listed under the Recording Controller
in a node named after the first request (i.e., <code>/AffableBean/</code>).
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/recording-controller.png"
class="margin-around b-all" alt="JMeter - Recording Controller in left column"
title="Request grouping for welcome page displayed under Recording Controller">
<br>
<p class="tips">If you inspect the <code>/AffableBean/</code> node, you'll note that it
is a <a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#Simple_Controller"
target="_blank">Simple Controller</a>. Although dubbed a &quot;Controller&quot;, the
Simple Controller doesn't offer any functionality beyond enabling you to group elements
together - as demonstrated here.</p></li>
<li>Return to the browser and continue clicking through the website according to the use-case
<a href="#useCase">outlined above</a>. You can select any of the categories and products.
Stop when you reach the checkout page - the proxy server will not be able to record requests
sent over HTTPS.<sup><a href="#footnote1TestProfile" id="1TestProfile" style="text-decoration:none">[1]</a></sup>
<br><br>
The elements within the Recording Controller will look as follows.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/recording-controller2.png"
class="margin-around b-all" alt="JMeter - Recording Controller in left column"
title="Requests according to use-case listed under Recording Controller"></li>
<li>Stop the proxy server. Click the Stop button in JMeter's HTTP Proxy Server panel.</li>
<li>In your browser, change the proxy configuration so that it no longer uses port 9090.
In Firefox for example, return to the proxy configuration window (<a href="#ff-proxy-config">displayed
above</a>) and select No Proxy.</li>
<li>Manually create the request for <code>/AffableBean/purchase</code>. Perform the following
steps:
<ol style="margin-top:8px; list-style-type:lower-alpha">
<li>Click the Simple Controller in JMeter's left column, then press Ctrl-X (&#8984;-X
on Mac) to cut the element.</li>
<li>Click the Recording Controller, then press press Ctrl-V (&#8984;-V on Mac) to paste
the element. The Simple Controller now displays beneath the <code>/AffableBean/checkout</code>
request.</li>
<li>Click the Simple Controller node, then in its main panel rename the controller to
<code>/AffableBean/purchase</code>.</li>
<li>Right-click the new <code>/AffableBean/purchase</code> node and choose Add &gt; Sampler
&gt; <a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#HTTP_Request"
target="_blank">HTTP Request</a>.</li>
<li>Click the new HTTP Request node, then in its main panel configure it as follows:
<ul style="margin: 7px 0 0 -1.7em">
<li><strong>Name:</strong> <code>/AffableBean/purchase</code></li>
<li><strong>Server Name or IP:</strong> <code>${nb.server}</code></li>
<li><strong>Port Number:</strong> <code>8181</code></li>
<li><strong>Protocol:</strong> <code>https</code></li>
<li><strong>Method:</strong> <code>POST</code></li>
<li><strong>Path:</strong> <code>/AffableBean/purchase</code></li>
</ul></li>
<li>Under 'Send Parameters With the Request', click the Add button and create
the following entries:
<table class="margin-around">
<tbody>
<tr>
<th class="tblheader" scope="col">Name</th>
<th class="tblheader" scope="col">Value</th>
<th class="tblheader" scope="col">Encode?</th>
<th class="tblheader" scope="col">Include Equals?</th>
</tr>
<tr>
<td class="tbltd1"><code>name</code></td>
<td class="tbltd1"><code>Benjamin Linus</code></td>
<td class="tbltd1" style="text-align: center">&#10003;</td>
<td class="tbltd1" style="text-align: center">&#10003;</td>
</tr>
<tr>
<td class="tbltd1"><code>email</code></td>
<td class="tbltd1"><code>b.linus@lost.com</code></td>
<td class="tbltd1" style="text-align: center">&#10003;</td>
<td class="tbltd1" style="text-align: center">&#10003;</td>
</tr>
<tr>
<td class="tbltd1"><code>phone</code></td>
<td class="tbltd1"><code>222756448</code></td>
<td class="tbltd1" style="text-align: center">&#10003;</td>
<td class="tbltd1" style="text-align: center">&#10003;</td>
</tr>
<tr>
<td class="tbltd1"><code>address</code></td>
<td class="tbltd1"><code>DruĹľstevnĂ­ 77</code></td>
<td class="tbltd1" style="text-align: center">&#10003;</td>
<td class="tbltd1" style="text-align: center">&#10003;</td>
</tr>
<tr>
<td class="tbltd1"><code>cityRegion</code></td>
<td class="tbltd1"><code>4</code></td>
<td class="tbltd1" style="text-align: center">&#10003;</td>
<td class="tbltd1" style="text-align: center">&#10003;</td>
</tr>
<tr>
<td class="tbltd1"><code>creditcard</code></td>
<td class="tbltd1"><code>4444222233331111</code></td>
<td class="tbltd1" style="text-align: center">&#10003;</td>
<td class="tbltd1" style="text-align: center">&#10003;</td>
</tr>
</tbody>
</table>
</li>
</ol>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/http-request.png"
class="margin-around b-all" style="margin-top:0; width:688px" alt="JMeter - HTTP Request panel"
title="Configure an HTTP Request for HTTPS connection"></li>
<li>Now, add an <a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#HTTP_Cookie_Manager"
target="_blank">HTTP Cookie Manager</a> to the test plan. Right-click the <code>AffableBean</code>
<code>Users</code> thread group node in JMeter's left column, then choose Add &gt; Config Element
&gt; HTTP Cookie Manager.
<br><br>
Recall that the <code>AffableBean</code> application relies on a session-tracking mechanism
(i.e., cookies or URL-rewriting) to remember which shopping cart belongs to which request.
Therefore, we need to account for this in the test plan. JMeter acts as the client when sending
requests to the server, however unlike a browser, it doesn't have cookies &quot;enabled by
default.&quot; We apply the HTTP Cookie Manager to the thread group so that the
<code>JSESSIONID</code> cookie can be passed between client and server.
<br><br>
<p class="notes"><strong>Note:</strong> If you want to employ URL rewriting as the
session-tracking mechanism, you would need to add the
<a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#HTTP_URL_Re-writing_Modifier"
target="_blank">HTTP URL Re-writing Modifier</a> to the thread group.</p></li>
<li>Finally, add an element to the test plan that simulates a delay between user-initiated requests.
<ol style="margin-top:8px; list-style-type:lower-alpha">
<li>Right-click the <code>/AffableBean/</code> Simple Controller in the left column
and choose Add &gt; Sampler &gt; Test Action.</li>
<li>In the main panel, specify the following:
<ul style="margin-top:8px">
<li><strong>Name:</strong> <code>user delay</code></li>
<li><strong>Duration (milliseconds):</strong> <code>${nb.interleave}</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/test-action.png"
class="margin-around b-all" alt="JMeter - Test Action panel"
title="Use a Test Action element to simulate a delay between user-initiated requests"></li>
<li>In JMeter's left column, copy (Ctrl-C; &#8984;-C on Mac) the new <code>user</code> <code>delay</code>
Test Action node, then paste it (Ctrl-V; &#8984;-V on Mac) into each of the other Simple Controllers (
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/simple-controller-node.png"
alt="Simple Controller icon"> ) that form the test plan, except for the final one
(<code>/AffableBean/purchase</code>).
<br><br>
When you finish, the final six Simple Controllers and their contents will look as follows.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/user-delay.png"
class="margin-around b-all" alt="Test Action nodes shown in JMeter left column"
title="Use copy and paste functionality to place existing elements elsewhere in your test plan">
</li>
</ol>
</li>
<li>(<em>Optional</em>.) Clean up the test plan. You can remove the Loop Controller and
Constant Timer. (Right-click and choose Remove.) Also, move all of the Recording Controller's
child elements directly into the <code>AffableBean</code> <code>Users</code> thread group,
then remove the Recording Controller. When you finish, the test plan will look as follows.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/test-plan.png"
class="margin-around b-all" alt="Test plan displayed in JMeter left column"
title="Remove unnecessary items from test plan">
</li>
</ol>
<h3 id="loadTest">Load Testing</h3>
<p><a href="http://en.wikipedia.org/wiki/Load_testing" target="_blank">Load testing</a> a web
application involves making concurrent requests for resources, typically by simulating multiple
users, and then examining the server's behavior. We can use the test plan we created for this
purpose, and make adjustments to the number of users and other settings to determine how the
server behaves under the given work load.</p>
<p>Load testing should be performed with specific goals in mind, such as determining the
<a href="http://en.wikipedia.org/wiki/Throughput" target="_blank">throughput</a> for
the anticipated average and peak numbers of users. It is also worthwhile to assess the
<em>response time</em> for requests, to ensure that site customers are not having to wait
too long to be served. In order to measure the response time, you need to take into account
the time during which data spends traveling over the Internet. One way to do this is to
compare test results between a local server, where network travel time is nearly non-existent,
and results from testing the production server remotely. The following example demonstrates
how you can perform tests using your local development server. Once you migrate an application
to the production server, you can simply change the value for the server variable set
under the test plan's User Defined Variables.</p>
<p>The results recorded in this and the following sections were arrived at by running tests on
a computer with a 2.4 GHz Intel Core 2 Duo processor and 4 GB of memory. Naturally, the results
you get depend on your computer's performance, and will likely not match those displayed here.</p>
<p class="alert">When you run load tests, you should be careful not to overload your computer.
If you set too many threads (i.e., users), do not place adequate delay between individual
requests, or continuously loop through the test plan, there is a chance that JMeter will
expend your computer’s processing capacity or memory. JMeter will then become unresponsive
and you may need to &quot;force quit&quot; the tool using your computer's task manager. It
is therefore recommended that you open the task manager in order to monitor the computer's
CPU and memory levels while the test is running. This will allow you to gauge the limits
of your computer in terms of running the test plan.</p>
<ol>
<li>Open JMeter if it is not already opened. (In the IDE's Projects window, right-click
<code>useCaseTest.jmx</code> and choose External Edit.)
<br><br>
<p class="notes"><strong>Note:</strong> If you did not create the JMeter test plan in
the <a href="#createTestPlan">previous sub-section</a>, you can download the complete
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FuseCaseTest.jmx"><code>useCaseTest.jmx</code></a>
file and add it to your project. To add it to the <code>AffableBean</code> project,
copy it from your computer's file system (Ctrl-C; &#8984;-C on Mac), then in the IDE,
open the Files window (Ctrl-2; &#8984;-2 on Mac), right-click the <code>jmeter</code>
folder and choose Paste.</p></li>
<li>Add several <em>listeners</em> to the test plan:
<ul style="margin: 7px 0 0 -1.7em">
<li>Right-click <code>AffableBean</code> <code>Users</code> and choose Add &gt;
Listener &gt; <strong>Summary Report</strong>.</li>
<li>Right-click <code>AffableBean</code> <code>Users</code> and choose Add &gt;
Listener &gt; <strong>View Results Tree</strong>.</li>
<li>Right-click <code>AffableBean</code> <code>Users</code> and choose Add &gt;
Listener &gt; <strong>Graph Results</strong>.</li>
</ul>
In JMeter, you require a <em>listener</em> to record and display the results of your test plan.
The <a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#Summary_Report"
target="_blank">Summary Report</a> displays a table, with each row corresponding to each
differently named request in your test. The
<a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#View_Results_Tree"
target="_blank">View Results Tree</a> shows a tree of all sample responses, allowing you
to view response details for any sample. The
<a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#Graph_Results"
target="_blank">Graph Results</a> listener displays a simple graph that plots all
sample times.</li>
<li>Click the JMeter Template Plan node, then make the following changes to User Defined
Variables:
<ul style="margin: 7px 0 0 -1.7em">
<li><strong><code>nb.users</code>:</strong> <code>1</code></li>
<li><strong><code>nb.interleave</code>:</strong> <code>5000</code></li>
</ul>
We begin the test by simulating just one user. The value for <code>nb.interleave</code>
is used in the <code>user</code> <code>delay</code> Test Action that we created, and
represents the duration of a pause in milliseconds. Therefore, the test will pause for
5 seconds between each user-initiated request.</li>
<li>Click the Summary Report node so that you are able to view the test results while the
test is running.</li>
<li>Run the test plan. Choose Run &gt; Start (Ctrl-R; &#8984;-R on Mac) from the main menu.
<br><br>
The test plan runs for approximately 50 seconds. Note that request samples are taken
every three seconds, during which you can watch as results are added and updated. Note
that values for the <code>Average</code>, <code>Min</code>, and <code>Max</code> columns
are represented in milliseconds.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/summary-report.png"
class="margin-around b-all" alt="JMeter - Summary Report" style="width:688px"
title="Summary Report displays results from the completed test plan">
<p>From the results displayed in the above image, we can observe that:</p>
<ul style="margin: 7px 0 0 -1.7em">
<li>The server, when loaded with a single user, provides a total <em>throughput</em> of
approximately 41 per minute. In other words, the server is capable of serving all
requests within the test plan 41 times within a minute. According to the
<a href="http://jakarta.apache.org/jmeter/usermanual/glossary.html#Throughput"
target="_blank">JMeter User's Manual</a>, the throughput is calculated as:
<code>(number</code> <code>of</code> <code>requests)/(total</code> <code>time)</code>,
and includes any delay inserted between samples, as it is supposed to represent
the load on the server. When we consider that the <code>user</code> <code>delay</code>
occurs for 5 seconds between each request (9 times in total, 9 * 5 seconds = 45 seconds),
we see that with the server would theoretically be utilized for only approximately
15 seconds.</li>
<li>The <code>AffableBean/checkout</code> request, recorded at 33 milliseconds, takes
much longer to process than most other requests. This is likely due to the fact that
the initial request is redirected to the HTTP + SSL protocol on port 8181. So there
are essentially two requests taking place.</li>
<li>The <code>AffableBean/purchase</code> request, recorded at 147 milliseconds, takes
the most time to be served. This is likely due to both the write operations required
on the database, and the fact that client-server communication takes place over an
encrypted channel (i.e., using HTTPS).</li>
<li>According to the <code>Error</code> <code>%</code> column, no errors occurred from
running the test. In other words, all server responses included an HTTP 200 status.</li>
<li>The <code>Avg.</code> <code>Bytes</code> column represents the average size of the
sample response. We see that the JQuery core library (<code>jquery-1.4.2.js</code>)
is the largest file that is served in the test plan, at nearly 164 KB. Because the
file is served each time a new user accesses the site, it may be worth linking to
this file on a public <a href="http://en.wikipedia.org/wiki/Content_delivery_network"
target="_blank">content delivery network</a> (CDN) instead of maintaining it on the
server. &quot;Unburdening&quot; the server in this manner could have a notable
effect on its overall performance.
<br><br>
<p class="tips">For further information, see the official jQuery documentation:
<a href="http://docs.jquery.com/Downloading_jQuery#CDN_Hosted_jQuery" target="_blank">CDN
Hosted jQuery</a>.</p></li>
</ul></li>
<li>Click the View Results Tree node. Here you see the individual results from each of the sample
requests, listed in the order in which they occurred.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/view-results-tree.png"
class="margin-around b-all" alt="JMeter - View Results Tree" style="width:688px"
title="View Results Tree displays a tree of all sample responses listed in the order in which they occurred">
<br>
The green (
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/jmeter-ok-icon.png"
alt="success icon"> ) icons indicate an HTTP status response of 200. In the above image, under
'Sampler result' in the right panel, note that the Thread Name for the selected sample is
'AffableBean Users 1-1'. The second '1' represents the thread (i.e., user) number. When testing
multiple threads, you can use View Results Tree listener to pinpoint exactly when each thread
makes a request within the test. Finally, in the image above, note that the 'HTML (download
embedded resources)' option is selected in the lower left corner. When you select the 'Response
data' tab in the right panel, JMeter attempts to render the response as it would display in a
browser.
<br><br>
<p class="notes"><strong>Note:</strong> Red warning
( <img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/jmeter-warning-icon.png"
alt="warning icon"> ) icons indicate that requests are not being handled properly
(i.e., HTTP 404 status messages are being sent). While this begins to happen when a
server reaches its performance capacity, 404 status messages under a normal load
suggest that the application is not functionally stable. You should then check the
server log to determine why requests are failing, and make changes to your application.
<br><br>
In the coming steps, we'll add an increasing number of users to the test, and examine the
server's overall throughput.</li>
<li>Click the JMeter Template Plan node, then make the following changes to User Defined Variables:
<ul style="margin: 7px 0 0 -1.7em">
<li><strong><code>nb.users</code>:</strong> <code>20</code></li>
<li><strong><code>nb.rampup</code>:</strong> <code>20</code></li>
</ul>
The <code>nb.rampup</code> variable is used in the <code>AffableBean</code> <code>Users</code>
Thread Group panel, and specifies the ramp-up period in seconds. In this case, if we test 20
users and the ramp-up period is 20 seconds, then a new user will begin sending requests
every second.</li>
<li>Clear the results from the previous test by choosing Run &gt; Clear All (Ctrl-E; &#8984;-E on Mac).</li>
<li>Click the Graph Results node so that you are able to view the test results while the
test is running.</li>
<li>Run the test plan. Choose Run &gt; Start (Ctrl-R; &#8984;-R on Mac) from the main menu.
When the test plan runs, make the following observations:
<ul style="margin: 7px 0 0 -1.7em">
<li>A green square displays in the upper right corner of the interface, indicating that
the test plan is running. Adjacent to the square is a ratio listing the number of
active threads against the total number of threads being tested. For example,
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/jmeter-active-threads.png"
class="b-all" style="margin:2px 0 -2px 0" alt="Green square with number of active threads"> demonstrates that
the test is running, and that there are currently 15 active threads of a total of 20.
Because of the ramp-up period, you should notice that the number of active threads
increases each second to 20, remains at 20 for some time, then gradually decreases
to zero, at which the square becomes gray indicating that the test has terminated.</li>
<li>You can filter the graphs you wish to display by selecting the checkboxes above the
graph. For an explanation of Median and Deviation, refer to the
<a href="http://jakarta.apache.org/jmeter/usermanual/glossary.html" target="_blank">JMeter
User's Manual Glossary</a>. The image below displays graphs for Average and Throughput
only. The metric values provided at the bottom of the graph apply to the most recent sample.</li>
<li>From the green line designating throughput, we see that the server was able to maintain
a nearly consistent value as the load increased to 20 users. Toward the end of the test,
as user number decreases, we see that the throughput slightly lessens. We can assume
that this is simply due to the fact that there are fewer requests per unit of time.</li>
<li>While the vertical line of the graph represents time (in milliseconds), this doesn't
apply to the throughput measurement (nor the measurement for standard deviation, for
that matter). The throughput represents the number of requests the server processes
during the total time which the test plan runs. In the image below, note that the
throughput value listed at the bottom of the graph is: <code>577.496/minute</code>.
Switching to the Summary Report, the total throughput value is listed as:
<code>9.6/second</code>. The two values equate: <code>577.496/60 = 9.6</code>.</li>
<li>The blue line, designating the average time (in milliseconds), increases dramatically
at the end of the test. If you examine the final request samples in the View Results
Tree, you can get an idea why. The final samples taken are all <code>/checkout</code>
and <code>/purchase</code> requests, which as we've already seen, take much longer than
the other requests in the test plan.</li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/graph-results.png"
class="margin-around b-all" alt="JMeter - Graph Results" style="width:688px"
title="Graph Results shows a graph that plots all sample times">
</li>
</ol>
<h3 id="stressTest">Stress Testing</h3>
<p>In the tests we've so far conducted, the throughput for a single user was calculated at 41/min,
and for 20 users it was 577/min. You can continue to increase the demand on the server to see
if it's possible to determine what the maximum throughput value can be, given your local setup.
This is an example of <a href="http://en.wikipedia.org/wiki/Stress_testing" target="_blank">stress
testing</a>, in which the system resources are purposely worked to their limits in order to
arrive at a maximum capacity value.</p>
<p>You can adjust the User Defined Variables, then run the test plan and examine the results.
For example, experiment by increasing the number of users, or decreasing the ramp-up period
or delay between requests.</p>
<p class="alert"><strong>Important:</strong> When stress testing, you should monitor your computer's
CPU and memory levels. If you see that JMeter is not able to record results under a specific
load and becomes unresponsive, you can try to stop the test by choosing Run &gt; Stop (Ctrl-.;
&#8984;-. on Mac). Otherwise, if JMeter does not respond, you may need to kill the JMeter
process from your computer's task manager.</p>
<p>The following table lists results recorded in JMeter's
<a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#Summary_Report"
target="_blank">Summary Report</a>, from increasing the number of users with each test run.</p>
<table>
<tr>
<td style="vertical-align:top">
<table class="margin-around" style="width:350px">
<tbody>
<tr>
<th class="tblheader" scope="col">Users</th>
<th class="tblheader" scope="col">Ramp-up<br><small>(seconds)</small</th>
<th class="tblheader" scope="col">Average<br><small>(milliseconds)</small></th>
<th class="tblheader" scope="col">Throughput</th>
<th class="tblheader" scope="col">Error&nbsp;%</th>
</tr>
<tr>
<td class="tbltd1">1</td>
<td class="tbltd1">(n/a)</td>
<td class="tbltd1">11</td>
<td class="tbltd1">41/min</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">20</td>
<td class="tbltd1">20</td>
<td class="tbltd1">9</td>
<td class="tbltd1">577/min</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">50</td>
<td class="tbltd1">25</td>
<td class="tbltd1">8</td>
<td class="tbltd1">22.2/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">80</td>
<td class="tbltd1">25</td>
<td class="tbltd1">8</td>
<td class="tbltd1">35.3/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">100</td>
<td class="tbltd1">25</td>
<td class="tbltd1">7</td>
<td class="tbltd1">44.1/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">120</td>
<td class="tbltd1">25</td>
<td class="tbltd1">7</td>
<td class="tbltd1">52.9/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">150</td>
<td class="tbltd1">25</td>
<td class="tbltd1">7</td>
<td class="tbltd1">66.0/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">200</td>
<td class="tbltd1">25</td>
<td class="tbltd1">11</td>
<td class="tbltd1">87.5/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">250</td>
<td class="tbltd1">25</td>
<td class="tbltd1">16</td>
<td class="tbltd1">109.5/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">300</td>
<td class="tbltd1">25</td>
<td class="tbltd1">35</td>
<td class="tbltd1">130.1/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">350</td>
<td class="tbltd1">25</td>
<td class="tbltd1">54</td>
<td class="tbltd1">150.4/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">400</td>
<td class="tbltd1">25</td>
<td class="tbltd1">120</td>
<td class="tbltd1">164.3/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">450</td>
<td class="tbltd1">25</td>
<td class="tbltd1">394</td>
<td class="tbltd1">158.4/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">500</td>
<td class="tbltd1">25</td>
<td class="tbltd1">355</td>
<td class="tbltd1">182.9/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">550</td>
<td class="tbltd1">25</td>
<td class="tbltd1">369</td>
<td class="tbltd1">198.4/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">600</td>
<td class="tbltd1">25</td>
<td class="tbltd1">446</td>
<td class="tbltd1">206.4/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">650</td>
<td class="tbltd1">25</td>
<td class="tbltd1">492</td>
<td class="tbltd1">219.9/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">700</td>
<td class="tbltd1">25</td>
<td class="tbltd1">599</td>
<td class="tbltd1">225.9/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">750</td>
<td class="tbltd1">25</td>
<td class="tbltd1">668</td>
<td class="tbltd1">231.9/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">800</td>
<td class="tbltd1">25</td>
<td class="tbltd1">875</td>
<td class="tbltd1">225.6/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">850</td>
<td class="tbltd1">25</td>
<td class="tbltd1">976</td>
<td class="tbltd1">230.5/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">900</td>
<td class="tbltd1">25</td>
<td class="tbltd1">1258</td>
<td class="tbltd1">220.9/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">950</td>
<td class="tbltd1">25</td>
<td class="tbltd1">1474</td>
<td class="tbltd1">215.8/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
<tr>
<td class="tbltd1">1000</td>
<td class="tbltd1">25</td>
<td class="tbltd1">1966</td>
<td class="tbltd1">190.8/sec</td>
<td class="tbltd1">0.00%</td>
</tr>
</tbody>
</table>
</td>
<td class="valign-top">
<p style="margin: 20px 0 0 5px"><strong>Notes and observations:</strong></p>
<ul style="margin: 5px 0 0 -.7em">
<li>Maximum throughput was recorded at 231.9/sec for 750 users. Throughput
is generally much quicker for requests in the first part of the test
plan, and then decreases as <code>/checkout</code> and <code>/purchase</code>
requests are served. Because the elapsed time for these requests begins
to dramatically increase beyond 750 users, the overall throughput begins
to decrease beyond this number.</li>
<li>When testing for 500 users, JMeter became unresponsive and it was necessary
to shut it down from the task manager. It is likely that JMeter was running
out of memory to record and display results for the
<a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#Graph_Results"
target="_blank">Graph Results</a> and
<a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#View_Results_Tree"
target="_blank">View Results Tree</a> listeners. These two listeners were
removed from the test plan, and results for 500 - 1000 users were then recorded
using the <a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#Summary_Report"
target="_blank">Summary Report</a> listener only.</li>
<li>In all tests, the <code>Error</code> <code>%</code> column remained at
<code>0.00%</code>. The server was able to successfully respond to all
requests, even when the computer's CPU levels were at a maximum, and JMeter
was lagging in its ability to display results. This would indicate that the
bottleneck in these tests was the computer's processing resources. (The
computer had available memory for all tests.)</li>
<li>The Average represents the average elapsed time (in milliseconds)
for all requests serviced in the test plan. While the average values
for the most demanding tests were still under 2 seconds, the Summary
Report's Maximum values recorded for elapsed time were much higher,
reaching nearly 70 seconds for the <code>/purchase</code> request.
When determining what resources are required for a normal load, consider
that these results do not include network time, and that most users
are willing to wait at most 4 - 8 seconds for a
response.<sup><a href="#footnote2TestProfile" id="2TestProfile"
style="text-decoration:none">[2]</a></sup>
</li>
</ul>
</td>
</tr>
</table>
<p style="margin-top: 0">If the production server is on a machine that has resources similar
to those of your development environment, and assuming your computer is not running other
CPU-intensive processes while tests are conducted, you can get a rough idea of how many
users can be served by examining your computer's CPU usage during tests. For example, if
it has been decided that CPU levels for normal and peak loads will be approximately 30%
and 70%, respectively, you can watch the CPU monitor as you increase the number of users
with each run of the test plan. The following images suggest 150 users could be served
during a normal load, and 400 during a peak load.</p>
<table>
<tr>
<td><strong>CPU levels for 150 users</strong></td>
<td><strong>CPU levels for 400 users</strong></td>
</tr>
<tr>
<td>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/150-users.png"
alt="CPU graph for 150 users" class="margin-around b-all"
title="CPU levels when running the test with 150 users"></td>
<td>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/400-users.png"
alt="CPU graph for 400 users" class="margin-around b-all"
title="CPU levels when running the test with 400 users"></td>
</tr>
</table>
<p>Keep in mind that when running tests in this manner, your local server is
competing with JMeter for the computer's resources. Eventually, you'll want
to test your production server remotely to get more accurate results. See the
following resources for more information:</p>
<ul style="margin: 0 0 0 -1.7em">
<li><a href="http://jakarta.apache.org/jmeter/usermanual/remote-test.html"
target="_blank">JMeter User's Manual: 15. Remote Testing</a></li>
<li><a href="http://jakarta.apache.org/jmeter/usermanual/jmeter_distributed_testing_step_by_step.pdf"
target="_blank">JMeter Distributed Testing Step-by-Step</a> [pdf]</li>
</ul>
</div>
<br>
<h2 id="profile">Using the NetBeans Profiler</h2>
<p>The NetBeans Profiler is an
<a href="http://www.developer.com/java/other/article.php/3795991/Winners-of-the-Developercom-Product-of-the-Year-2009-Are-Announced.htm"
target="_blank">award winning</a> development utility that enables you to profile
and monitor your application's CPU and memory usage, and thread status. The Profiler
is an integral component of the IDE, and offers a click-of-the-button profiling environment
that aids you when handling memory and performance-related issues. For an overview of
the Profiler's features, see
<a href="../../../../features/java/profiler.html" target="_blank">NetBeans IDE 6.9
Features: Profiler</a>.</p>
<p>When profiling web applications, you can use the Profiler to work in tandem with a load
script, such as a test plan created in JMeter. Often, problems start to arise only after
your application has been running in a host environment for a certain period of time, and
has begun serving multiple concurrent requests. In order to get an idea of how the application
will perform before it is migrated to a production environment, you can launch the Profiler,
run a test script on the application, and examine the results in the Profiler's interface.</p>
<ul>
<li><a href="#memoryLeaks">About Memory Leaks</a></li>
<li><a href="#monitoring">Monitoring your Application</a></li>
<li><a href="#heapWalker">Evaluating Heap Contents with the HeapWalker</a></li>
</ul>
<div class="indent">
<h3 id="memoryLeaks">About Memory Leaks</h3>
<p>In Java, memory leaks occur when objects continue to be referenced even after they are no
longer needed. This prevents Java's built-in garbage collection mechanism from destroying
these objects, and consequently they remain in existence throughout the life of your
application. When these objects are regularly created, the Java Virtual Machine (JVM) <em>heap</em>
will continue to grow over time, ultimately resulting in an <code>OutOfMemoryError</code>
when the heap is eventually exhausted.</p>
<p>The JVM heap represents memory that is dynamically allocated by the Virtual Machine during
runtime. Because the GlassFish server runs on Java, it relies on the JVM heap for memory
resources during execution. All applications that are deployed to the server can be perceived
as extensions to this rule; in other words when your web application runs, it consumes
resources from the JVM heap.</p>
<p>When building web applications, you need to be mindful of memory allocation. Aside from
avoiding memory leaks in your code, you must ensure that the JVM heap is large enough to
accommodate all user sessions at a given time, and that your system is able to support the
maximum heap size set by your server.</p>
<h3 id="monitoring">Monitoring your Application</h3>
<p>The following example aims to familiarize you with the Profiler's interface, and demonstrates
how you can utilize its functionality to ensure that the <code>AffableBean</code> application
will continue to perform efficiently after it has been serving client requests for some time.
In this example, you download and add a new JMeter test plan,
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FuseCaseTestRandom.jmx"><code>useCaseTestRandom.jmx</code></a>,
to the project. The new test plan is an advanced version of the one you created earlier
in this unit. It makes use of JMeter's conditional and random controllers to adapt a slightly
more realistic simulation of the tutorial's use-case.</p>
<p>Consider that only a small fraction of visits to an e-commerce site will result in a completed
order. If you recall from units 8 and 9, <a href="#manage-sessions">Managing Sessions</a>
and <a href="#transaction">Integrating Transactional Business Logic</a>, the application
terminates the user session upon a successfully completed order. In other words, with each
completed order, the server is able to free up any resources that were previously tied to the
session. Now, consider the far more common scenario of a user not completing an order, but
simply navigating away from the site. Based on the session time-out which you specified in the
application's web deployment descriptor, the server will need to wait a period of time before
it can free any resources tied to the session. The new load script, <code>useCaseTestRandom.jmx</code>,
is configured so that on average one in ten user threads completes an order. Our goal by running
this load script is to determine whether the application's host environment (i.e., the GlassFish
server running locally on your computer) has enough memory capacity to provide continuous, fast
service for an extended period of time.</p>
<p class="notes"><strong>Note:</strong> Recall that in
<a href="manage-sessions.html#time-out">Managing Sessions: Handling Session Time-Outs</a>,
you set the <code>AffableBean</code> session time-out to 10 minutes.</p>
<ol>
<li>Download
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FuseCaseTestRandom.jmx"><code>useCaseTestRandom.jmx</code></a>
and add it to the <code>AffableBean</code> project. To add it to the project, copy it from
your computer's file system (Ctrl-C; &#8984;-C on Mac), then in the IDE, open the Files
window (Ctrl-2; &#8984;-2 on Mac), right-click the <code>jmeter</code> folder and choose
Paste.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/files-window.png"
alt="JMeter test plans displayed in Files window" class="margin-around b-all"
title="JMeter test plans contained in 'jmeter' folder within project">
<br>
<p class="notes"><strong>NetBeans 6.8 note:</strong> The <code>useCaseTestRandom.jmx</code>
script is not compatible with the JMeter Kit plugin for NetBeans 6.8. Because the script
utilizes various logic controllers which unfortunately are not available in JMeter
version 2.2, it will not run on the JMeter implementation in NetBeans 6.8. In order to
become familiar with the Profiler, use <code>useCaseTest.jmx</code> in this exercise
instead. If you use <code>useCaseTest.jmx</code>, you need to set the load script to
run continuously. To do so, open the script in JMeter, select the <code>AffableBeanUsers</code>
thread group, then in the main panel, select the 'Forever' checkbox for the Loop Count
field.</p></li>
<li>If you are running the Profiler for the first time, you need to perform a calibration step
on the JDK. To do so, choose Profile &gt; Advanced Commands &gt; Run Profiler Calibration.
For more information, refer to the NetBeans User FAQ wiki:
<a href="http://wiki.netbeans.org/FaqProfilerCalibration" target="_blank">What exactly does
the Profiler Calibration mean?</a>.</li>
<li>Click the Profile Project ( <img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/profile-btn.png"
alt="Profile Project button"> ) button. When a project is profiled for the first time, its
build script must be modified to enable profiling. The IDE warns you that it will modify the
project's build script.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/enable-profiling.png"
alt="Profiler dialog box warning that build script will be modified" class="margin-around b-all"
title="The project build script must be modified to enable profiling">
<p class="notes"><strong>Note:</strong> You can undo this action at a later point by choosing
Profile &gt; Advanced Commands &gt; Unintegrate Profiler from the main menu. Alternatively,
you can switch to the Files window, delete your project's <code>build.xml</code> file, then
rename the <code>build-before-profiler.xml</code> file to <code>build.xml</code>.</p></li>
<li>Click OK. The project's build file is modified, and the Profiler window opens for the project.
The window enables you to select from one of three profiling tasks:
<ul style="margin: 7px 0 0 -1.7em">
<li><strong>Monitor Application:</strong> Provides obtain high-level information about
properties of the target JVM, including thread activity and memory allocations.</li>
<li><strong>Analyze Performance:</strong> Provides detailed data on application performance, including
the time to execute methods and the number of times the method is invoked.</li>
<li><strong>Analyze Memory:</strong> Provides detailed data on object allocation and garbage
collection.</li>
</ul>
<li>Click the Monitor button in the left column. Select the 'LoadGenerator Script' option, then choose
<code>useTestCaseRandom.jmx</code> from the drop-down list.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/monitor-application.png"
alt="Profiler window - Monitor Application" class="margin-around b-all" id="profilerWindow"
title="Profiler window opens, enabling task selection and configuration"></li>
<li>Click Run. The IDE takes the following actions:
<ul style="margin: 7px 0 0 -1.7em">
<li>Starts the GlassFish server in profile mode. (If the server is already running, it is first stopped.)</li>
<li>Deploys the web application to GlassFish.</li>
<li>Starts a profiling session, attaches the profiler to the server, and opens the Profiler Control Panel in the IDE.</li>
<li>Runs the associated load script (<code>useTestCaseRandom.jmx</code>).</li>
</ul>
<p class="notes"><strong>Note:</strong> If the profiler does not run the load script after starting
the application in profile mode, you can invoke it yourself. From the Projects window, right-click
the script and choose External Edit. Then, in JMeter, press Ctrl-R (&#8984;-R on Mac) to run the
script. If the left-hand graph displayed by the VM Telemetry Overview depicts the purple area as
remaining horizontal (shown below), you can be fairly certain that the load script is not running.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/vm-telemetry-overview-heap.png"
alt="VM Telemetry Overview - JVM Heap" class="margin-around b-all" style="margin:0 0 0 35px"
title="The server is loaded, but the load script is not running"></li>
<li>In the Profiler Control Panel, click the Threads (
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/threads-btn.png"
alt="VM Telemetry button"> ) button. The Threads window opens to display all threads
maintained by the server while the application is running. You can select Live Threads Only,
or Finished Threads Only in drop-down at the top of the window in order to filter the display
according to live or finished threads.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/live-threads.png"
alt="Threads window" class="margin-around b-all" style="width:688px"
title="View live threads maintained by the server at runtime">
<p class="tips">You can select the Enable Threads Monitoring option in the Profiler window
(displayed <a href="#profilerWindow">above</a>). This will trigger the Threads window to
open by default when running the Profiler.</p></li>
<li>In the Profiler Control Panel, click the VM Telemetry (
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/vm-telemetry-btn.png"
alt="VM Telemetry button"> ) button.
<br><br>
Similar to the VM Telemetry Overview, the VM Telemetry window provides views on the
JVM heap, garbage collection (GC), as well as threads and loaded classes.</li>
<li>Ensure that the Memory (Heap) tab is selected at the bottom of the window, then allow the
Profiler to monitor the heap while the load script runs against the application.
<br><br>
You can hover your cursor over the graph to view real-time measurements of the heap size versus the used heap.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/heap-popup.png"
alt="Popup displaying heap measurements in the Memory (Heap) tab of the VM Telemetry window"
class="margin-around b-all"
title="Hover your cursor over the graph for a real-time display of heap measurements">
<p class="tips">Click the Scale to Fit (
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/scale-to-fit-btn.png"
alt="Scale to Fit button"> ) button above the graph to maintain a continuous view of the entire
monitoring session.</p>
<br>
The image below shows the state of the heap after monitoring the server for approximately
three hours while running the <code>useTestCaseRandom.jmx</code> script continuously with
150 simultaneous users. The <code>AffableBean</code> application running on the GlassFish
server uses under 175 MB of the JVM heap.
<a href="../../../../images_www/articles/73/javaee/ecommerce/test-profile/heap-monitor.png" rel="lytebox"
title="The profiler monitors the JVM heap while the JMeter load script runs continuously against the application"
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/heap-monitor.png"
alt="VM Telemetry - Memory (Heap)" class="margin-around b-all" style="width: 688px"
title="Click to enlarge" id="vmTelemetryMonitor"></a>
</li>
</ol>
<h3 id="heapWalker">Evaluating Heap Contents with the HeapWalker</h3>
<p>The HeapWalker is a tool that is built into the NetBeans Profiler, which allows you to examine
JVM heap contents. You can use it to browse classes and instances of classes on the heap, fields
of each instance or class, and references to each instance.</p>
<p>The HeapWalker is particularly useful when locating the cause of memory leaks in your code. You can
set the Profiler to automatically take a heap dump if an <code>OutOfMemoryError</code> occurs
when you are profiling an application. You can then use the HeapWalker to inspect the heap dump
and determine which objects were consuming the most memory.</p>
<p>This functionality is enabled by default, but you can view and modify Profiler settings from
the IDE's Options window (Tools &gt; Options; NetBeans &gt; Preferences on Mac). From the Options
window, select Miscellaneous, then select the Profiler tab. In the On OutOfMemoryError field,
note that 'Save heap dump to profiled project' option is selected.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/profiler-options.png"
alt="Options window - Profiler options" class="margin-around b-all" style="margin-top:0"
title="A heap dump is taken by default if the JVM runs out of memory for the profiled application">
<p>For example, if the GlassFish server utilizes 512 MB of memory, and the JVM attempts to allocate
more than 512 MB of memory to the JVM heap (represented by the pink area in the heap size graph
of the VM Telemetry monitor, <a href="#vmTelemetryMonitor">shown above</a>), an <code>OutOfMemoryError</code>
will occur, and the IDE will ask you if you would like to view the heap in the HeapWalker.</p>
<p>To take a heap dump while your application is being profiled, choose Profile &gt; Take Heap Dump
from the main menu.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/take-heap-dump.png"
alt="Profiler menu" class="margin-around b-all" style="margin-top:0"
title="To take a heap dump, choose Profile > Take Heap Dump from the main menu">
<p>The following example depicts a heap dump from running the <code>useCaseTestRandom.jmx</code>
script at 500 users, ramp-up period at 100 seconds, and with a loop count of 5. The HeapWalker's
Summary provides an Inspect panel which enables you to locate the largest objects in the heap.
Specify the number of objects you want to search for, then click Find.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/inspect-heap.png"
alt="HeapWalker - Summary - Inspect panel" class="margin-around b-all" style="margin-top:0"
title="Use the Inspect panel to determine the largest objects in the heap">
<p>In the above image, you can see that for the <code>AffableBean</code> application, the largest
object in the heap dump is an instance of the <code>org.apache.catalina.session.StandardManager</code>
class, with a retained size of nearly 79 MB.</p>
<p>Clicking the object name enables you to open the Instances view on the object. When you do so,
you can see the instances of the class that exist on the heap (left column), the fields contained
in the class, and their values (right column, top), and other objects on the heap referring
to the instance (right column, bottom).</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/instances-view.png"
alt="HeapWalker - Instances view" class="margin-around b-all" style="width:728px; margin-top:0"
title="Use the Instances view to examine class instances, their fields and references">
<p>In the above image, it appears that 706 <code>StandardSession</code> objects were active on
the heap, a result of the load script simulating multiple user sessions. The server must have
sufficient memory resources to maintain session objects during periods of high traffic.</p>
<p>You can save (Ctrl-S; &#8984;-S on Mac) heap dumps. When you do so, they become listed in the
Profiler Control Panel under Saved Snapshots.</p>
<img src="../../../../images_www/articles/73/javaee/ecommerce/test-profile/saved-snapshots.png"
alt="Profiler Control Panel - Saved Snapshots" class="margin-around b-all" style="margin-top:0"
title="Saved heap dumps can be loaded from the Profiler Control Panel">
</div>
<br>
<h2 id="glassFishTune">Tuning the GlassFish Server</h2>
<p>In order to gain optimum performance for your application when it is deployed to GlassFish,
you should become acquainted with various tuning parameters which can be adjusted from the
Administration Console. The following tips are taken directly from the white paper,
<a href="https://www.sun.com/offers/details/OptimizeGlassFishPerformance.xml" target="_blank">Optimize
GlassFish Performance in a Production Environment</a>. Although the paper focuses on GlassFish
v2, the tuning tips can be directly applied to GlassFish v3 or Open Source Edition 3.0.1.</p>
<p class="tips">There are various mapping changes that occurred between GlassFish v2 and v3. Tables
listing changes are provided on the GlassFish wiki: <a href="http://wikis.sun.com/display/GlassFish/GrizzlyConfigOnePager"
target="_blank">GrizzlyConfig One Pager</a>.</p>
<p>The GlassFish Administration Console can be accessed from the IDE's Services window:</p>
<ol style="margin-top:0">
<li>Open the Services window (Ctrl-5; &#8984;-5 on Mac) and expand the Servers node
so that the GlassFish server node is visible.</li>
<li>Ensure that the GlassFish server is running. If the server is running, a small green
arrow is displayed next to the GlassFish icon (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/gf-server-running-node.png"
alt="GlassFish server node in Services window"> ). If you need to start it, right-click
the server node and choose Start.</li>
<li>Right-click the GlassFish server node and choose View Admin Console. The login form
for the GlassFish Administration Console opens in a browser.</li>
<li>Log into the Administration Console by typing <code>admin</code> / <code>adminadmin</code>
for the username / password.</li>
</ol>
<p>From the GlassFish Administration Console, you can view and make adjustments to the following
parameters.</p>
<ul>
<li><a href="#tip3">Tip 3: Java Heap Size</a></li>
<li><a href="#tip6">Tip 6: HTTP Request Processing Threads</a></li>
<li><a href="#tip10">Tip 10: JDBC Tuning</a></li>
</ul>
<div class="indent">
<h3 id="tip3">Tip 3: Java Heap Size</h3>
<p>From <a href="https://www.sun.com/offers/details/OptimizeGlassFishPerformance.xml" target="_blank">Optimize
GlassFish Performance in a Production Environment</a>:</p>
<blockquote style="margin-top: 0">
<em>The size of the heap is determined by the Java options -Xmx (maximum) and -Xms
(minimum). While a larger heap can contain more objects and reduce the frequency
of garbage collection, it may result in longer garbage collection times especially
for a full GC cycle. The recommendation is to tune the heap based on the size of
total available memory in your system, process data model (32-bit or 64-bit) and
operating system.</em>
</blockquote>
<ol>
<li>In the Tree which displays in the left column of the Administration Console,
expand the Configuration node, then click JVM Settings.</li>
<li>In the main panel, select the JVM Options tab.</li>
<li>Scroll the list of options and note the <code>-Xmx</code> option:
<pre class="examplecode">-Xmx512m</pre>
The GlassFish server (v3 and Open Source Edition 3.0.1) sets the heap to 512 MB
by default. If you wanted to increase the heap size to 1 GB, you would enter
'<code>-Xmx1024m</code>', click the Save button in the upper right corner, and
then restart the server.</li>
</ol>
<h3 id="tip6">Tip 6: HTTP Request Processing Threads</h3>
<p>From the <a href="http://docs.sun.com/app/docs/doc/819-3681/abefm" target="_blank">Sun Java
System Application Server 9.1 Performance Tuning Guide</a>:</p>
<blockquote style="margin-top: 0">
<em>The</em> [Max Thread Pool Size] <em>parameter specifies the maximum number of
simultaneous requests the server can handle. The default value is 5. When the server
has reached the limit or request threads, it defers processing new requests until the
number of active requests drops below the maximum amount. Increasing this value will
reduce HTTP response latency times.
<br><br>
In practice, clients frequently connect to the server and then do not complete their
requests. In these cases, the server waits a length of time specified by the Idle Thread
Timeout parameter.</em> [900 seconds, i.e., 15 minutes, is the default entry for GlassFish
v3 and Open Source Edition 3.0.1.]
<br><br>
<em>Also, some sites do heavyweight transactions that take minutes to complete. Both of
these factors add to the maximum simultaneous requests that are required. If your site
is processing many requests that take many seconds, you might need to increase the number
of maximum simultaneous requests.
<br><br>
Adjust the thread count value based on your load and the length of time for an average
request. In general, increase this number if you have idle CPU time and requests that are
pending; decrease it if the CPU becomes overloaded. If you have many HTTP 1.0 clients
(or HTTP 1.1 clients that disconnect frequently), adjust the timeout value to reduce the
time a connection is kept open.
<br><br>
Suitable Request Thread Count values range from 100 to 500, depending on the load. If your
system has extra CPU cycles, keep incrementally increasing thread count and monitor performance
after each incremental increase. When performance saturates (stops improving), then stop
increasing thread count.</em>
</blockquote>
<ol>
<li>In the Administration Console Tree, expand the Configuration node, then click
Thread Pools.
<br><br>
The GlassFish server provides two thread pools by default. The <code>http-thread-pool</code>
thread pool is configured for use by network listeners, while <code>thread-pool-1</code> is
configured for use by the ORB (object request broker) for RMI/IIOP requests.
(A stand-alone web application deployed over a non-distributed environment, such
as the <code>AffableBean</code> application, relies on the <code>http-thread-pool</code>
by default.)</li>
<li>Under the Thread Pool ID column, click <code>http-thread-pool</code>.</li>
<li>In the <strong>Max Thread Pool Size</strong> field, adjust the maximum number of threads
available to the thread pool.</li>
<li>Click the Save button in the upper right corner, and then restart the server.</li>
</ol>
<h3 id="tip10">Tip 10: JDBC Tuning</h3>
<p>From <a href="https://www.sun.com/offers/details/OptimizeGlassFishPerformance.xml" target="_blank">Optimize
GlassFish Performance in a Production Environment</a>:</p>
<blockquote style="margin-top: 0">
<em>If your application uses Java DataBase Connectivity (JDBC) software for database access,
it may be beneficial to tune your database connection pool. A general rule of thumb is to
tune the value for <code>max-pool-size</code> and <code>steady-pool-size</code> to the
same number of HTTP request processing threads. If your JDBC driver supports this
feature, it is advisable to use JDBC drivers that use statement caching to re-use
prepared statements.</em>
</blockquote>
<ol>
<li>In the Administration Console Tree, expand the Resources &gt; JDBC &gt; Connection Pools node,
then click the <code>AffableBeanPool</code> node.</li>
<li>In the General tab under Pool Settings, specify values for the following fields:
<ul style="margin: 7px 0 0 -1.7em">
<li><strong>Initial and Minimum Pool Size:</strong> (<code>steady-pool-size</code>)
Minimum and initial number of connections maintained in the pool.</li>
<li><strong>Maximum Pool Size:</strong> (<code>max-pool-size</code>)
Maximum number of connections that can be created to satisfy client requests.</li>
<li><strong>Pool Resize Quantity:</strong> (<code>pool-resize-quantity</code>)
Number of connections to be removed when pool idle timeout expires.</li>
<li><strong>Idle Timeout:</strong> (<code>idle-timeout-in-seconds</code>)
Maximum time that connection can remain idle in the pool.</li>
<li><strong>Max Wait Time:</strong> (<code>max-wait-time-in-millis</code>)
Amount of time caller waits before connection timeout is sent.</li>
</ul></li>
<li>Click the Save button in the upper right corner, and then restart the server.</li>
</ol>
<p class="tips">Connection pool settings can also be specified in the <code>sun-resources.xml</code> descriptor:</p>
<pre class="examplecode" style="margin-top:0; margin-left:35px; width:685px">
&lt;jdbc-connection-pool <strong>max-pool-size</strong>=&quot;32&quot;
<strong>steady-pool-size</strong>=&quot;8&quot;
<strong>pool-resize-quantity</strong>=&quot;2&quot;
<strong>idle-timeout-in-seconds</strong>=&quot;300&quot;
<strong>max-wait-time-in-millis</strong>=&quot;60000&quot;&gt;
...
&lt;/jdbc-connection-pool&gt;</pre></div>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans E-commerce Tutorial - Testing and Profiling">Send
Us Your Feedback</a></div>
<br style="clear:both;">
<br>
<h2 id="seeAlsoTestProfile">See Also</h2>
<div class="indent">
<h3>NetBeans Resources</h3>
<ul>
<li><a href="http://profiler.netbeans.org/" target="_blank">NetBeans Profiler</a> [product page]</li>
<li><a href="../../../../features/java/profiler.html" target="_blank">NetBeans Profiler Features</a></li>
<li><a href="../../java/profiler-profilingpoints.html" target="_blank">Using Profiling Points</a></li>
<li><a href="http://profiler.netbeans.org/docs/help/6.0/heapwalker.html" target="_blank">Using HeapWalker</a></li>
<li><a href="http://wiki.netbeans.org/HeapWalkerDemo" target="_blank">HeapWalker Demo</a></li>
<li><a href="../../java/profile-loadgenerator.html" target="_blank">Using a Load Generator</a></li>
<li><a href="../profiler-javaee.html" target="_blank">Profiling an Enterprise Application</a></li>
<li><a href="../../java/profiler-intro.html" target="_blank">Introduction to Profiling Java Applications</a></li>
<li><a href="../../../articles/nb-profiler-uncoveringleaks_pt1.html" target="_blank">Uncovering Memory Leaks Using NetBeans Profiler</a></li>
<li><a href="../../../../community/magazine/html/04/profiler.html" target="_blank">Advanced Profiling: Theory in Practice with NetBeans</a></li>
<li><a href="https://netbeans.org/download/magazine/01/nb01_profiler.pdf" target="_blank">Exploring the NetBeans Profiler</a> [pdf]</li>
<li><a href="https://channelsun.sun.com/media/show/14757?n=playlist&nid=81" target="_blank">The New NetBeans IDE 6 Profiler</a> [screencast]</li>
<li><a href="https://netbeans.org/project_downloads/www/flashdemo/profiler-demo1.swf" target="_blank">Getting Started with NetBeans Profiler 5.0</a> [screencast]</li>
<li><a href="https://netbeans.org/project_downloads/www/flashdemo/profiler-demo2.swf" target="_blank">Performance Profiling with NetBeans Profiler 5.0</a> [screencast]</li>
<li><a href="http://www.javapassion.com/handsonlabs/javatestjmeter/index.html" target="_blank">JavaPassion LAB 5116: Finding Memory Leaks Using the NetBeans Profiler</a></li>
</ul>
<h3>JMeter</h3>
<ul>
<li><a href="http://jakarta.apache.org/jmeter/" target="_blank">Apache JMeter</a> [product homepage]</li>
<li><a href="http://jakarta.apache.org/jmeter/usermanual/index.html" target="_blank">Apache JMeter: User's Manual</a></li>
<li><a href="http://jakarta.apache.org/jmeter/usermanual/jmeter_distributed_testing_step_by_step.pdf" target="_blank">jMeter Distributed Testing</a> [pdf]</li>
<li><a href="http://www.javapassion.com/handsonlabs/javatestjmeter/index.html" target="_blank">JavaPassion LAB 1077: JMeter Load Testing</a></li>
<li><a href="http://vimeo.com/3453772" target="_blank">Apache JMeter Getting Started Tutorial</a> [screencast]</li>
<li><a href="https://www.packtpub.com/beginning-apache-jmeter/book" target="_blank">Apache JMeter</a> [book]</li>
</ul>
<h3>GlassFish Performance</h3>
<ul>
<li><a href="http://java.sun.com/performance/reference/whitepapers/tuning.html" target="_blank">Java Tuning White Paper</a></li>
<li><a href="http://www.google.co.uk/url?sa=t&source=web&cd=3&ved=0CCMQFjAC&url=http%3A%2F%2Fdeveloper.connectopensource.org%2Fdownload%2Fattachments%2F29851654%2FGlassFishDay2008PerfPreso.pdf&rct=j&q=Tuning%20GlassFish%20Performance%20Tips%20Deep%20Singh&ei=ru7WTNjUPIWUjAenyZTHCQ&usg=AFQjCNHLz1wnaG7h-ey6wsPOOIxV-xoDzA&sig2=aNoCg9O132PgIQ0eWmHx6g&cad=rja">Tuning Your GlassFish - Performance Tips</a> [pdf]</li>
<li><a href="https://www.sun.com/offers/details/OptimizeGlassFishPerformance.xml" target="_blank">Optimize GlassFish Performance in a Production Environment</a> [pdf]</li>
<li><a href="http://dlc.sun.com/pdf/819-3681/819-3681.pdf" target="_blank">Sun Java System Application Server 9.1 Performance Tuning Guide</a> [pdf]</li>
</ul>
</div>
<br>
<h2>References</h2>
<ol>
<li id="footnote1TestProfile"><a href="#1TestProfile" style="text-decoration:none">^</a> Actually, in JMeter
version 2.4, using the HTTP Proxy Server to record HTTPS requests should be possible. See the JMeter User's
Manual, <a href="http://jakarta.apache.org/jmeter/usermanual/get-started.html#opt_ssl"
target="_blank">2.2.4 SSL Encryption</a> for more details.</li>
<li id="footnote2TestProfile"><a href="#2TestProfile" style="text-decoration:none">^</a> The acceptable response
time for retail web page response times is debatable, but general concensus seems to waver between 4 and 8
seconds. For example, see:
<ul style="margin: 7px 0 0 -0.7em">
<li><a href="http://answers.google.com/answers/threadview/id/716510.html" target="_blank">Google Answers: E-Commerce Site Speed Industry Standards</a></li>
<li><a href="http://www.conversionchronicles.com/The_Billion-Dollar_Question_-_What_is_the_Impact_of_Web_Site_Performance_on_E-commerce.html" target="_blank">Conversion Chronicles: What is the Impact of Web Site Performance on E-commerce?</a></li>
<li><a href="http://www.akamai.com/html/about/press/releases/2006/press_110606.html" target="_blank">Akamai and JupiterResearch Identify '4 Seconds' as the New Threshold of Acceptability for Retail Web Page Response Times</a></li>
<li><a href="http://www.websiteoptimization.com/speed/1/" target="_blank">Response Time: Eight Seconds, Plus or Minus Two</a></li>
</ul>
</li>
</ol>
<br><br><br><br>
<h1 id="conclusion">The NetBeans E-commerce Tutorial - Conclusion</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Tutorial Contents</h4>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#design">Designing the Application</a></li>
<li><a href="#setup-dev-environ">Setting up the Development Environment</a></li>
<li><a href="#data-model">Designing the Data Model</a></li>
<li><a href="#page-views-controller">Preparing the Page Views and Controller Servlet</a></li>
<li><a href="#connect-db">Connecting the Application to the Database</a></li>
<li><a href="#entity-session">Adding Entity Classes and Session Beans</a></li>
<li><a href="#manage-sessions">Managing Sessions</a></li>
<li><a href="#transaction">Integrating Transactional Business Logic</a></li>
<li><a href="#language">Adding Language Support</a></li>
<li><a href="#security">Securing the Application</a></li>
<li><a href="#test-profile">Testing and Profiling</a></li>
<li><strong>Conclusion</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#deliver">Delivering your Work</a></li>
<li><a href="#framework">Using the JavaServer Faces Framework</a></li>
<li><a href="#seeAlsoConclusion">See Also</a></li>
<li><a href="#about">About the NetBeans E-commerce Tutorial</a></li>
<li><a href="#acknowledge">Acknowledgments</a></li>
<li><a href="#disclaimer">Disclaimer</a></li>
</ul></li>
</ol>
</div>
</div>
<p><img src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" class="stamp"
alt="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"
title="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"></p>
<p>Congratulations! You have now finished developing the <code>AffableBean</code> application.
By following this tutorial, you incrementally built a simple e-commerce application using
Java-based technologies. In the process, you became familiar with the NetBeans IDE, and
have learned how to use it for the development of Java EE and web projects. Referring
back to the <a href="design.html#requirements">customer requirements</a>, you can
confirm that each requirement has been fully implemented, and through continuous feedback
from the Affable Bean staff, you are confident that they'll be satisfied with the
final product. At this stage however, you may ask, &quot;What specifically needs to
be delivered to the customer?&quot; and &quot;How can the application become deployed
to the customer's production server so that it functions online?&quot; This tutorial
unit briefly discusses next steps in terms of handing off deliverables, and concludes
with a discussion on how using a framework such as JavaServer Faces could improve the
application and benefit your experience when developing future projects.</p>
<p>You can view a live demo of the <code>AffableBean</code> application:
<a href="http://services.netbeans.org/AffableBean/" target="_blank">NetBeans E-commerce
Tutorial Demo Application</a>.</p>
<p>The completed <code>AffableBean</code> project is also
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_complete.zip">available
for download</a>.</p>
<br style="clear:left;">
<br>
<h2 id="deliver">Delivering your Work</h2>
<p>When delivering your work, you should prepare both a WAR (web archive) file, which is
a compiled, ready-to-deploy version of your project, and a source distribution, which
contains all the source files you created during the development phase.</p>
<ol style="margin-top:0">
<li><strong>WAR File Distribution:</strong> A WAR file is basically a compressed
collection of classes, files and other artifacts that constitute the web application.
You can create a WAR file for your project using the IDE. In the Projects window,
right-click your project node and choose Clean and Build. When your project is
built, a WAR file is generated and placed in a <code>dist</code> folder in your
project. You can verify this by examining your project in the Files window (Ctrl-2;
&#8984;-2 on Mac). (Refer back to <a href="setup-dev-environ.html#run">Setting up
the Development Environment</a>).</li>
<li><strong>Source Distribution:</strong> A package containing all source and configuration
files, typically in an archive file format (e.g., ZIP, TAR). You can use your NetBeans
project as part of your source distribution. Before compressing your project, make sure
to clean it (In the Projects window, right-click the project node and choose Clean) in
order to delete <code>build</code> and <code>dist</code> folders, if they exist. You
should also remove any of your environment-specific details included in the project.
To do so, navigate to the project on your computer's file system, then expand the
project's <code>nbproject</code> folder and delete the <code>private</code> folder
contained therein. (When the project is opened again in the IDE, the <code>private</code>
folder and its files are regenerated according to the current environment.)
<br><br>
As part of your source distribution, you would need to also provide any scripts or
artifacts that are necessary for setup, configuration, and population of the database.
In this scenario, that would include the MySQL Workbench project from Unit 4,
<a href="#data-model">Designing the Data Model</a>, the DDL script that creates
the <code>affablebean</code> database schema, and possibly a separate script that
populates the <code>category</code> and <code>product</code> tables with business
data.</li>
</ol>
<p>As was indicated in the tutorial <a href="design.html#scenario">Scenario</a>, a
&quot;technically-oriented staff member is able to deploy the application to the
production server once it is ready.&quot; Aside from necessary performance tuning
(GlassFish tuning is discussed in Unit 12 <a href="test-profile.html#glassFishTune">Testing
and Profiling</a>) the person responsible for this would need to ensure that the database
driver is accessible to the server (i.e., place the driver JAR file in the server's
library folder). He or she would also need to know the JNDI name of the data source used
by the application to interact with the database. This is found in the persistence unit
(<code>persistence.xml</code> file) and, as you may recall, is: <code>jdbc/affablebean</code>.
This is the only &quot;link&quot; between the application itself and the back-end database
server.</p>
<p class="notes"><strong>Note:</strong> Recall that the <code>sun-resources.xml</code> file,
which you created in Unit 6, <a href="connect-db.html#createConnPoolDataSource">Connecting
the Application to the Database</a> contains entries that instruct the GlassFish server
to create the JDBC resource and connection pool when the application is deployed. The
<code>sun-resources.xml</code> file is a deployment descriptor specific to the GlassFish
server only. Therefore, if the customer isn't using GlassFish as the production server,
the file should be deleted before the application is deployed. If the <code>sun-resources.xml</code>
file isn't removed from the WAR distribution however, it would simply be ignored by the
server it is deployed to.</p>
<p>In terms of security, it would be necessary to set up a <em>user</em> and <em>group</em>
on the production server, so that the server can authenticate persons wanting to log into
the administration console. Also, SSL support for the production server would need to be
enabled, and you would need to acquire a certificate signed by a trusted third-party Certificate
Authority (CA), such as <a href="http://www.verisign.com" target="_blank">VeriSign</a> or
<a href="http://www.thawte.com/" target="_blank">Thawte</a>.</p>
<p>Once the database is created and tables are populated with necessary data, the connection
pool and JDBC resource are set up on the production server, and security measures have
been taken, the application WAR file can be deployed to and launched on the production
server. Using GlassFish, it is possible to deploy your applications via the Administration
Console. (Select Applications in the left-hand Tree, then click the Deploy button to deploy
a new application.)</p>
<p class="tips">The GlassFish plugin support in NetBeans also enables you to connect to a
remote instance of GlassFish. You can therefore work with a GlassFish production server
from the IDE for monitoring, profiling, and debugging tasks. If you are interested in
using GlassFish as a production server, refer to the <a href="#seeAlso">See Also</a>
section below for a list of web hosting solutions.</p>
<p><em>Portability</em> is among the key benefits of Java EE. As your application adheres to
the technology specifications, it can theoretically be deployed to any server that supports
the same specifications. Recall that the <a href="intro.html#jcp">Introduction</a> lists
the specifications that you have used in this tutorial. All of these specifications are
part of the Java EE 6 platform specification (<a href="http://jcp.org/en/jsr/summary?id=316"
target="_blank">JSR 316</a>). Therefore, any server that is Java EE 6-compliant would be
a candidate for running the <code>AffableBean</code> application.</p>
<br>
<div class="feedback-box float-left" style="width: 683px;">
<h3>Did you know?</h3>
<p>The NetBeans IDE began as a student project (originally called Xelfi) at
Charles University in Prague, Czech Republic in 1996. The goal was to write
a Delphi-like Java IDE. Xelfi was the first Java IDE written in Java, with
its first pre-releases in 1997.</p>
<p>NetBeans was later purchased by Sun Microsystems in 1999, and shortly
thereafter became Sun's first sponsored open source project.</p>
<p>In June 2000, the initial netbeans.org website was launched. You can view
an archived version of the site at:
<a href="http://web.archive.org/web/20000815061212/https://netbeans.org/index.html"
target="_blank">http://web.archive.org/web/20000815061212/https://netbeans.org/index.html</a></p>
<p>For more information, see <a href="https://netbeans.org/about/history.html" target="_blank">A
Brief History of NetBeans</a>.</p>
</div>
<br style="clear:left"/>
<br>
<h2 id="framework">Using the JavaServer Faces Framework</h2>
<p>Having developed a Java web application from scratch puts you in a great position to
begin appreciating how a framework can benefit your work. This section briefly introduces
the JavaServer Faces (JSF) framework, then examines the advantages of applying the
framework to the <code>AffableBean</code> application.</p>
<ul>
<li><a href="#whatJSF">What is the JavaServer Faces Framework?</a></li>
<li><a href="#benefitJSF">How Can JSF Benefit Your Project?</a></li>
</ul>
<div class="indent">
<h3 id="whatJSF">What is the JavaServer Faces Framework?</h3>
<p>The JavaServer Faces framework (<a href="http://jcp.org/en/jsr/detail?id=314" target="_blank">JSR 314</a>)
is an integral part of the Java EE platform and aims to facilitate web development by
providing the following:</p>
<ul>
<li><strong>a user interface component model:</strong> JSF includes a standard component
API, which enables you to use and create custom UI components for your applications.
A <em>UI component</em> is a widget that has a specific appearance and guarantees
certain behavior. For example, this can be a simple text field that includes built-in
data validation and conversion with accompanying error messages, or it can be a complex
data table that interacts with a back-end data store and offers scrolling and column
sorting for users. Being able to reuse UI components for your application's interface
(or acquire custom components from third-party vendors) becomes increasingly important
as your application grows in size and complexity.</li>
<li><strong>an MVC development infrastructure:</strong> The framework provides a
<code>FacesServlet</code> which works behind the scenes to dispatch requests to their
appropriate handlers (usually <em>backing beans</em> that you create). You author page
views using Facelets, the default view handler technology for JSF 2.0. These features,
when operating in tandem with JSF's <em>request processing lifecycle</em> (described
below), encourage your work to adhere to the MVC paradigm.</li>
</ul>
<p>The JSF framework manages the request-response cycle by automating events that typically
need to occur for each client request. These events are qualified into six distinct
phases that are together known as the <em>JSF request processing lifecycle</em>. The book,
<a href="http://www.amazon.com/JavaServer-Faces-2-0-Complete-Reference/dp/0071625097/ref=pd_bxgy_b_img_a"
target="_blank">JavaServer Faces 2.0: The Complete Reference</a> by Ed Burns and Chris
Schalk, describes the lifecycle phases as follows:</p>
<blockquote style="margin-top: 0">
<em>[T]he request processing lifecycle performs all of the necessary back-end processing
for which one would otherwise have to write his or her own code. The lifecycle directs
the processing of incoming request parameters, and it manages a server-side set of UI
components and synchronizes them to what the user sees in a client browser. It also
satisfies follow-up requests for images, style sheets, scripts, and other kinds of
resources required to complete the rendering of the UI.</em><sup><a href="#footnote1Conclusion"
id="1Conclusion" style="text-decoration:none">[1]</a></sup>
</blockquote>
<p id="lifecyclePhases">The six lifecycle phases, according to
<a href="http://www.amazon.com/JavaServer-Faces-2-0-Complete-Reference/dp/0071625097/ref=pd_bxgy_b_img_a"
target="_blank">JavaServer Faces 2.0</a>, are defined as follows:</p>
<ol style="margin-top:0">
<li><strong>Create or Restore View:</strong> Restores or creates a server-side component
tree (View) in memory to represent the UI information from a client.</li>
<li><strong>Apply Request Values:</strong> Updates the server-side components with fresh
data from the client.</li>
<li><strong>Process Validations:</strong> Performs validation and data type conversion on
the new data.</li>
<li><strong>Update Model Values:</strong> Updates any server-side Model objects with new
data.</li>
<li><strong>Invoke Application:</strong> Invokes any application logic needed to fulfill
the request and navigate to a new page if needed.</li>
<li><strong>Render Response:</strong> Saves state and renders a response to the requesting
client.<sup><a href="#footnote2Conclusion" id="2Conclusion" style="text-decoration:none">[2]</a></sup></li>
</ol>
<img src="../../../../images_www/articles/73/javaee/ecommerce/conclusion/jsf-request-processing-lifecycle.png"
class="margin-around" alt="JSF request processing lifecycle" title="The JSF request processing lifecycle">
<p>One important concept of the JSF framework is the server-side UI component tree, or Faces
<em>View</em>. This component tree is built and maintained in server memory for each client
request, and is primarily associated with the first and last phases of the request processing
lifecycle depicted above. Consequently, the application is able to maintain state between
requests in a way that doesn't involve any manual coding on the part of the developer. In
other words, the request processing lifecycle handles synchronization between the server-side
View and that which is presented to the client. This enables you, the Java web developer,
to focus on code that is specific to your business problem.</p>
<h3 id="benefitJSF">How Can JSF Benefit Your Project?</h3>
<p>To understand JSF's benefits, let's take a second look at the <code>AffableBean</code>
project and consider how the framework could be applied.</p>
<h4>Strong Templating Support</h4>
<p>Rather than creating your application page views in JSP pages, you'd be using Facelets
technology instead.<sup><a href="#footnote3Conclusion" id="3Conclusion" style="text-decoration:none">[3]</a></sup>
Facelets is a first-rate templating technology that enables you to maximize markup reuse
and reduce redundancy in your page views. Also, because Facelets pages use the <code>.xhtml</code>
file extension, you are able prepare views using standard XHTML syntax.</p>
<p>In the <code>AffableBean</code> project, we took measures to reduce redundancy by factoring
out the header and footer markup for all page views into separate JSP fragment files,
and then included them in views by using the <code>&lt;include-prelude&gt;</code> and
<code>&lt;include-coda&gt;</code> elements in the deployment descriptor. Aside from the
header, the layouts for each of the application's five page views were unique. However,
many websites maintain the same layout across multiple pages. This is where templating
comes in especially handy.</p>
<p>With Facelets templating, you have more control over which portions of markup get displayed
for individual page views. For example, you could create a template layout that is common
to all page views, and insert view-specific content into the template to render your views.
In this manner, you could specify a title for each page view. (Notice that in the
<code>AffableBean</code> application, the title remains the same for all page views.)</p>
<h4>No Need to Handle Incoming Request Parameters</h4>
<p>Upon reexamining the <code>AffableBean</code>'s <code>ControllerServlet</code>, you can see
that each time we implemented code for the supported URL patterns, it was necessary to manually
extract user parameters using the <code>request</code>'s <code>getParameter</code> method.
When working in JSF, you often create <em>backing beans</em>, which are Java classes that
are conceptually bound to a specific page view. Parameters are automatically extracted from
a request (during phase 2 of the <a href="#lifecyclePhases">request processing lifecycle</a>),
and set as properties for the backing bean. JSF also takes care of casting the <code>String</code>
values of your request parameters into the types that you have defined for your backing bean
properties. For example, if you have a property defined as an <code>int</code>, and your
incoming request parameter is a <code>String</code> whose value is &quot;<code>33</code>&quot;,
JSF automatically converts the value to an <code>int</code> before storing it in the backing
bean.</p>
<h4>No Need to Programmatically Configure Navigation</h4>
<p>In order to set up navigation, we followed a certain pattern when implementing the
<code>ControllerServlet</code>: For each incoming request, the <code>getServletPath</code>
method is called to determine the requested URL pattern. After logic related to the URL pattern
is performed, a <code>RequestDispatcher</code> is attained, and the request is forwarded
to the appropriate page view. In numerous cases, the appropriate page view is specified by
hard-coding the path using the <code>userPath</code> variable.</p>
<p>None of this is necessary when using JSF - navigation is handled by the framework. Your job
would be to either associate page views with URL patterns and any logical outcomes using a
Faces configuration file, or take advantage of JSF 2.0's <em>implicit navigation</em> feature,
which automatically forwards a request to a view that has the same name as the requested
URL pattern.</p>
<h4>Built-in Validation Support</h4>
<p>JavaServer Faces provides built-in server-side validation support. In the <code>AffableBean</code>
project, we created a <code>Validator</code> class and manually coded logic to perform all
validation. Using JSF, server-side validation would automatically occur at phase 3 of the
<a href="#lifecyclePhases">request processing lifecycle</a>.</p>
<p>It would be worthwhile to take advantage of this validation for the <code>AffableBean</code>
checkout form, however some preliminary steps would be in order. Specifically, the HTML
markup for form elements would need to be replaced with comparable tags from JSF's
<a href="http://javaserverfaces.dev.java.net/nonav/docs/2.0/vdldocs/facelets/h/tld-summary.html"
target="_blank">Standard HTML Library</a>. This step converts the form elements into
JSF UI components, which we can then specify validation actions on using JSF's
<a href="http://javaserverfaces.dev.java.net/nonav/docs/2.0/vdldocs/facelets/f/tld-summary.html"
target="_blank">Core Library</a>. To give an idea, the side-by-side comparison
below demonstrates an adaptation of the checkout form's &quot;name&quot; field.</p>
<table>
<tr>
<td>
<strong>HTML Markup</strong>
<pre class="examplecode" style="width:252px">
&lt;label for=&quot;name&quot;&gt;name:&lt;/label&gt;
&lt;input type=&quot;text&quot;
id=&quot;name&quot;
size=&quot;30&quot;
maxlength=&quot;45&quot;
value=&quot;${param.name}&quot; /&gt;
&lt;c:if test=&quot;${!empty nameError}&quot;&gt;
Value is required.
&lt;/c:if&gt;</pre>
</td>
<td class="indent">
<strong>JSF HTML Tag Library</strong>
<pre class="examplecode" style="width:362px">
&lt;h:outputLabel value=&quot;name: &quot; for=&quot;name&quot;&gt;
&lt;h:inputText id=&quot;name&quot;
size=&quot;30&quot;
maxlength=&quot;45&quot;
<strong>required=&quot;true&quot;</strong>
value=&quot;#{checkoutBean.name}&quot; /&gt;
&lt;/h:outputLabel&gt;
&lt;h:message for=&quot;name&quot; /&gt;
</pre>
</td>
</tr>
</table>
<p>The <code>&lt;h:outputLabel&gt;</code> tag renders as an HTML <code>&lt;label&gt;</code>
tag, whereas <code>&lt;h:inputText&gt;</code> renders as an <code>&lt;input&gt;</code>
tag whose <code>type</code> is set to &quot;<code>text</code>&quot;. Note the <code>required</code>
attribute, which is set to <code>true</code> (shown in <strong>bold</strong>). This is
all that's needed to ensure that the field is not left blank by the user. The
<code>&lt;h:message&gt;</code> tag identifies the location where any validation error
messages for the field should display. JSF's default error message for a field that
requires user input is, &quot;Value is required.&quot;</p>
<p>Continuing with the example, if we wanted to check whether input for the field hasn't
exceeded 45 characters, we could apply the <code>&lt;f:validateLength&gt;</code> tag.</p>
<pre class="examplecode" style="margin-top:0; width:660px">
&lt;h:outputLabel value=&quot;name: &quot; for=&quot;name&quot;&gt;
&lt;h:inputText id=&quot;name&quot;
size=&quot;30&quot;
maxlength=&quot;45&quot;
required=&quot;true&quot;
value=&quot;#{checkoutBean.name}&quot;&gt;
<strong>&lt;f:validateLength maximum=&quot;45&quot; /&gt;</strong>
&lt;/h:inputText&gt;
&lt;/h:outputLabel&gt;
&lt;h:message for=&quot;name&quot; /&gt;</pre>
<h4>Well-Defined Division of Labor</h4>
<p>As stated in the <a href="http://download.oracle.com/javaee/6/tutorial/doc/bnapj.html" target="_blank">Java
EE 6 Tutorial</a>, &quot;One of the greatest advantages of JavaServer Faces technology is that it
offers a clean separation between behavior and presentation for web applications.&quot; If you
are working on a large project that involves a team of developers, the framework functions as a
blueprint which allows team members to focus on different areas of development simultaneously. For
example, front-end developers can implement page views using tags from JSF's HTML Library, while
programmers responsible for implementing component logic and behavior can &quot;plug their work
into&quot; existing HTML library tags.</p>
<h4>Ability to Render the View with Other Markup Languages</h4>
<p>Suppose that the Affable Bean staff commission you at a later point to prepare a
mobile version of their site, so users can access it using a hand-held device.
JSF APIs are a flexible rendering technology that enable you to attach multiple
renderers to the component tree (i.e., View) of a JSF-enabled application. In
other words, it is possible to create custom components that, for example, render
HTML when requested by a browser, or WML when requested by a PDA.</p>
</div>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans E-commerce Tutorial - Conclusion">Send
Us Your Feedback</a></div>
<br style="clear:both;">
<h2 id="seeAlsoConclusion">See Also</h2>
<div class="indent">
<h3>NetBeans Tutorials</h3>
<div class="indent">
<p><strong>JavaServer Faces</strong></p>
<ul style="margin: -.5em 0 1em -1.8em">
<li><a href="../../web/jsf20-support.html" target="_blank">JSF 2.0 Support in NetBeans IDE</a></li>
<li><a href="../../web/jsf20-intro.html" target="_blank">Introduction to JavaServer Faces 2.0</a></li>
<li><a href="../../web/jsf20-crud.html" target="_blank">Generating a JavaServer Faces 2.0 CRUD Application from a Database</a></li>
<li><a href="../../../samples/scrum-toys.html" target="_blank">Scrum Toys - The JSF 2.0 Complete Sample Application</a></li>
</ul>
<p><strong>Contexts and Dependency Injection</strong></p>
<ul style="margin: -.5em 0 1em -1.8em">
<li><a href="../cdi-intro.html" target="_blank">Getting Started with Contexts and Dependency Injection and JSF 2.0</a></li>
<li><a href="../cdi-inject.html" target="_blank">Working with Injection and Qualifiers in CDI</a></li>
<li><a href="../cdi-validate.html" target="_blank">Applying @Alternative Beans and Lifecycle Annotations</a></li>
<li><a href="../cdi-events.html" target="_blank">Working with Events in CDI</a></li>
</ul>
</div>
<h3>JavaServer Faces</h3>
<ul>
<li><strong>Product Page:</strong> <a href="http://www.oracle.com/technetwork/java/javaee/javaserverfaces-139869.html" target="_blank">JavaServer Faces Technology</a></li>
<li><strong>Specification Download:</strong> <a href="http://jcp.org/aboutJava/communityprocess/final/jsr314/index.html" target="_blank">JSR 314: JavaServer Faces 2.0</a></li>
<li><strong>Reference Implementation:</strong> <a href="http://javaserverfaces.dev.java.net/" target="_blank">GlassFish: Project Mojarra</a></li>
<li><strong>Official Forum:</strong> <a href="http://forums.sun.com/forum.jspa?forumID=427" target="_blank">Web Tier APIs - JavaServer Faces</a></li>
<li><a href="http://download.oracle.com/javaee/6/tutorial/doc/bnaph.html" target="_blank">The Java EE 6 Tutorial - Chapter 4: JavaServer Faces Technology</a></li>
<li><a href="http://download.oracle.com/javaee/6/tutorial/doc/giepx.html" target="_blank">The Java EE 6 Tutorial - Chapter 5: Introduction to Facelets</a></li>
<li><a href="http://www.amazon.com/JavaServer-Faces-2-0-Complete-Reference/dp/0071625097/ref=pd_bxgy_b_img_a" target="_blank">JavaServer Faces 2.0: The Complete Reference</a> [Book]</li>
<li><a href="http://www.amazon.com/Core-JavaServer-Faces-David-Geary/dp/0137012896/ref=pd_bxgy_b_img_b" target="_blank">Core JavaServer Faces</a> [Book]</li>
<li><a href="http://www.amazon.com/JSF-2-0-Cookbook-Anghel-Leonard/dp/1847199526/ref=pd_sim_b_2" target="_blank">JSF 2.0 Cookbook</a> [Book]</li>
<li><a href="http://refcardz.dzone.com/refcardz/javaserver-faces-20" target="_blank">JSF 2.0 Refcard</a></li>
</ul>
<h3>GlassFish Web Hosting</h3>
<ul>
<li><a href="http://www.joyent.com/" target="_blank">Joyent Cloud Hosting</a></li>
<li><a href="http://www.eapps.com/applications/glassfish-hosting.php" target="_blank">eApps Hosting</a></li>
<li><a href="http://www.visionwebhosting.net/glassfish-hosting.html" target="_blank">Vision Web Hosting</a></li>
<li><a href="http://www.jspzone.net/glassfish_hosting.htm" target="_blank">[DE]SYSTEMS</a></li>
<li><a href="http://www.jspzone.net/glassfish_hosting.htm" target="_blank">JSPZone</a></li>
</ul>
</div>
<br>
<h2 id="about">About the NetBeans E-commerce Tutorial</h2>
<img src="../../../../images_www/articles/73/javaee/ecommerce/conclusion/logo.png"
class="margin-around float-left" alt="AffableBean logo">
<br>
<p>The NetBeans E-commerce Tutorial and sample application were conceived of and
written by Troy Giunipero. The application began as a project arising out of
Sun's <a href="http://research.sun.com/SEED/" target="_blank">SEED program</a>,
and was developed from January 2009 to November 2010. The tutorial was prepared
as part of ongoing efforts to provide documentation for the IDE's
<a href="../../../trails/java-ee.html" target="_blank">Java EE & Java Web Learning
Trail</a>.</p>
<br style="clear:left">
<br>
<h2 id="acknowledge">Acknowledgments</h2>
<p>Many people have helped with this project. I am especially grateful to following individuals
for their help, support and contributions:</p>
<ul>
<li>Ed Burns, who was my SEED mentor, for his patience and guidance, and his willingness to
share his technical expertise in our numerous discussions concerning Java web technologies.</li>
<li>My managers, Patrick Keegan, for originally approving this project, and David Lindt, who
showed continuous support.</li>
<li>David Konecny and Andrei Badea for their invaluable help and advice, especially in regard
Java Persistence, working with EclipseLink, and integrating EE 6 technologies.</li>
<li>Don McKinney for providing the three beautiful diagrams used in <a href="#design">Designing
the Application</a>.</li>
<li>Eric Jendrock and the Java EE Tutorial team, for granting permission to adapt and reproduce
diagrams from the Java EE 5 Tutorial. Diagrams were used in <a href="#security">Securing
the Application</a>, and are based on <a href="http://download.oracle.com/javaee/5/tutorial/doc/bnbxj.html#bnbxl"
target="_blank">Figure 28-6: Mapping Roles to Users and Groups</a> and
<a href="http://download.oracle.com/javaee/5/tutorial/doc/bncbe.html#gexfa"
target="_blank">Figure 30-3: Form-Based Authentication</a>.</li>
<li>Jan Pirek, for coordinating and setting up necessary resources to make the
<a href="http://services.netbeans.org/AffableBean/" target="_blank">live demo</a> a reality.</li>
<li>Ondrej Panek for providing a Czech translation of text used in the sample application.</li>
<li>Also, special thanks to <a href="http://www.flickr.com/photos/cobalt/" target="_blank">cobalt123</a>
for graciously permitting usage of several photos, including
<a href="http://www.flickr.com/photos/cobalt/46523149/" target="_blank">Fresh Picks</a> and
<a href="http://www.flickr.com/photos/cobalt/1441879742/" target="_blank">Give Us Our Daily
Bread #1</a>.</li>
</ul>
<br>
<h2 id="disclaimer">Disclaimer</h2>
<p>This tutorial and sample application are solely available for educative purposes. Although
the sample application demonstrates a real-world scenario, there are several aspects that
are decidedly not &quot;real-world&quot;. For example, e-commerce sites do not typically
store customer credit card details, but allow payment to be managed by a reputable third-party
service, such as <a href="https://www.paypal.com" target="_blank">PayPal</a> or
<a href="http://www.rbsworldpay.com/" target="_blank">WorldPay</a>. Furthermore, although
not discussed in the tutorial, customer trust is a hard-earned commodity. An e-commerce
site's privacy policy, as well as the terms and conditions surrounding placed orders should
be made easily available to customers and site visitors.</p>
<p>The sample application and project snapshots are provided &quot;AS IS,&quot; without a warranty
of any kind. If you aim to use or modify this software for your own purposes, please comply
with the license presented at
<a href="http://developers.sun.com/berkeley_license.html" target="_blank">http://developers.sun.com/berkeley_license.html</a>.</p>
<br>
<h2>References</h2>
<ol>
<li id="footnote1Conclusion"><a href="#1Conclusion" style="text-decoration:none">^</a> Adapted from <a href="http://www.amazon.com/JavaServer-Faces-2-0-Complete-Reference/dp/0071625097/ref=pd_bxgy_b_img_a"
target="_blank">JavaServer Faces 2.0: The Complete Reference</a>, Chapter 3: The JavaServer
Faces Request Processing Lifecycle.</li>
<li id="footnote2Conclusion"><a href="#2Conclusion" style="text-decoration:none">^</a> Ibid.</li>
<li id="footnote3Conclusion"><a href="#3Conclusion" style="text-decoration:none">^</a> You can
certainly use JavaServer Pages in a JSF application. Facelets is the default view handler
technology for JSF version 2.0. For previous JSF versions, the default is JSP. In fact, when
creating a new JSF 2.0 project in the IDE, you are able to specify the view technology you
want to use (Facelets or JSP).</li>
</ol>
<br><br><br><br>
<h1 id="setup">The NetBeans E-commerce Tutorial - Setup Instructions</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Tutorial Contents</h4>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#design">Designing the Application</a></li>
<li><a href="#setup-dev-environ">Setting up the Development Environment</a></li>
<li><a href="#data-model">Designing the Data Model</a></li>
<li><a href="#page-views-controller">Preparing the Page Views and Controller Servlet</a></li>
<li><a href="#connect-db">Connecting the Application to the Database</a></li>
<li><a href="#entity-session">Adding Entity Classes and Session Beans</a></li>
<li><a href="#manage-sessions">Managing Sessions</a></li>
<li><a href="#transaction">Integrating Transactional Business Logic</a></li>
<li><a href="#language">Adding Language Support</a></li>
<li><a href="#security">Securing the Application</a></li>
<li><a href="#test-profile">Testing and Profiling</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ol>
</div>
</div>
<p><img src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" class="stamp"
alt="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"
title="Content on this page applies to NetBeans IDE, versions 6.8 and 6.9"></p>
<p>If you want to follow a tutorial unit without having completed previous units,
you need to perform some preliminary steps in order to set up your development
environment.</p>
<ol style="margin:5px 0 0 320px">
<li><strong>Set up your MySQL database server.</strong> Follow the steps outlined in:
<a href="setup-dev-environ.html#communicate">Communicating with the Database Server</a>.</li>
<li><strong>Create the <code>affablebean</code> schema on the database server,
and populate the database with sample data:</strong>
<ol style="margin: 5px 0 0 -1.5em">
<li>Click on <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252Faffablebean.sql">affablebean.sql</a>
and copy (Ctrl-C; &#8984;-C on Mac) the entire contents of the file.</li>
<li>Open the IDE's SQL editor. In the Services window (Ctrl-5; &#8984;-5 on Mac),
right-click the <code>affablebean</code> database connection (
<img src="../../../../images_www/articles/73/javaee/ecommerce/common/db-connection-node.png"
alt="Database connection node"> ) node and choose Execute Command.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup/execute-command.png"
class="margin-around b-all" alt="Services window - Execute command menu option"
title="Choose Execute Command from a connection node to open the IDE's SQL editor">
<br>
The IDE's SQL editor opens.</li>
<li>Paste (Ctrl-V; &#8984;-V on Mac) the entire contents of the <code>affablebean.sql</code>
file into the editor.</li>
<li>Click the Run SQL ( <img src="../../../../images_www/articles/73/javaee/ecommerce/common/run-sql-btn.png"
alt="Run SQL button"> ) button in the editor's toolbar. The script runs on your
MySQL server. Tables are generated for the database, and sample data is added to
the <code>product</code> and <code>category</code> tables.</li>
</ol></li>
<li><strong>Create a connection pool and JDBC resource on GlassFish.</strong>
<ol style="margin: 5px 0 0 -1.5em">
<li>In the Services window (Ctrl-5; &#8984;-5 on Mac), expand the Servers &gt; GlassFish
Server 3 node and choose Properties. In the Servers window that displays, make sure the
'Enable JDBC Driver Deployment' option is selected. If your project requires the MySQL
<a href="http://www.mysql.com/downloads/connector/j/" target="_blank">Connector/J</a>
driver, this option will ensure that the driver is deployed to GlassFish when your
project is deployed. (If the server is already running, you'll need to restart the
server.)</li>
<li>In the Services window, right-click the GlassFish Server 3 node and choose Start.</li>
<li>Once the server is running, right-click the GlassFish Server 3 node and choose View Admin
Console.</li>
<li>Log into the console (default username/password is: <code>admin/adminadmin</code>).</li>
<li>In the Admin Console, in the Tree on the left, expand the Resources &gt; JDBC node,
then click the Connection Pools node.</li>
<li>In the Connection Pools interface, click the New button, and enter the following details:
<ul style="margin: 5px 0 0 -1em">
<li><strong>Name:</strong> <code>AffableBeanPool</code></li>
<li><strong>Resource Type:</strong> <code>javax.sql.ConnectionPoolDataSource</code></li>
<li><strong>Database Vendor:</strong> <code>MySql</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup/connection-pool.png"
class="margin-around b-all" alt="GlassFish Admin Console - Connection Pools interface"
title="Specify settings to create a connection pool that connects with a MySQL database"></li>
<li>Click Next. Accept all defaults and click Finish.</li>
<li>In the Connection Pools interface, click on your newly created <code>AffableBeanConnectionPool</code>
to make the following change under the General tab:
<ul style="margin: 5px 0 0 -1em">
<li><strong>Datasource Classname:</strong> <code>com.mysql.jdbc.jdbc2.optional.MysqlDataSource</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup/datasource-classname.png"
class="margin-around b-all" style="width:638px"
alt="GlassFish Admin Console - Connection Pools interface"
title="Set the datasource classname for the connection pool"></li>
<li>Click Save.</li>
<li>Click the Additional Properties tab and ensure that the following three properties
have been set. (There may be other properties listed - these are default settings,
however the following three must be set manually.)
<ul style="margin: 5px 0 0 -1em">
<li><strong>User:</strong> <code>root</code></li>
<li><strong>Password:</strong> <code>nbuser</code></li>
<li><strong>URL:</strong> <code>jdbc:mysql://localhost:3306/affablebean</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup/additional-properties.png"
class="margin-around b-all" style="width:638px"
alt="GlassFish Admin Console - Connection Pools interface"
title="Set username, password and url to the database"></li>
<li>Click Save.</li>
<li>Click the General tab, then click Ping. You should see a message indicating that
the ping succeeded. The <code>AffableBeanPool</code> connection pool can now
connect to your MySQL database server.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup/ping-succeeded.png"
class="margin-around b-all" style="width:638px"
alt="GlassFish Admin Console - Connection Pools interface"
title="Ping the MySQL server to determine whether the connection pool can connect"></li>
<li>In the Admin Console's Tree in the left column, click the Resources &gt;
JDBC &gt; JDBC Resources node. The JDBC Resources interface opens in
the main window.</li>
<li>Click the New button to create a new JDBC resource, then enter the following
details:
<ul style="margin: 5px 0 0 -1em">
<li><strong>JNDI Name:</strong> <code>jdbc/affablebean</code></li>
<li><strong>Connection Pool:</strong> <code>AffableBeanPool</code></li>
</ul>
<img src="../../../../images_www/articles/73/javaee/ecommerce/setup/jdbc-resource.png"
class="margin-around b-all" alt="GlassFish Admin Console - JDBC Resource interface"
title="Specify JNDI name and connection pool to create the JDBC resource"></li>
<li>Click OK.</li>
</ol>
</li>
</ol>
<p style="margin-left:27em">You have set up the MySQL server and can connect to it from the
IDE's Services window. You created a database named <code>affablebean</code>, and populated
the database's <code>product</code> and <code>category</code> tables with sample data. You
then started the GlassFish server, and created a connection pool that enables the server to
connect to the <code>affablebean</code> database. Finally, you created a JDBC resource which
your application can use to reference the server's connection pool.</p>
<p style="margin-left:27em">You can now open and run any of the project snapshots provided for
you in the tutorial units.</p>
</body>
</html>