Copyright © 2007. All Rights Reserved.

Restricted Rights Legend The documentation is provided “as is” without warranty of any kind including without limitation, any warranty of merchantability or fitness for a particular purpose. Further, bea systems does not warrant, guarantee, or make any representations regarding the use, or the results of the use, of the document in terms of correctness, accuracy, reliability, or otherwise.

Trademarks and Service Marks Copyright © 2007. All Rights Reserved Tomcat, JBoss, RedHat, Microsoft, IBM, WebSphere, Sun Microsystems, BEA Systems, NetBeans. All other names and marks are property of their respective owners.

Legal Notice Any opinions expressed herein are solely those of the creators of the material and are not the opinions of BEA Systems, Inc. or its management.

TABLE OF CONTENTS
1. Welcome ....................................................................................................................7 What is Covered and Why ...........................................................................................8 2. Forward......................................................................................................................9 Prerequisites and Audience .......................................................................................11 3. Why Java? ...............................................................................................................12 Benefits of Java on the Web ......................................................................................12 4. Dynamic Web History..............................................................................................14 A Journey from CGI to Today ....................................................................................14 Chapter Goals........................................................................................................15 Common Gateway Interface (CGI) .........................................................................15 Active Server Pages (ASP Classic or ASP 3.0) ......................................................16 Hypertext Preprocessor (PHP) ...............................................................................17 Coldfusion Markup Language (CFM)......................................................................18 Java Server Pages (JSP) .......................................................................................19 ASP.NET................................................................................................................20 Emerging Web Application Frameworks.................................................................21 Ruby on Rails .....................................................................................................21 Django................................................................................................................22 5. Foundations.............................................................................................................23 Chapter Goals........................................................................................................23 Born from Servlets .....................................................................................................24 Application Server Architecture..................................................................................28 Free Java Application Servers................................................................................30 Apache Tomcat ..................................................................................................31 JBoss .................................................................................................................31 GlassFish ...........................................................................................................31 Commercial Java Application Servers ....................................................................32

Acronyms Abound: JDK, SDK, JRE, J2EE, Java EE, J2SE, J2ME and JVM Demystified................................................................................................................32 JDK (formerly the Software Development Kit) ........................................................33 JRE ........................................................................................................................33 J2EE ......................................................................................................................33 Java EE..................................................................................................................33 J2SE ......................................................................................................................34 J2ME......................................................................................................................34 JVM........................................................................................................................34 Development Tools....................................................................................................34 NetBeans: ..............................................................................................................35 Eclipse ...................................................................................................................36 Another Neat Tool (Ant) .........................................................................................37 The Anatomy of a JSP Application.............................................................................38 A Quick Note on Development............................................................................40 What are WAR Files?.............................................................................................40 What are JAR Files? ..............................................................................................41 Understanding Classpath .......................................................................................41 A Java Server Page Dissected...............................................................................42 Scriptlet <% … %>..............................................................................................43 Directive <%@ … %> ........................................................................................45 Expression <%= … %>.......................................................................................47 Declaration <%! … %> .......................................................................................48 Actions................................................................................................................49 Comment <%-- … --%> ......................................................................................50 Chapter Summary......................................................................................................50 6. Digging In.................................................................................................................51 Chapter Goals........................................................................................................51 The Nuts and Bolts of Java Server Pages .................................................................52 Implicit Objects.......................................................................................................52 Dealing with Data - JDBC.......................................................................................54

Connecting to a Database with JDBC .................................................................54 Retrieving Data from a Database........................................................................56 Adding Data to a Database.................................................................................58 Updating Data within a Database........................................................................59 Deleting Data from a Database...........................................................................59 What are JavaBeans? ...............................................................................................61 Attributes of a Bean................................................................................................64 Accessing a Bean ..................................................................................................65 Building and Deploying a Bean ..............................................................................67 Developing with Tags – JSTL / EL .............................................................................69 Java Server Pages Standard Tag Library (JSTL) ...................................................70 Accessing JSTL..................................................................................................71 Working with Variables .......................................................................................71 Expression..........................................................................................................71 Iteration ..............................................................................................................72 Conditionals........................................................................................................72 URL Management ..............................................................................................73 Exception Handling with Try / Catch ...................................................................74 Expression Language (EL) .....................................................................................74 Tags in Action - Examples......................................................................................75 Developing Custom Tags...........................................................................................79 Sending Email ...........................................................................................................92 File Uploads...............................................................................................................93 Capturing User Input with Forms ...............................................................................95 Validating User Input: ..............................................................................................101 JavaScript ............................................................................................................101 JSTL Form Validation...........................................................................................102 Advanced Validation ............................................................................................103 When Things Go Wrong - Error Handling ................................................................103 Chapter Summary....................................................................................................105

7. Reference Application...........................................................................................106 Chapter Goals......................................................................................................107 The Database ..........................................................................................................107 Scriptlet Sample ......................................................................................................109 Customer Listing ..................................................................................................110 Deleting a Customer ............................................................................................112 JSTL Sample ...........................................................................................................113 Customer Listing ..................................................................................................114 Adding a Customer ..............................................................................................115 Model View Controller (MVC) and JavaBeans .........................................................117 Controller Servlet .................................................................................................118 Customer Listing ..................................................................................................129 Adding a Customer ..............................................................................................130 Updating a Customer ...........................................................................................131 8. Map of Technology................................................................................................132 9. Next Steps..............................................................................................................133 Jakarta Struts ..........................................................................................................134 Java Server Faces...................................................................................................134 Hibernate.................................................................................................................139

Welcome

WELCOME

This primer has been developed to provide a 15,000 foot overview of Java Server Pages (JSP), the plumbing that supports it and related technologies. If you only have a few hours one afternoon and need to quickly get up to speed on these technologies, this collection of material has been designed as an excellent resource.

My aim is to provide a conceptual understanding of the Java technologies needed to build dynamic web applications, so that you can begin to design and develop solutions quickly with a solid fundamental understanding of the various components needed to create a solution. This book does not dive into the minutia of each topic covered, but instead provides links to additional information so that a complete understanding of a particular area can be achieved if it is relevant to your projects or interests. It will answer common questions in plain English and provide real world context for each element of the toolset.

Feel free to jump directly to a chapter that you are interested in, as this book also contains supplemental information about competing web technologies, details of Java application servers and more.

I hope you will find this book to be highly informative, and welcome any feedback that you may have at jspandbeyond@gmail.com.

JSP and Beyond 2007

7

Welcome

What is Covered and Why
This book has been arranged to allow you to jump to chapters that make sense depending on the task at hand. Here is an overview of what will be covered. • Forward – Since there are a seemingly endless number of books that cover JSP, this chapter examines why this book was written and the skills you need to jump in and get started. Why Java? – With so many technologies available for building web-based solutions, why are Java technologies a good choice? Is it worth investing in this education? Dynamic Web History – Why is JSP so powerful? This chapter covers how people built web-based solutions before technologies like JSP were made available, and reviews the landscape of various alternative web application development platforms. Foundations – This chapter provides an in-depth discussion about Servlets, application servers and the anatomy of a JSP application. The series of acronyms around JSP development kits are also demystified. Development Tools – It is time to forget notepad. This section reviews the tools necessary to expedite the JSP development process and will aid in your learning about them. Digging In – In this chapter you will learn about objects in a JSP, connecting and interacting with databases through JDBC, uses for JavaBeans, JSTL, nuts and bolts, email, form handling, error handling, file uploading and other elements needed to develop solutions. Reference Application – This chapter reviews and explains a sample code that uses a variety of approaches (scriptlets, JSTL and MVC) to build the same application. This sample code is intended to act as a base for your own development efforts. Map of Technology – The JSP technology map provides a quick overview of how the elements covered throughout this book operate together to support our solutions. Next Steps – Now that you have a good handle on the basics of JSP, advanced technologies like Jakarta Struts, Java Server Faces and Hibernate that you may encounter on a project or use in future projects are previewed.

JSP and Beyond 2007

8

Forward

FORWARD

Building real world solutions with powerful technology is a challenging and thoroughly enjoyable endeavor.

After working for leading software technology companies and developing a range of web-based .NET solutions, I felt compelled to peak over the fence and onto the Java side of the industry. What I found was a challenging, often difficult to understand, range of technologies that would supposedly come together to create business solutions. Java Beans, JSPs, EJBs, Struts, JVM, JDK… what do they all mean? What do they do? How can I build solutions with these building blocks? I was also certain that there were probably many other people with these same curiosities.

Fast forwarding through a series of late nights and plenty of espressos later, I began to wrap my head around what these technologies were all about.

Even though my journey was enjoyable and enlightening, I wished that there would have been some “jumpstart” guide to get me up and running faster with these technologies. It

JSP and Beyond 2007

9

Forward was at this point that I gained the inspiration for this book, with the goal of helping others quickly pickup on these Java-based technologies in an easy to understand manner.

“What tools do I need to create applications?”, “How do I install a Java application server to run my applications?”, “How can I read data from a database?” and “How can I update data in a database?” are just some of the questions that I want to answer for those starting the journey as I did. I am not here to focus on minutia, that can be done at a later date, but in order to help you start building solutions today in a very real, nonacademic environment.

Even though it seems that Java technologies are generally aimed at a more engineering oriented crowd, I see no reason why they cannot be leveraged by a wider audience. Hopefully I can help you bridge that gap so that you can begin to embrace some of the features of Java technologies that can be used to meet your organization’s business needs and ease your application development management.

JSP and Beyond 2007

10

Forward

Prerequisites and Audience
This book is meant to serve as a guide to fast track your introduction to JSP and related technologies. It will not cover Java syntax or object oriented programming techniques, so it is expected that at minimum you have some familiarity with a scripting language (PHP, ASP, etc) as well as a basic understanding of relational databases. Spending time to explain how to add integers is not very helpful, as there are already hundreds of books dedicated to dealing with the fine-grained details of Java development. Our intent is to aid you in developing solutions quickly.

Novice developers new to Java Server Pages, business analysts and technical managers can all benefit from the architectural information provided in this book. For experienced developers the goal is to act as a stepping stone to more powerful JSPbased (JSF, Struts, etc) development systems.

JSP and Beyond 2007

11

Why Java?

WHY JAVA?

Benefits of Java on the Web
You might ask, “Why Java”? Great question. There are a range of application development technologies for the web, each with their strengths and weaknesses that are discussed in the next chapter. In short, Java-based technologies offer a modern, robust, cross-platform technology for development.

The biggest draw to this technology is undoubtedly the ability to deploy applications inside of any Java application server on an extremely wide range of platforms. This means that you can avoid any sort of vendor lock-in and have an overwhelming choice of operating systems to deploy your applications on.

Some people might be quick to point out that other technologies are cross-platform and can be used to develop applications as well. However, Java has a unique advantage as

JSP and Beyond 2007

12

Why Java? it has been crafted with the web in mind and offers a mature, enterprise-ready, robust framework for application deployment.

At the time of this writing there is even more excitement surrounding the technology, as Sun Microsystems, the creators of Java, are fueling rumors that they may open source the technology to spread adoption. This direction is uncertain, but without a doubt the future of this technology is bright.

If you want to learn a technology for developing robust web applications, learning Java technologies is a sound investment that will pay off in spades.

JSP and Beyond 2007

13

Dynamic Web History

DYNAMIC WEB HISTORY

A Journey from CGI to Today
Before diving into the details on how to build solutions with JSP technology, it is helpful to revisit the past to see why the new tools and systems are so helpful. It is also beneficial to look at some current competing technologies along with the future direction of web development frameworks. Along with each technology is presented a brief history, an outline of some of its strengths and drawbacks and related resources.

I am not going to give you the old “in my day we walked to school uphill both ways in a blizzard” story, but after reading this section you will be glad that the tools have evolved. Development is now faster and easier than ever before, making it easy to take these new, more evolved tools for granted and to forget the past.

JSP and Beyond 2007

14

Dynamic Web History

Chapter Goals
• • Gain an understanding of the landscape for server-side technologies that produce dynamic web pages and content Learn how development capabilities have evolved over time to address recurring needs in application development

Common Gateway Interface (CGI)
CGI is not a programming language, but a standard way for a web server to communicate with other applications running on a server. CGI was developed by the National Center for Supercomputing Applications in 1993.

You might therefore ask why this is included in the Dynamic Web History section. CGI was the first major method by which dynamic web content was generated and is still serving dynamic content on the web for many sites today. Most CGI programs are written in Perl and there are a wide range of web sites that provide Perl scripts for guest books, shopping carts and other web application components.

That being said, there are a few drawbacks that make other development options more attractive for building web-based applications.

CGI Hello World # Hello world in perl print "Hello World!\n";

Drawbacks of CGI

There is nothing inherently wrong with using this tool to build applications, but CGI does suffer from some general problems • Scalability - Each time a request is made to a CGI application the application needs to be instantiated, respond to the request and then be destroyed. This is a very high overhead operation for each request and is a major drawback of CGI technology Security - CGI applications are generally run under accounts with permission to access files and OS related operations. A poorly written CGI program can inadvertently open security holes in an application.
15

JSP and Beyond 2007

Dynamic Web History • • • Runtime - Any errors that occur through a CGI application have the ability to harm the operation of the web server, since it is closely tied to the OS. Debugging - Debugging a CGI application can be more difficult than in other languages used for the web (ASP, PHP, ASP.NET and JSP). Limited Functionality - More modern languages designed for the web have access to more information about the environment, whereas CGI is restricted to the elements from a form post or get. Separation of Presentation and Logic – In CGI code, both presentation and business logic are mixed. That means that anyone who is developing a CGI application will have to retain specialists in the language used to develop their application in order to make any changes to the appearance. It also means that a CGI page can contain a large amount of code that is difficult to maintain.

Active Server Pages (ASP Classic or ASP 3.0)
Active Server Pages represented Microsoft’s first foray into tools that helped people create dynamic web content. The technology was derived from an acquisition made by a company that produced a product called DBWeb for the purpose of creating dynamic, data-driven websites. Released in 1996, ASP-based applications ran in conjunction with Internet Information Services 3.0, Microsoft’s web server.

ASP provided developers with a series of tools to solve common web application needs. This allowed them to speed application development and focus more on the solution, rather than building the underlying processes to facilitate communications and functions.

ASP also allows access to COM objects. This allows it to use existing business logic that has been built using COM objects.

ASP Hello World <html><body> <% Response.Write('Hello World!'); %> </body></html>

Drawbacks of ASP

JSP and Beyond 2007

16

Dynamic Web History Many web sites use ASP to generate content. However, newer languages that provide more robust functionality and ASP is becoming a less common solution for building dynamic web sites. • • Platform – ASP can only run on a Microsoft’s Internet Information Services web server on a Microsoft operating system*. Separation of Presentation and Logic – Using ASP it is difficult to separate business logic from presentation, however leveraging COM can mitigate this issue. Interpreted at Run Time – ASP code is interpreted line by line with each request. This means that it is less efficient than compiled code.

*There are some third party tools that will allow ASP to run on a different operating system and web server.

Hypertext Preprocessor (PHP)
The origins of Hypertext Preprocessor lie in Perl Scripts and CGI binaries developed in 1994. It was not until the 3rd release in 1998 that PHP resembles what it does today (it is currently in its 5th version at time this was written).

PHP is known for allowing people to easily and quickly create dynamic web-based content on a range of platforms such as Windows, Linux, Solaris, and various other Unix systems. PHP is open source and has very broad community support.

PHP Hello World <?php // Hello World in PHP echo 'Hello World!'; ?>

Drawbacks of PHP

PHP has continued to improve and remains a popular language for developing dynamic web content, but historically has some drawbacks. • Not Designed as Object Oriented – PHP has not been designed with object oriented programming in mind. It was not until version 4 that an object model was introduced to the language.

JSP and Beyond 2007

17

Dynamic Web History • • Lack of Exception Handling – PHP does not have a native structure to handle exceptions. PHP 5 has introduced error handling. Separation of Presentation and Logic – PHP lacks the ability to separate presentation and logic. This means that complex projects can become difficult to design and maintain. Interpreted at Run Time – PHP code is interpreted line by line with each request. This means that it is less efficient than compiled code. There is, however, a tool from a commercial organization named Zend that will precompile PHP code.

Coldfusion Markup Language (CFM)
Coldfusion and Coldfusion Markup Language were big stars during the .COM boom because due to the simplicity of the syntax, they provided a platform for quick development of web applications for those with little programming experience. Made available in 1997 the language still has a strong following.

ColdFusion MX 7 now runs on a Java Application Server, but older versions ran on an application server developed in C++ which gave Coldfusion a reputation for poor performance. Coldfusion Markup has the distinction of being a completely tag-based language. Interestingly enough,it has some similarities to Java Server Tag Language, or JSTL, allowing developers to quickly build applications with a tag-based framework that has been specifically designed for web application development. For instance, the sample below illustrates how an email could be sent from Coldfusion. As you will notice later in this book, JSTL is very similar to Coldfusion Markup.

<cfmail from="jspbeyond@example.com" to="recipientemail@jspbeyond.com" subject="An Email from JSP Beyond" server="mail.jspbeyond.com"> Sample Email Body Here </cfmail>

CFM Hello World <cfset message = "Hello World"> <cfoutput> #message#</cfoutput>

JSP and Beyond 2007

18

Dynamic Web History
Drawbacks of CFM

Depth – Coldfusion does not have the depth that a more complete stack like .NET or Java has. However, it is possible to have some interaction with a Servlet using a special tag. Scalability – Coldfusion has received a reputation for scalability problems. However, now that Coldfusion has been designed to run within a J2EE container, it has enhanced scalability compared with prior versions.

Java Server Pages (JSP)
First released in 1999, Java Server Pages are an extension of Java Servlets technology which was introduced in 1997. JSPs are considered the presentation layer of the Java 2 Enterprise Edition technology stack.

The overriding benefit of JSP technology is its ability to separate presentation of information from business logic and data. A JSP Page is essentially an HTML page with bits of Java-code mixed in, thereby enabling dynamic information to be displayed to an end-user. These bits of Java-code are generally referred to as Scripting Elements or Scriptlets for short. The HTML code surrounding these elements acts as a template, while the Java-based scriptlets can fill portions of the page with dynamic content like shopping cart information, customer account information and other dynamic information.

Beyond the separation of presentation from business logic and data, JSP offers tremendous advantages around enterprise system integration, as many large scale systems have integration points that can be accessed with Java. To enable platform independence these access points, or APIs, have been developed to use Java, thereby enabling JSPs to access and use these other systems.

Drawbacks of Java Server Pages

High Learning Curve - Java Server Pages and their related technologies often have a steep learning curve. By virtue of the value provided from the decoupled architecture versus the Microsoft-style development stack (IIS, Visual Studio and SQL Server), the world of JSP requires a more thorough understanding of each individual technology that comes together to provide a complete solution for applications.

JSP and Beyond 2007

19

Dynamic Web History

ASP.NET
Originally known as ASP+, ASP.NET is Microsoft’s next generation web platform. Version 1.0 was released to the public in 2002. From a development standpoint the Microsoft stack is unquestionably powerful. Developers often find the stack easiest to work with, thereby making it easier for companies to find developers who are familiar with the technology stack.

One of the somewhat unique distinctions of the ASP.NET technology is the concept of “controls”, or reusable building blocks that can easily be included into code to provide calendaring functionality, database results display, result set paging and more. Other technologies have similar features, but due to its native support control, use in development is quite popular. This model has so many benefits that the Java world has created something similar called JSF that uses “components” to provide a similar mechanism. JSF will be explored in the Next Steps chapter at the end of this book.

Controls also abstract the request and response elements of a web application. For instance, to retrieve the select value on a calendar, a code block like “Calendar.SelectedDate.Value” could be used instead of using the request object to obtain the value as more traditionally done (Request[“CalendarSelectedDate”]).

ASP.NET Hello World <%@ Page language="c#" Codebehind="HelloWorld.aspx.cs" AutoEventWireup="false" Inherits="Sample.HelloWorld" %> <form id="frmHelloWorld" method="post" runat="server"> Hello World! </form>

Drawbacks of ASP.NET

ASP.NET is a powerful platform, but does have some limitations as noted below. • Platform – ASP.NET applications can only run on a Microsoft Internet Information Services web server on a Microsoft operating system. Projects like Mono.net from the open source community are developing solutions to expand the support that .NET can enjoy, but I have reservations about this being embraced in the business world. MVC – Not perceived by all people as a drawback the ASP.NET model does not support a true MVC framework out-of-box. Due to the business logic for ASP.NET applications getting stored inside code-behind layer ASP.NET offers
20

JSP and Beyond 2007

Dynamic Web History the business logic and presentation separation, but adds some constraints around how request routing can be handled. • Cost – The operating system, database, development tools and application server are only available commercially through Microsoft.

Emerging Web Application Frameworks
Beyond the development languages mentioned above, are an emerging set of frameworks and languages that have grown out of the common need to deliver complex web applications. Although each web application that is developed will be unique, common needs (data retrieval, data display, form submission, form validation, sending email and more) have emerged throughout them, and because of this toolsets have evolved in an attempt to refine the way in which these common needs are addressed.

Ruby on Rails Out of all of the emerging frameworks few are talked about as much as Ruby on Rails. Rails is a framework that lets the Ruby language become extended to the web, providing many built-in tools commonly required by web applications. One of the major assumptions made by Ruby on Rails is that the web application will be backed by a database. An object layer automatically created over the database requires a programmer to write very little SQL, if any at all, since everything is dealt with through objects. The Next Steps chapter will review a tool called Hibernate that can be used to provide a similar object layer to abstract interactions with a database. Rails also provides form validation, error messages and many other common web application features.

To highlight the momentum behind the Ruby movement it is interesting to note that Ruby on Rails will be shipping with the latest version of Apples MAC OSX Leopard.

Django Django is very similar to Ruby on Rails, providing a pragmatic MVC framework with object modeled database abstraction, but uses Python as its programming language. It has not received quite as much press as Ruby on Rails, and the community surrounding it is less mature than the one for Ruby on Rails. In addition there are far less hosting options which makes production deployment somewhat of a hassle. That said, the Python language is more prevalent within the enterprise then Ruby. It will be interesting to see how much traction this framework gains over time.

JSP and Beyond 2007

21

Foundations

FOUNDATIONS

Now that we have a good handle on the history of application development on the web, let us examine what it takes to develop and serve Java Server Pages applications. One of the biggest challenges in JSP development is the extremely steep learning curve due to the many options that it offers.

This chapter helps to explore the underpinnings of JSP applications. It will explain how JSP is derived from Servlets, the nuts and bolts of application servers, acronyms related to development kits that you will need to know and development tools that will help you get up and running as quickly as possible for the next chapter, Java Server Pages Deconstructed.

Chapter Goals
• • Gain an understanding of how JSPs are essentially an extension on top of Servlets Learn about how JSPs are processed by application servers, also known as containers
22

JSP and Beyond 2007

Foundations • • Comprehend the distinctions between various “kits” that are needed for JSP development Review the ways in which JSPs incorporate various pieces of markup to generate dynamic content, and the various ways they can interact with user requests, format their responses and access information from the container that the JSP runs in

Born from Servlets
Before going into what is needed with regard to application servers, it is helpful to understand how Java Server Pages run within that application server.

I hesitate to completely confuse people, but Java Server Pages actually turn into Servlets within the container when they are requested by the end-user. Java Server Pages are so powerful for this very reason. They give you the ability to manipulate the page’s presentation of dynamic data while leveraging HTML without having to do complex server side coding, and yet you reap the power of the server side coding.

More on this process is explained in the following section, Application Server Architecture, but it is always good to know this background so you do not look at someone like they are nuts if they suggest that Java Server Pages are nothing more than fancy Servlets.

Below I have included two “Hello World” code samples, one using a Servlet to create the content and another using a JSP to create the content. Both methods produce the same output. This sample with code comments is designed to allow Servlets and JSPs to relate to each other, as JSPs are an abstraction layer on top of Servlets. Do not worry about the details of the Servlet code, as we will dig deeper into the code later in the book.

HelloWorld Servlet package org.apache.jsp; import javax.Servlet.*; import javax.Servlet.http.*; import javax.Servlet.jsp.*; JSP and Beyond 2007 23

Foundations

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { private static java.util.Vector _jspx_dependants; public java.util.List getDependants() { return _jspx_dependants; } public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException { JspFactory _jspxFactory = null; PageContext pageContext = null; HttpSession session = null; ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; JspWriter _jspx_out = null; PageContext _jspx_page_context = null; try { _jspxFactory = JspFactory.getDefaultFactory(); response.setContentType("text/html"); pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; out.write("<html>\ out.write("<html>\n"); <head>\ out.write(" <head>\n"); out.write(" <title>JSP and Beyond Hello World</title>\n"); World</title>\ </head>\ out.write(" </head>\n"); <body>\ out.write(" <body>\n"); out.write(" Hello World \n"); </body>\ out.write(" </body>\n"); out.write("</html>\ out.write("</html>\n"); } catch (Throwable t) { if (!(t instanceof SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0)

JSP and Beyond 2007

24

Foundations

out.clearBuffer(); if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); } } finally { if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context); } } }

HelloWorld JSP Page <%@page contentType="text/html"%> <html> <head> <title>JSP and Beyond - Hello World</title> </head> <body> <!-- This is our Hello World code --> <%= out.println("Hello World") %> </body> </html>

This is the HTML that is produced from the above Servlet and the JSP code!

<html> <head> <title>JSP and Beyond Hello World</title> </head> <body> Hello World </body> </html>

JSP and Beyond 2007

25

Foundations

Which one do you think took more effort to write? Which one makes it easier to manage the layout of the page? Even though we do not have to do complex coding in the JSP the Java Application Server will handle all of the translation to Servlet code for us as JSPs are transformed into Servlets when they are run.

On the highlighted lines in the code for the Servlet above it is interesting to notice that the out.write lines produce the HTML lines that we see in the HelloWorld.JSP code. This is much the equivalent of doing a Response.Write using Microsoft ASP or ASP.NET.

Speaking of Java Application Servers let’s look at how the HelloWorld.JSP page above was processed to produce the HelloWorld Servlet that is ultimately executed to render the content above in the Application Server section below.

Application Server Architecture
In order to run your dynamic web applications using JSP, you will need a Java Application Server or what are often times referred to as a “container”. When a JSP page is requested, it is this container that will ultimately deal with processing the request.

JSP and Beyond 2007

26

Foundations

It is important to understand at a high level how the container processes a request from a user, as this interaction underlies all JSP operations. The diagram below illustrates how an application server deals with these requests for dynamic content.

1. The client (i.e. user) makes a request for an item on the server (JSP, JPG, GIF, etc.). 2. The web container checks to see if the content has been requested before. If so the container will serve the content from an existing class file which is the result of a previously requested JSP (step B). If the content has not been requested before the container will build a class file and then process the request by executing the class file (step A). 3. The content is then served back to the HTTP server to be sent back to the client.

Regardless of the application server that is used to run your Java application, it will always process the request in the same nature. For our purposes we will initially work with a free container like Tomcat.

JSP and Beyond 2007

27

Foundations So… if that is Tomcat, what is this Apache Tomcat thing that I am hearing about? That is an excellent question!

Although at first a bit confusing, application servers have historically combined with an HTTP server for maximum performance in a slightly different manner than the sample above, which used a single application server that acts as both the java application server and HTTP server.

This has been done because the Apache HTTP server is designed to serve static content (HTML, GIF, JPG, CSS, JS, etc.) at a high rate under a high load. While Tomcat, the Java Application Server, by itself is capable of serving this content as well, it is not as optimized or configurable as an Apache HTTP server for this task. This is why it is common to hear about “Apache Tomcat”. The process of using a separate HTTP server and Java Application Server to handle an HTTP request are outlined below.

1. The client (i.e. user) makes a request for an item on the server (JSP, JPG, GIF, etc.). 2. The HTTP server checks to see if the request is a static item (JPG, GIF, etc.) or an item that needs further processing (JSP).
JSP and Beyond 2007 28

Foundations 3. The web container checks to see if the content has been requested before. If so the container will serve the content from an existing class file. If the content has not been requested before the container will build a class file and then process the request by executing the class file. 4. The dynamic content is then served back to the HTTP server to be sent back to the client.

Free Java Application Servers
The list below is by no means exhaustive, but in the interest of being pragmatic the front runners in free Java Application Server space have been outlined below. The samples in this book will work with any of the servers below, but have been developed using the Apache Tomcat application server.

Apache Tomcat Perhaps the most popular of all web containers due to its flexibility and simplicity, Apache Tomcat has a significant place in the world of Java Server Pages. Apache Tomcat is the Servlet container that is used in the official Reference Implementation for the Java Servlet and Java Server Pages technologies. This means that it follows the design specification exactly from Sun Microsystems.

Apache Tomcat was developed in an open and participatory environment and released under the Apache Software license. Since Tomcat contains an HTTP server it can also be used as a standalone web server. Tomcat was developed entirely in Java. This allows it to run on any platform that has a Java Virtual Machine.

For information about the Tomcat application server visit http://tomcat.apache.org/

JBoss Now owned by RedHat, Inc, JBoss is an application server developed purely in Java. This allows it to run on any platform that has a Java Virtual Machine just as Apache Tomcat.

JSP and Beyond 2007

29

Foundations JBoss is a free, open source, application server that implements the complete Java 2 Enterprise Edition (J2EE) stack, including Java Server Pages (JSP), Servlets, and Enterprise JavaBeans (EJB).

For information about the JBoss application server visit http://www.jboss.org

GlassFish GlassFish is a free, open source application server that contains some of the newest features for Java application servers. It was developed by Sun Microsystems.

For more information about GlassFish application server visit https://glassfish.dev.java.net/

Commercial Java Application Servers
A wide range of commercial Java application servers are available. The commercial Java application servers generally provide robust support for clustering, management and other tools that the free tools have spent less time developing (although JBoss does potentially have the most maturity in this area for a free application server).

Some examples of commercial Java application servers are BEA WebLogic, IBM WebSphere, Oracle Application Server and Macromedia JRun.

For information about the BEA WebLogic application server visit http://www.bea.com For information about the IBM WebSphere application server visit http://www.ibm.com For information about the Oracle Application Server visit http://www.oracle.com For information about the Macromedia JRun application server visit http://www.adobe.com/products/jrun/

JSP and Beyond 2007

30

Foundations

Acronyms Abound: JDK, SDK, JRE, J2EE, Java EE, J2SE, J2ME and JVM Demystified
One of the initial things that I found to be extremely frustrating when trying to build Java web-based solutions was getting my head around all of the different acronyms for the components used to run the applications. Part of the trouble seems to stem from Sun’s marketing department deciding it might be fun to switch things around fairly frequently.

The list below details each acronym and what it is used for. A summary table lies below the list and can be used for quick reference.

JDK (formerly the Software Development Kit)
Produced by Sun Microsystems the Java Development Kit (JDK) provides the nuts and bolts for Java software development minus an Integrated Development Environment (IDE) and web application server. It contains tools that allow compilation of Java code, running and debugging of Java code.

JRE
The Java Runtime Environment (JRE) consists of the barebones components to run Java applications. It contains a Java Virtual Machine (JVM), core classes and supporting files. It does not contain components for application development like the JDK.

J2EE
Java 2 Platform Enterprise Edition is a suite of tools that help developers create connections to enterprise data and systems. Specifically, Enterprise JavaBeans (EJBs), JavaServer Pages (JSPs) and Java Servlets can be used to access the data through tools like JDBC, JNDI, JTA, JMS, Java Mail and CORBA. For our purposes we will only be covering a fraction the J2EE platform abilities, specifically focusing on JSPs, the presentation layer of the J2EE technology stack.

JSP and Beyond 2007

31

Foundations

Java EE
As the J2EE platform has evolved Sun Microsystems has added additional functionality. Some of the new features that Java EE added are support for Java Server Faces, enhanced web services capabilities and better ways to interact with Java code brokering database access. This highlights the Java community’s evolution based on the common needs that are continually identified by organizations looking for easier ways to develop software.

J2SE
Think of Java 2 Platform, Standard Edition (J2SE) as JDK plus. It includes a wide range of components like Swing (a user interface library) for application development on desktops and servers and for deployment in embedded environments.

J2ME
The Java 2 Platform Micro Edition enables PDAs, TV set top boxes, ovens, printers, cell phones and other devices to run Java applications. Just as JVMs are specific to a particular platform each device that is J2ME-capable needs a specific “profile” for J2ME code to work on it based on a device’s particular capabilities.

JVM
The Java Virtual Machine is the heart of the Java applications. It provides an abstraction layer on top of the operating system that is capable of running Java applications. This makes it platform independent, allowing Java code to run on Windows, UNIX, Linux and any platform that a JVM has been developed for. At a nuts and bolts level the JVM is able to consume compiled Java code (bytecode) into machine language where it can be run on a particular platform. This is Java’s claim to fame and gives way to the expression “write once, run anywhere”.

Development Tools
In order to speed our development process we have the luxury of being able to use an Integrated Development Environment (IDE). Some purists might say that IDEs hold
JSP and Beyond 2007 32

Foundations people back from learning about what really occurs when you build an application. Unfortunately, I think that this viewpoint stems from the insecurity that they feel due to the tremendous power of IDEs today opening the development of applications to a greater range of users who have little interest in memorizing every class and it methods, but instead want to focus on solving the business problem at hand.

If I were going to run a marathon, wouldn’t I want to have the best shoes? If I were going to race cars, wouldn’t I want to have the best automobile? This book is all about practicality and creating solutions to problems, not spending all day trying to do things in cryptic, archaic ways.

We are therefore going to be pragmatic and give ourselves the best shoes, the best car and get building! Here are some powerful IDEs that can help you start to make the most of your experience building solutions.

NetBeans:
NetBeans is a free IDE from Sun Microsystems. It is a great tool for letting developers quickly get into Java development, as it comes packaged with a built-in Java Application Server preconfigured to run your projects, and is aware of syntax for web application development immediately out-of-the-box. I highly recommend this IDE for working with the samples that we will review over the course of this book.

JSP and Beyond 2007

33

Foundations

You can learn more about this IDE and download it at http://www.netbeans.org/.

Eclipse
Eclipse is a powerful open source IDE. Once you become more familiar with Java development it might be worthwhile giving it a try. Eclipse has been developed to be extensible and there are now a wide series of “plugins” that enable various features within the development environment. A series of examples can be found at http://www.eclipse.org/projects/. Some organizations offer a preloaded version of Eclipse with plugins to assist with Java web development that offers a quick, easy method to get started. One such example is Lomboz which can be downloaded at http://lomboz.objectweb.org/.

Many large software organizations that used to build their own IDEs (BEA and IBM) discontinued their tools and now ship components called plugins that run inside of Eclipse and provide that same functionality.

JSP and Beyond 2007

34

Foundations

You can learn more about and download this IDE at http://www.eclipse.org/.

Another Neat Tool (Ant)
Bugs are generally thought of as a bad thing, especially in relation to software development. This being said, Ant has rightfully made quite a name for itself in the development world. It is a powerful “build” and deployment automation tool that can be configured using XML. You can think of the tool as being a very powerful, highly configurable batch file.

In any medium- or large-scale software project it is not unusual to spend a lot of time preparing your files to get sent to a server where end users will use or test your application. Ant excels at providing repeatable build processes, especially for more complex deployments, when many files may need to be compiled, adjusted, directories created, moved, sent over FTP, etc. Here is an example of an Ant file from the Apache Ant help file that demonstrates how the XML file guides the build process.

JSP and Beyond 2007

35

Foundations

<project name="MyProject" default="dist" basedir="."> <description> simple example build file </description> <!-- set global properties for this build --> <property name="src" location="src"/> <property name="build" location="build"/> <property name="dist" location="dist"/> <target name="init"> <!-- Create the time stamp --> <tstamp/> <!-- Create the build directory structure used by compile --> <mkdir dir="${build}"/> </target> <target name="compile" depends="init" description="compile the source " > <!-- Compile the java code from ${src} into ${build} --> <javac srcdir="${src}" destdir="${build}"/> </target> <target name="dist" depends="compile" description="generate the distribution" > <!-- Create the distribution directory --> <mkdir dir="${dist}/lib"/> <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -> <jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/> </target> <target name="clean" description="clean up" > <!-- Delete the ${build} and ${dist} directory trees --> <delete dir="${build}"/> <delete dir="${dist}"/> </target> </project>

Our purpose here is not to dive into the details of Ant, but to help you understand that it is a very powerful tool for standardizing deployments and saving time. The above sample from Apache starts to hint at how much activity can be automated with a single mouse click.

JSP and Beyond 2007

36

Foundations

You can learn a good deal more about Ant at http://ant.apache.org/.

The Anatomy of a JSP Application
At first glance the directory structure for a JSP application can appear complex. Each JSP-based application that is deployed inside of an application server needs to follow a certain directory hierarchy.

Each section of the directory hierarchy has been created to serve a particular purpose as illustrated below. Once you become accustomed to the directory format, it becomes easily navigable and logically structured.

At the very root of the container’s file structure there is generally a directory to house the web applications. It is within this directory that you will place your application files. In the examples below, let us suppose that you have a web application name called “YourWebApp”.

YourWebApp/

Within this directory all static content should reside. This includes JSP, HTML and image files.
JSP and Beyond 2007 37

Foundations
YourWebApp /WEB-INF/

The Web Application deployment descriptor (web.xml) lives within this directory. This deployment descriptor maintains all of your application settings that dictate how the container delivers your application. The following code sample shows a web.xml file that lets the container know that the default file for the directory is index.jsp and the application timeout is set at 30 minutes.

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file> index.jsp </welcome-file> </welcome-file-list> </web-app>

This directory is private and not externally accessible by end users.

YourWebApp /WEB-INF/classes

Java classes and Servlets should reside in this directory. The directory is private and not externally accessible by end users, so they cannot request the source code for the files.

YourWebApp /WEB-INF/lib

This is where you can place a JAR fileand tag libraries. The directory is private and not externally accessible by end users. As above, this inherent safety mechanism stops end users from directly accessing this content.

JSP and Beyond 2007

38

Foundations A Quick Note on Development During application development, it can be most advantageous to work with your application files in what is called an exploded format. The exploded format allows you to work directly with the directory structure, which makes it easier to work with. Once the application is ready for distribution, it can be packaged into a WAR file for easy portability by consolidating all of the above directories into a single file.

What are WAR Files?
Some may consider developing software under pressure and tight deadlines a war, but this is not what was intended by the strange name. A WAR or Web Archive file contains an entire web application in a single, compressed file. To create a WAR file it is possible to ZIP an entire web application into a package with a WAR file extension. This makes deploying an application contained within a WAR file very easy compared to dealing with a less manageable directory structure of files.

For instance, to deploy a WAR file in Tomcat simply place the WAR file in a /webapps directory and restart the application server (note that in the newer version of Tomcat it is possible to use a web-based administrative console to deploy WAR files by way of file upload). This WAR will contain all JSPs and supporting materials like JARs, images and JavaScript.

What are JAR Files?
A JAR file is a ZIP file that contains Java class files. The JAR file offers a convenient way to group together a series of classes for distribution with an application. It is pretty much the same concept as the WAR file and helps to simplify management of your application and the deployment process. A common example of a JAR file would be one that a company distributes that contains an API specific to their product. This makes it easier to consume their classes, method and attributes.

Understanding Classpath
Even seasoned developers wrestle with the beast called Classpath. Although this guide is not meant to teach the basics of Java development, I think that it is nonetheless important to take a moment to speak about the Classpath environment variable.

JSP and Beyond 2007

39

Foundations The Classpath information which is held in an environment variable, lets a compiler or JVM know where it can find JAR and class files that you want to reference in your code. A good example might be including the mail.jar file in an application, an example that will be discussed later. Classpath provides a pointer to JAR and class files that you will want to use in a project. As you deploy your applications into different environments, it is essential that the Classpath is properly set on the target system.

To check what references are currently being made in your Classpath, you can type “echo %classpath%” in Windows or “echo $classpath” on Linux / Unix systems. You should see something like the following if your Classpath environment variable is set.

As illustrated in the above example, a JAR file to help connect with MySQL is directly referenced to ensure that an application can use it.

A Java Server Page Dissected
It is important to remember that a JSP is just HTML code with some special, dynamic markup. The HTML portion of the page is referred to as the template, and the dynamic portions of the page can be scriptlets, directives, expressions, declarations, actions and comments.

The chart below illustrates how the pieces can come together within a single JSP.

JSP and Beyond 2007

40

Foundations

Scriptlet <% … %> Scriptlets let you use full Java code in the body of a JSP. That being said, it is considered bad practice to use scriptlets within the page because they mix application code with presentation code, detracting from many of the available benefits.

JSP and Beyond 2007

41

Foundations

The block of code below demonstrates how a series of scriptlets can be used to display a list of months. Notice how the scriptlet can contain HTML within a “for loop” to format how the HTML will be sent to the browser.
<table> <% String months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "July", "Aug", "Sep", "Oct", "Nov", "Dec"}; for(int i = 0; i < months.length; i++ ) { %> <tr> <td> Month: <%= months[i] %> </td> </tr> <% } %> </table>

JSP and Beyond 2007

42

Foundations Directive <%@ … %> Directives do not send output to the screen, but set configuration values for the JSP page. There are three main directives: page, taglib and include. Each of these directives and a high level explanation of them is provided below.

Page

The page directive allows you to include code from other packages within the JSP, include another block of JSP code, set the current page to act as an “error” page and set other page level settings.

A common example of a page directive might be <%@ page import="java.util.*, java.lang.*" %>, which lets a JSP access methods and properties within the Java.util and Java.lang packages more easily. For example, by using the <%@page import="java.sql.*" %> directive, you are allowed to write code that requires fewer characters to work with in a SQL database. This is somewhat analogous to addresses, and saying that “we are talking about Chicago”, so that any references that are made to a street address would be assumed to be in a Chicago location.

Below are some of the most commonly used page directives.

Directive Import

Description The Import directive easily allows for access to other libraries that you may be using in your project. Some common examples might be <%@ page import="java.util.*, java.lang.*" %> or <%@page import="java.sql.*" %>

errorPage isErrorPage

/ Using the errorPage attribute directive makes it possible to setup a page to handle errors that may occur on that page. The isErrorPage attribute will let the page know that it is capable of being used as the error page that will field errors from other pages.

JSP and Beyond 2007

43

Foundations More information about the complete range of page directives can be found at http://java.sun.com/products/jsp/syntax/1.2/syntaxref1210.html.

Include

The include directive allows a JSP to call another JSP within its same container. This is very helpful to include headers, footers and other repeated elements for a web site or web application. The syntax to include a file called header.jsp would be as follows:
<%@ include file="/header.jsp" %>

Taglib

With the introduction of JSP 1.1, a new feature was added that allows custom tag libraries to be added to JSPs. Using custom tag libraries lets you access rich functionality that allows its complexity to be masked within a particular tag. This is a very useful feature to assist in the separation of logic from presentation, following the JSP best practices, and letting non-developers incorporate tags into HTML templates.

To access a tag library called “mytag” you would use the following line of code within the JSP to make it aware of the custom tag library that was developed.
<%@ taglib uri="tlds/taglib.tld" prefix="mytag" %>

The sample below shows how the above line would be incorporated into the JSP and then the mytag prefix used to display content in the middle of the page.

<%@ taglib uri="tlds/taglib.tld" prefix="mytag" %> <html> <head> <title>JSP Custom Tag Sample</title> </head> <body> < mytag:ourTestTag name="Stan the JSP Master"/> </body> </html>

JSP and Beyond 2007

44

Foundations Expression <%= … %> Expressions allow you to directly output values to the page rather than using an out.write statement within a scriptlet. It is a nice, shorthand way of displaying output from a method or variable within your HTML template.

For example, instead of using the following line within a scriptlet or Servlet
out.write(“Bill Smith”);

You can use this line to directly write a string value to the page
<%@ page import="java.util.*" %> <%! String sName = "Bill Smith"; %> <table> <tr> <td> Welcome <%= sName %>! </td> </tr> </table>

JSP and Beyond 2007

45

Foundations Declaration <%! … %> Declarations are used to set variables and define methods within the JSP. The following example shows a method written inline within the JSP.

<%@ page import="java.util.*" %> <%! // This is the method that will return the current time String GetCurrentTime() { Date date = new Date(); return date.toString(); } %> <table> <tr> <td> What time is it? <%= GetCurrentTime() %> </td> </tr> </table>

Results of the above code

JSP and Beyond 2007

46

Foundations Actions Actions are XML-based tags that allow access to common pieces of JSP functionality. useBean, setProperty, getProperty.include, forward and plugin are all accessed through user friendly XML-based tags. Think of it as new HTML markup that allows for dynamic, rich functionality in a page with no development by a page designer.

Action useBean

Description Allows simplified interaction with JavaBeans. The useBean action will instantiate a bean if it has not been instantiated already, and associates a scope with the bean.

getProperty

This XML snippet allows tag-based access to a Bean’s property.

setProperty

This XML snippet provides a tag-based method to set the value of a Bean’s property.

include

Merges content from another JSP into the page markup.

forward

Sends the page processing to another JSP or Servlet.

param

Identifies a value to be sent to another JSP or Servlet that a request is being forwarded to.

plugin

The plugin action allows HTML markup to be sent to the user’s browser for Applets based on the platform they are using.

JSP and Beyond 2007

47

Foundations Comment <%-- … --%> Sometimes you only want your comments to show to your development team. NormallyHTML comments (<!—your informative or witty comment here -->) are sent to the requestor’s browser. With the JSP style you can keep comments inline with the code, but they will not be sent with the HTML response to the requestor’s browser.

Chapter Summary
Java Server Pages are essentially an extension of Servlets. JSPs make it much easier to write dynamic code that runs with an application server, also known as a container. There are many ways to make JSPs, but it is recommend to use an IDE such as NetBeans or Eclipse, to help learn JSP and speed development efforts. The IDEs can also abstract the file structure for an application, but it is always good to know the inner workings and why certain files are placed within certain spots in the directory structure of an application deployment. JSP markup contains various elements that all serve a different purpose. Scriptlets, directives, expressions, declarations, actions and comments are all added to the HTML template markup to inject dynamic information into the page that is rendered to end users.

JSP and Beyond 2007

48

Digging In

DIGGING IN

So far, so good, right? Now that we have reviewed the underpinnings of JSP it is time to dig into the specifics of JSP itself, and examine the various pieces that allow us to directly develop applications to solve business problems. This chapter also begins to present samples from an application that will be referenced throughout the remainder of the book as a way to best practice methods for application development with JSP.

Chapter Goals
• • • • • • Review what implicit objects we have access to throughout a JSP and what that means to us Learn how to interact with databases Understand what JavaBeans are and how we can use them Review the benefits of tags and how they can help simplify development, reducing the need for scriptlets in our JSPs Demonstrate how to send email from a JSP Review how file uploads can be managed in a JSP
49

JSP and Beyond 2007

Digging In • • Capture and validate user input from forms Gracefully manage errors that occur in an application

The Nuts and Bolts of Java Server Pages
Implicit Objects
Within each JSP page there are a series of objects that can be used to access and set information all with some type of scope. The following table provides a practical overview of each. It is not necessary to know every single one of these off of the top of your head, but common objects, such as the request and session objects, will become a big part of your life when developing JSP pages.

Object request

Description Cookies, querystring variables and other pieces of data are readily accessible from the request object.

For instance, by using the following expression <%= request.getParameter("ProductID") %> , the “ProductID” argument from the querystring can be captured and displayed. This is very useful for easily passing ID information between pages of an application.

response

Response is used to send information to the client. A good example might be setting a cookie. The following block of code sends a cookie to the client that can be retrieved at a later time through the request object <% response.addCookie(myCookie) %>.

JSP and Beyond 2007

50

Digging In

config

Allows you to access configuration settings in the web.xml deployment descriptor for your application. This is very useful when trying to access name value pairs that may adjust based on where your application is deployed.

out

When using a scriptlet, it is possible to send output to your HTML page within the scriptlet code by using the out object. The following sample of code uses out object’s print method to send text to the HTML page <% out.print("some text here") %>

session

The session object is useful for storing small amounts of information that will be accessible throughout a users visit to your application or web site. A good example might be their user ID so you will not have to continually query a database to find this information.

application

Similar to the session object, the application object allows you to store generally small amounts of data across many page requests. Unlike the session object the application object values will be available to all user sessions.

page

The page object represents the current request. There is generally no practical use for the page object when developing JSPs.

exception

In order to leverage the implicit exception object the page directive attribute must be set to true.

JSP and Beyond 2007

51

Digging In

pageContext

The pageContext object provides access to all of the above objects. As an example, we can see that the following code mySession = pageContext.getSession() will return the session object for the current user. In your JSP you could also access the session object directly without using the pageContext object.

Practically, the pageContext object can be used to get and set attributes such as <% pageContext.getAttribute(“MyShoppingCart”) %> to store or retrieve data.

Dealing with Data - JDBC
Connecting to a Database with JDBC In this day and age it is probably fair to say that any application that you are developing must connect to some persistent data store. Generally, this means that we are going to use a relational database for creating, reading, updating and deleting information commonly abbreviated as CRUD. In order to do any of these actions a connection needs to be created with a database. This is where the following code comes in handy by creating a connection object that can be used later to perform any of the CRUD activities.

// Import the namespace for the database connection import java.sql // Create the database connection object Connection cnDB = null; // Load the driver that will be used for the database connection Class.forName("com.mysql.jdbc.Driver").newInstance(); // Establish the connection cnDB = DriverManager.getConnection("jdbc:mysql:///DatabaseName","user", "password");

JSP and Beyond 2007

52

Digging In
import java.sql

This line lets the system know that you will make references to objects pertaining to sql without having to use a complete namespace reference.

Connection cnDB = null;

In order to do any work with the database we will need a connection object. This line creates a connection object “cnDB” that we can use later in the code.

Class.forName()

Class.forName() uses reflection to dynamically load a class on runtime and register it with the DriverManager class. This allows you to load whatever driver will make sense for the database that you wish to connect to. For instance, to connect with an Oracle, DB2 or Postgre database you could use one of the following lines for your respective database
Class.forName ("oracle.jdbc.driver.OracleDriver"); Class.forName("com.ibm.db2.jdbc.app.DB2Driver"); Class.forName("postgresql.Driver");

For our sample we will be connecting to a MySQL Database and will therefore use com.mysql.jdbc.Driver supplied by MySQL AB called Connector J. More information about Connector J can be found at: http://www.mysql.com/products/connector/j/

cnDB = DriverManager.getConnection("jdbc:mysql:///DatabaseName","user", "password");

The connection object is now given the information needed to connect with the database in the form of a URL. The URL can contain the database hostname, database name, user and password.

jdbc:mysql://databasehost/database?user=username&password=passwor d

We will now be able to use this object to communicate with the database as the following illustrations will demonstrate.

JSP and Beyond 2007

53

Digging In Retrieving Data from a Database The most common action that any database driven application or web site will perform is data retrieval. For the sample below we will simply show how the data is returned by using Servlet code. We will also use the connection object, cnDB , that was established in the above example, “Connecting to a Database with JDBC”.
// Prepare a statement object that will be used to request the data Statement stmt = cnDB.createStatement(); // Create an object to hold the results set ResultSet results; // Populate the results object with the data from the SQL statement above results = stmt.executeQuery("SELECT * FROM tblCustomer ORDER BY CustomerName"); // Use a string to hold the HTML results from the query String strResults = "<table cellpadding=\"3\" width=\"100%\">"; // Move through the result set object while(results.next()) { results.getRow(); strResults += "<tr><td>" + results.getString("CompanyName") + "</td><td>10/10/06</td><td><a href=\"CustomerEdit.jsp?CustomerID=" + results.getString("CustomerID") + "\">edit account</a></td><td><a href=\"NoteAdd.jsp?CustomerID=" + results.getString("CustomerID") + "\">add note</a></td></tr>"; } strResults += "</table>"; // Close the result set results.close(); // Close the result set stmt.close(); // Close the connection cnDB.close(); // Print strResults somewhere

JSP and Beyond 2007

54

Digging In
Statement stmt = cnDB.createStatement();

Assuming that you are already using the cnDB database connection object from the previous example, you will be able to create a statement object that will provide a way to update or query the database. The createStatement object will mainly be used by way of the executeQuery and executeUpdate methods. In this example we will use the executeQuery method to give us a result set.

ResultSet results;

This instantiates a ResultSet object call that holds the response from the executeQuery statement with the records returned.

results = stmt.executeQuery("SELECT * FROM tblCustomer ORDER BY CustomerName");

This line combines a few things to populate the results object with the relevant rows from the database. The executeQuery method of our statement object lets us pass an SQL query like “SELECT * FROM tblCustomer ORDER BY CustomerName” that will return a ResultSet that will be stored in the results object.

while(results.next()) {

This line uses a method of the ResultSet object called next to iterate through the series of results. In this example we have created a string called strResults that we will add to in the ? does this make sense? loop. During the loop we access the results object to get different parts of the database row. For instance results.getString(“CompanyName”) will return the company name from the database for the current row in the loop. After the loop, we add an additional string to the strResults variable to complete an HTML table containing the database information.

results.close();

This line releases the connection object's database and JDBC resources immediately instead of waiting for them to be automatically released. Closing ResultSet explicitly gives a chance for garbage collector to recollect memory as early as possible, because ResultSet objects may occupy lots of memory depending on the query.

stmt.close();

Close statement object as soon as you finish working with that. It explicitly gives a chance for garbage collector to recollect memory as early as possible, which in turn affects performance.

cnDB.close();

JSP and Beyond 2007

55

Digging In Close statement object as soon as you finish working with that. It explicitly gives a chance for garbage collector to recollect memory as early as possible, which in turn affects performance.

Adding Data to a Database The statement object that was discussed in the last example is also used to insert data into the database.
// Obtain a statement object Statement stmt = cnDB.createStatement(); // Execute the block of SQL code stmt.executeUpdate("INSERT INTO tblCustomer VALUES ('Smith', 'Boston', 2006)"); // Close the result set stmt.close(); // Close the connection cnDB.close();

Statement stmt = cnDB.createStatement();

Assuming that you are already using the cnDB database connection object, you can create a statement object that will allow you to add a record to the database.

stmt.executeUpdate("INSERT INTO tblCustomer VALUES ('Smith', 'Boston', 2006)");

With the stmt Statement object you can leverage the executeUpdate method to accept your SQL string with the insert SQL as shown above.

stmt.close();

Close statement object as soon as you finish working with that, It explicitly gives a chance for garbage collector to recollect memory as early as possible, which in turn affects performance.

cnDB.close();

Close statement object as soon as you finish working with that, It explicitly gives a chance for garbage collector to recollect memory as early as possible which in turn affects performance.

JSP and Beyond 2007

56

Digging In Updating Data within a Database An update is very similar to the insert above, the only difference being the SQL that is passed into the executeUpdate method of the statement object.
// Obtain a statement object Statement stmt = cnDB.createStatement(); // Execute the block of SQL code stmt.executeUpdate(“UPDATE tblCustomer SET Name = 'Bob' WHERE CUSTOMERID = 21”); // Close the result set stmt.close(); // Close the connection cnDB.close();

Statement stmt = cnDB.createStatement();

Assuming that you are already using the cnDB database connection object, you can create a statement object that allows you to add a record to the database.

stmt.executeUpdate(“UPDATE tblCustomer SET Name = 'Bob' WHERE CUSTOMERID = 21”);

With the stmt Statement object you can leverage the executeUpdate method to accept your SQL string with the update SQL as shown above.

stmt.close();

Close statement object as soon as you finish working with that. It explicitly gives a chance for garbage collector to recollect memory as early as possible, which in turn affects performance.

cnDB.close();

Close statement object as soon as you finish working with that. It explicitly gives a chance for garbage collector to recollect memory as early as possible, which in turn affects performance.

Deleting Data from a Database Just as in the above example, the Statement object stmt, will be used to execute SQL by way of the executeUpdate method.
JSP and Beyond 2007 57

Digging In

// Obtain a statement object Statement stmt = cnDB.createStatement(); // Execute the block of SQL code stmt.executeUpdate(“DELETE FROM tblCustomer WHERE CUSTOMERID = 21”); // Close the result set stmt.close(); // Close the connection cnDB.close();

Statement stmt = cnDB.createStatement();

Assuming that you are already using the cnDB database connection object, you can create a statement object that will allow you to add a record to the database.

stmt.executeUpdate(“DELETE FROM tblCustomer WHERE CUSTOMERID = 21”);

With the stmt Statement object you can leverage the executeUpdate method to accept your SQL string with the delete SQL as shown above.

stmt.close();

Close statement object as soon as you finish working with that It explicitly gives a chance for garbage collector to recollect memory as early as possible, which in turn affects performance.

cnDB.close();

Close statement object as soon as you finish working with that. It explicitly gives a chance to garbage collector to recollect memory as early as possible, which in turn affects performance.

JDBC is an essential component for application development. From the information above you should now have a good grasp on the fundamentals, allowing you to perform CRUD within your own applications. For more information, an excellent amount of detail about JDBC can be found at: http://java.sun.com/docs/books/tutorial/jdbc/basics/index.html

JSP and Beyond 2007

58

Digging In

What are JavaBeans?
It might sound strange, but there is nothing inherently special about JavaBeans. They are just blocks of Java code that follow a few standards. That being said, they are very useful.

Beans are a great way of representing an item such as a user or product. You can think of a bean as a bucket that you can place information into, take information out of or let it know that you need it to do some sort of operation and send you the result when it is done. The beauty is that when you interact with this bucket, you do not need to know anything regarding how it does its job because the inner workings are abstracted by “Getter” and “Setter” methods that broker access to the attributes of the bean.

“Getter” and “Setter” methods are created by adding “get” or “set” to the name of an attribute within the bean that you would like to interact with. For example, the attribute employeeFirstName would have a setter called setEmployeeFirstName.

Using beans within JSPs can help you separate the presentation (HTML) from the business logic. Leveraging this type of encapsulation is much better than writing Java code directly into your JSPs. Beans will make code easier to edit and maintain. They will also allow for reusability across any number of JSPs which will save you coding and testing time.

As we embrace more advanced features within the Java development world, beans will become even more important to the development. More advanced development frameworks like Struts and Java Server Faces use beans to maintain the state between requests, and pass data between presentation and business logic layers.

Although beans can be used directly within a JSP, they are generally sent to the JSP from a Servlet in a MVC type of framework. This chapter will not detail with that, but the MVC section of our sample application toward the end of the book will demonstrate this interaction. For the purposes of this chapter, we will only cover the basics by using a simple bean like the one outlined below.

JSP and Beyond 2007

59

Digging In

The above bean contains a few components. The “attributes” hold the person’s first name, last name, age and email address. It allows developers to access these attributes and set all of them, with the exception of the person’s age, through “getters” and “setters”. This is a nice benefit of a bean in that it can be designed to allow updates to only certain portions of the bean’s contents. In addition to these attributes and “getters” and “setters”, the bean also provides two methods, one to calculate pay for the employee and the other to give the employee a pay raise. To put the above example into the context of a Java class you can review the code for this bean below.

SamplePersonBean.java package JSPBeyond; public class SamplePersonBean { private private private private String firstName; String lastName; String emailAddress; int age;

public SamplePersonBean() { JSP and Beyond 2007 60

Digging In

} public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmailAddress() { return emailAddress; } public void setEmailAddress(String emailAddress) { this.emailAddress = emailAddress; } public int getAge() { return age; } public void givePayRaise () { // Add code here to give more $! } public int calculatePay () { // Figure out what the employee's pay and then send back the result Return 1; } }

JSP and Beyond 2007

61

Digging In

Attributes of a Bean
When accessing beans through a JSP, you need to create an instance of them by setting a series of attributes. The following block of code provides an example of a bean that is called “calendar” and will only live for the current request. It is created from the com.mycompany.Calendar class.

<jsp:useBean id="calendar" scope="page" class="com.mycompany.Calendar" />

id

The name that we will use to refer to the bean after it is created.

class

The class contains the fully qualified name of the class for the bean. This is the fully qualified name for the class such as “com.mycompany.Calendar”.

type

This defines the object type that the bean will return (String, Int or another type or object). Our example above does not return a type.

scope

Each bean lives for a certain amount of time. The value for the scope can reference the page, request, session or application types.

• •

Page - The bean is valid only for the current request. Request - The bean is valid only for the current request. This is not a typo, even though it is very similar to the above Page scope. The difference is that the request scope will make the information in the bean available to any other JSPs that are accessed via <jsp:include> or <jsp:forward> actions. Session - The bean will persist over the lifespan of the user’s session. Application - Similar to the session, but applied globally. If we place a bean in the application scope it will be available across all user sessions.

• •

JSP and Beyond 2007

62

Digging In

Accessing a Bean
Beans can be accessed in a variety of ways. Once again, the beauty of using a bean is that an HTML developer can actually call a bean into their JSP page without having to know how to code Java, and yet can still access the rich functionality provided by the JSP. To provide this level of abstraction, JavaBeans have three ways in which you can interact with them through JSP which are outlined below through the use of XML tags.

1. In order to use a JavaBean it must be instantiated on the JSP page. This is done using the following code block:

<jsp:useBean id=”mynewbean” class=”com.yourclassname” scope=”request”>

Using this line of code, the container is smart enough to see if the object already exists and if not creates a new one with the attributes provided.

2. Setting a value for a bean is done through the setProperty action. Whatever code exists within the method for this attribute will execute upon this set.

<jsp:setProperty name=”newsfeed” property=”topic” value=”weather”/>

3. Getting content from a bean. Whatever code exists within the method for this attribute will execute upon this set.

<jsp:useBean id="calendar" scope="page" class="com.mycompany.Calendar" /> <h2> Calendar of <jsp:getProperty name="calendar" property="username" /> </h2>

Beans can also be accessed through scriptlets, just as though you were directly using a method from a class. It is not a good practice to return HTML markup from a bean. If development of tabled structures for lists or other presentation of collections is needed, it

JSP and Beyond 2007

63

Digging In is best practice to return a collection or record set from the bean and deal with displaying the contents through the use of additional scriptlet markup or JSTL. The example below outlines one such approach.

<%@ page contentType="text/html" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <% // Popultate an array with the values from our bean for the customer listing java.util.ArrayList alCustomers = JSPBeyond.CustomerBean.GetCustomerRecords(); // Set the "CustomerListing" attribute so it can hold the array for access later within this page request.setAttribute("CustomerListing", alCustomers); %> <html> <head> <title>JSP and Beyond - Customer List - Bean Example</title> </head> <body> <h1>Customer List - Bean and JSTL Example</h1> <table width="100%" border="1"> <tr> <td colspan="4">Customer</td> </tr> <%-- Start a loop through the results from the SQL query and mix it with HTML --%> <c:forEach var="row" items="${CustomerListing}"> <tr> <%-- Notice how with each "row" object we can access the column name by specifying it after the "row" object --%> <td><a href="CustomerList-Bean.jsp?shownotes=<c:out value="${row.customerID}"/>">show notes</a> <c:out value="${row.customerName}"/></td> <td><a href="CustomerEdit-Bean.jsp?CustomerID=<c:out value="${row.customerID}"/>">edit</a></td> <td><a href="NoteAdd-Bean.jsp?CustomerID=<c:out value="${row.customerID}"/>">add note</a></td> <td><a href="CustomerDelete-Bean.jsp?CustomerID=<c:out value="${row.customerID}"/>">delete</a></td> JSP and Beyond 2007 64

Digging In

</tr> </c:forEach> </table> </body> </html>

Please note that the following code would generally exist in a Servlet and then be sent to the JSP if you were using an MVC framework, by using the request.setAttribute code as shown below.

// Popultate an array with the values from our bean for the customer listing java.util.ArrayList alCustomers = JSPBeyond.CustomerBean.GetCustomerRecords(); // Set the "CustomerListing" attribute so it can hold the array for access later within this page request.setAttribute("CustomerListing", alCustomers);

The code would remain the same as the one in our scriptlet. This approach is detailed toward the end of the book.

Building and Deploying a Bean
We are going to be pragmatic with our approach in this section of the book, so this is where you will let an IDE do what it does best and assist with your beans. A class file that represents the bean that you are working with in the IDE will be compiled into byte code when you use the IDE to “build and deploy” your project. The bytecode class file is the equivalent of a DLL for those familiar with Microsoft technologies.

As stated in the prior segment, beans are just regular Java classes with a bit of special structure provided by “getters” and ”setters”. This means that by using the Java Compiler (javac.exe), you can build it from the command line as in the example below, but the IDE just does it so much better. The IDE below (NetBeans) does an excellent job of helping you quickly build a project.

JSP and Beyond 2007

65

Digging In

Once the bean has been compiled, there are two options as to how to incorporate it into your project. You can include your newly compiled class file into a JAR and place it in the lib folder within your application server or place the class file under the WEB-INF folder.

Depending on what you have named your package, in the above example we used JSPBeyond, you need to move the class file under WEB-INF in accordance with the package name. For our sample we would move it into classes -> JSPBeyond under WEB-INF.

The diagram below highlights the folder structure containing application elements.

JSP and Beyond 2007

66

Digging In

After moving the files onto the application server, a restart is generally required in order to recognize the new files.

Developing with Tags – JSTL / EL
The Java Server Pages Standard Tag Library (JSTL) enables us to bring commonly needed web actions and components out of scriptlets and into easy to use tag libraries. JSTL is generally used in conjunction with another “tag” style markup called expression language, or EL, to build non-scriptlet JSP solutions. Since JSTL and EL are standards, they are supported by all containers that are JSP 1.2 and beyond compliant. This makes them portable between different application servers, and they are guaranteed to run on any application server that supports the JSP 1.2 specification and beyond.

JSP and Beyond 2007

67

Digging In That being said, it is important not to go overboard with this technology when developing applications. JSTL is very powerful and can even connect to databases using certain tags, but that is not always the best way to include that type of functionality. To get the most out of JSP, you should keep the majority of logic- and settings-related-markup out of your JSP pages and in reusable components (i.e. beans or other classes) whenever possible; and then use JSTL and EL to focus on displaying the contents of those objects and not retrieving or manipulating the data.

Java Server Pages Standard Tag Library (JSTL)
JSTL consists of a few libraries. Each one of these libraries provides slightly different capabilities as highlighted below.

Tag Library Core (c)

Description Variable support, management conditionals, URL

XML (x) Internationalization (fmt)

Core, Flow control, Transformation Locale, Message formatting, Number and date formatting SQL query and update Collection length, String manipulation

Database (sql) Function (fn)

This chapter will focus on the Core library, since once you understand how the libraries can be used it is relatively trivial to implement the one that will meet your needs.

Accessing JSTL In order to use JSTL you need to make sure to reference the specific tag set within JSTL that you would like to use in the body of the JSP.
<%-- Core --%> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>

JSP and Beyond 2007

68

Digging In

<%-- I18N Formatting --%> <%@ taglib uri="/WEB-INF/tld/fmt-rt.tld" prefix="fmt_rt" %> <%-- SQL --%> <%@ taglib uri="/WEB-INF/tld/sql-rt.tld" prefix="sql_rt" %> <%-- XML --%> <%@ taglib uri="/WEB-INF/tld/x-rt.tld" prefix="x_rt" %>

As “core” would indicate, the core library contains some of the most used tags from the JSTL. Below is a listing of the core types along with samples.

Working with Variables Using JSTL it is possible to set and remove variables within the JSP page. The following example set the accountHistory variable with the value from a JavaBean called “account” using the set tag.
<c:set var=”accountHistory” value=”${account.history}”>

Expression JSTL has the ability to display object attribute and variable information very easily. The example below renders the username from the bean called “customer” using the out tag.
<jsp:useBean id="user" class="com.jspbeyond.user"/> Welcome <c:out value="${user.displayname}" />!

Iteration One of the biggest challenges that I have encountered with iteration is the understanding of exactly what objects can be used to iterate through. java.util.Collection, java.util.Map, java.util.Iterator, java.util.Enumeration, an array of object instances and javax.Servlet.jsp.jstl.sql.Result can all be used as the object that an iteration can be based on. In the code sample below, assume that you have an array called “customerList” containing a list of beans representing customers.

<table> JSP and Beyond 2007 69

Digging In

<c:forEach items="${customerList}" var="customer"> <tr><td> <c:out value="${customer.name}" /> </td></tr> <tr><td> <c:out value="${customer.contactInfo}" /> </td></tr> </c:forEach> </table>

With the above example, you are able to merge your dynamic elements with the HTML template. This allows maximum control over the look and feel of the page that is displayed to users and lets developers and designers focus on their respective disciplines.

Conditionals JSTL provides an elegant way to conditionally display content. The following block uses an “if” conditional.
<c:if test="${user.loggedin}"> <tr> <td> <c:out value="${user.password}"/> </td> </tr> </c:if>

The code block below uses a “choose” conditional. The choose conditional is best applied when various matches are possible.
<c:choose> <c:when test="${user.team == 'Management'}"> Project is on time! </c:when> <c:when test="${user.team == 'Developer'}"> Great job coding! </c:when> <c:otherwise> Not sure why you are here! </c:otherwise> </c:choose>

JSP and Beyond 2007

70

Digging In

Beyond the examples above, you will see that during form validation, JSTL conditionals can be very helpful.

URL Management JSTL provides some innovative ways to interact with page flow and incorporating content from other JSPs. This is done through three tags: “import”, “redirect” and “url”. For each one of the tags, it is also possible to specify parameters that are passed along with the request.

The following example highlights the use of the import tag.
<!-- This example gets content from welcomeheader.jsp and injects it into the page --> <c:import url="welcomeheader.jsp" /> <!-- This example requests a URL with the parameter “myparam” set to 1 --> <c:import url=”mypagewithparameter.jsp”> <c:param name=”myparam” value=”1” /> </c:import>

The redirect tag works much the same way as the import tag, allowing you to pass along arguments with the request in the URL.
<c:redirect url="accountView.jsp"> <c:param name="id" value="${id}"/> </c:redirect>

When you need to ensure that a URL is properly formatted, the “url” tag does a nice job of handling things such as automatic encoding.
<c:url value="listproducts.jsp"> <c:param name="category" value="outdoor camping gear"/> </c:url>

JSP and Beyond 2007

71

Digging In Exception Handling with Try / Catch Just at with any code that is written, it is always good to make sure that you can handle errors gracefully. JSTL provides a nice way to do this directly in the JSP as follows.
<c:catch var="testexception"> <!-- Do something REALLY bad here to cause an error --> </c:catch> <c:out value="${ testexception.message}"/>

Expression Language (EL)
Expression language provides an easy way to access information from a variety of objects directly within the body of a JSP, and send the resulting information into an attribute for a JavaBean or JSTL element. EL can get information from implicit objects and/or custom objects and variables that you may have in scope.

Looking at many of the examples in the prior section, you can see that there were instances where we accessed data in a format like ${somedata.here}. This is EL. The close relationship between JSTL and EL is why many people lump them into a single category, although they are ultimately different technologies.

That being said, some of the best, most common uses, would be leveraging EL Implicit Objects directly in the JSP. For instance, the following section of EL retrieves the query string variable called username.
How are you ${param.username}?

Beyond accessing information from objects, EL also has the ability to leverage operators. This allows blocks of code to execute conditionally when combined with JSTL as illustrated below.
<c:if test="${user.age >= 16}"> You can drive! </c:if>

JSP and Beyond 2007

72

Digging In Operators like ==, !=, <, >, >= or <= can all be used to make decisions with EL. For example, using the above operators lets you perform conditional evaluations directly in your JSPs
Is a one the same as a two? ${1==2}

Tags in Action - Examples
The following two JSPs are from our reference application, and demonstrate how much cleaner the template (HTML) markup can be when scriptlets are replaced with JSTL, keeping any serious Java code out of the presentation layer. CustomerList-Scriptlet.jsp shows a version of a page using scriptlets and CustomerList-JSTL.jsp shows a cleaned up version using JSTL.

CustomerList-Scriptlet.jsp <%@page import="java.sql.*" %> <html> <head> <title>JSP and Beyond - Customer List - Scriptlet Example</title> </head> <body> <h1>Customer List - Scriptlet Example</h1> <% Connection conn = null; // Reference the JDBC driver Class.forName("com.mysql.jdbc.Driver").newInstance(); conn = DriverManager.getConnection("jdbc:mysql:///YourDatabaseName","Databa seUser", "Password"); Statement stmt = conn.createStatement(); // Set the SQL query ResultSet rs = stmt.executeQuery("SELECT * FROM tblCustomer ORDER BY CustomerName"); // Start our table tag out.println("<table width=\"100%\" border=\"1\">"); out.println("<tr><td colspan=\"4\">Customer</td></tr>");

JSP and Beyond 2007

73

Digging In

while(rs.next()) { out.println("<tr><td>"); // Render a link that will let this page show notes out.println("<a href=\"" + request.getRequestURI() + "?shownotes=" + rs.getString("CustomerID") + "\">show notes</a>"); // Render the Customer name out.println(rs.getString("CustomerName") + "</td>"); // Render the customer type //out.println(rs.getString("CustomerType") + "</td><td>"); // Render edit link out.println("<td><a href=\"CustomerEditScriptlet.jsp?CustomerID=" + rs.getString("CustomerID") + "\">edit</td>"); // Render add note link out.println("<td><a href=\"NoteAdd-Scriptlet.jsp?CustomerID=" + rs.getString("CustomerID") + "\">add note</td>"); // Render delete customer link out.println("<td><a href=\"CustomerDeleteScriptlet.jsp?CustomerID=" + rs.getString("CustomerID") + "\">delete</td>"); out.println("</tr>"); // Check to see if show details is enabled if (request.getParameter("shownotes") != null) { if (request.getParameter("shownotes").equals(rs.getString("CustomerID")) | request.getParameter("shownotes").equals("all")) { Statement stmtDetails = conn.createStatement(); // Set the SQL query ResultSet rsDetails = stmtDetails.executeQuery("SELECT * FROM tblNote WHERE CustomerID = " + rs.getString("CustomerID")); while(rsDetails.next()) {

JSP and Beyond 2007

74

Digging In

// Render the customer type out.println("<tr><td colspan=\"4\">" + rsDetails.getString("Note") + " - <a href=\"NoteDeleteScriptlet.jsp?NoteID=" + rsDetails.getString("NoteID") + "\">delete</a></td></tr>"); } rsDetails.close(); stmtDetails.close(); } } } // Close our table out.println("</table>"); // Close the connections to database objects to free resources stmt.close(); conn.close(); %> <br> <a href="CustomerAdd-Scriptlet.jsp">Add a New Customer</a> | <a href="CustomerList-Scriptlet.jsp?shownotes=all">Show all Notes</a> </body> </html>

CustomerList-JSTL.jsp <%-- Let the system know that we are using JSTL and load the proper prefixs --%> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <%@ taglib prefix="sql" uri="http://java.sun.com/jstl/sql_rt" %> <html> <head> <title>JSP and Beyond - Customer List - JSTL Example</title> </head> <body> <h1>Customer List - JSTL Example</h1> <%-- Let the system know what datasource we will speak with --%> <sql:setDataSource var="dataSource" url="jdbc:mysql://localhost/YourDatabaseName" JSP and Beyond 2007 75

Digging In

driver="com.mysql.jdbc.Driver" user="DatabaseUser" password="Password" /> <sql:query var="queryResults" dataSource="${dataSource}"> <%-- Place our SQL query here within the XML tag "sql:query" --%> SELECT * FROM tblCustomer ORDER BY CustomerName </sql:query> <table width="100%" border="1"> <tr> <td colspan="4">Customer</td> </tr> <%-- Start a loop through the results from the SQL query and mix it with HTML --%> <c:forEach var="row" items="${queryResults.rows}"> <tr> <%-- Notice how with each "row" object we can access the column name by specifying it after the "row" object --%> <td><a href="CustomerList-JSTL.jsp?shownotes=<c:out value="${row.CustomerID}"/>">show notes</a> <c:out value="${row.CustomerName}"/></td> <td><a href="CustomerEdit-JSTL.jsp?CustomerID=<c:out value="${row.CustomerID}"/>">edit</a></td> <td><a href="NoteAdd-JSTL.jsp?CustomerID=<c:out value="${row.CustomerID}"/>">add note</a></td> <td><a href="CustomerDelete-JSTL.jsp?CustomerID=<c:out value="${row.CustomerID}"/>">delete</a></td> </tr> <c:if test="${(row.CustomerID) == (param.shownotes) or (param.shownotes) == 0}"> <sql:query var="queryDetailResults" dataSource="${dataSource}"> <%-- Place our SQL query here within the XML tag "sql:query" --%> SELECT * FROM tblNote WHERE CustomerID = ? <sql:param value="${row.CustomerID}" /> </sql:query> <c:forEach var="rowDetail" items="${queryDetailResults.rows}"> <tr><td colspan="4"><c:out value="${rowDetail.Note}"/> - <a href="NoteDelete-JSTL.jsp?NoteID=<c:out value="${rowDetail.NoteID}"/>">delete</a></td></tr> </c:forEach> </c:if> </c:forEach> </table>

JSP and Beyond 2007

76

Digging In

<br> <a href="CustomerAdd-JSTL.jsp">Add a New Customer</a> | <a href="CustomerList-JSTL.jsp?shownotes=0">Show all Notes</a> </body> </html>

Not only is the above code easier to read, the code block is also much shorter. It is easy to see how JSTL can make code much easier to read and maintain.

Developing Custom Tags
Custom Tags were introduced with the introduction of the JSP 1.1. They represented a major step forward in being able to further separate HTML markup from complex Java code. Given this, you might ask why they are so great when we have Java Beans and the Include JSTL tag? Don’t they provide that same functionality?

So far we have examined an inline Java code <% some Java code here %>, JavaBeans and JSTL as various ways to place dynamic content into the presentation layer. Inline Java code is messy and breaks JSPs best practices, and JavaBeans are not meant to return HTML markup to a JSP, but rather to provide objects from which data can be stored and retrieved.

Custom tags give you the best of both worlds and then some. In this examination we will cover the JSP 2.0 tags which, without diving into details, are much easier to develop and use than the first series of tags that JSP introduced.

Custom Tags allow you to place XML-style markup within your HTML which provides rich functionality, completely separating complex code from your JSP presentation layer. Custom Tags let developers develop and designers design, strictly isolating both job functions.

Custom Tags let tag developers access intrinsic objects related to the JSP, unlike a JavaBean where these objects are not easily accessible.

JSP and Beyond 2007

77

Digging In

So what do you need to do to create a custom tag?

1. Create a TLD file that tells the application server what your tags do. An example of this is the description, price and comments for a product that you might purchase on Amazon. It lets the system know what your tag’s name is, what class contains the code for it and what inputs it might take. 2. Create a class that implements the javax.Servlet.jsp.tagext.SimpleTagSupport interface. This allows the class to do all of the heavy lifting behind the scenes in order to produce HTML output to send back into your page template. 3. Place the tag markup inside the JSP markup along with a reference to the TLD in the page of your choice, and let it work its magic!

Custom tags are so powerful that it is worthwhile to spend some additional time walking through an example of building a trivial one. Let’s walk through an example of creating a “Hello World” custom tag.

Keeping in the spirit of our pragmatic approach to this development, let’s use NetBeans to make the custom tag. It is an excellent way for you to see what needs to happen to properly build the tag with minimal effort. Once you have built the tag, we can review the files that the IDE created in order for you to gain a deeper understanding of the code.

The latest version of the NetBeans IDE can be downloaded from: http://www.netbeans.org/downloads/

1. Launch NetBeans and Open an existing Web Project (you can use the JSPandBeyond project) 2. Go to “File” > “New File…” 3. Select “Tag Library Descriptor” and the click “Next >”

JSP and Beyond 2007

78

Digging In

4. Fill out the “TLD Name” field. Our example uses “jspandbeyondtags”. Then select a folder to place the new TLD in. “WEB-INF/tlds” is the default folder, and for consistency you should place it there. Click “Finish” to complete the wizard and have the TLD created.

JSP and Beyond 2007

79

Digging In

The new TLD should look like the image below. You can see how much work the IDE was able to do for us, helping to minimize errors and save time.

JSP and Beyond 2007

80

Digging In

Now that you have the basic skeleton of the TLD file, let’s create the tag file that will be added to the TLD to be used within your JSPs. 1. Go to “File” > “New File…” 2. Select “Web” as the Category and “Tag Handler” as the “File Types” as shown below, then click “Next >”. The “Tag Handler” will represent a tag in your application and is a java class that implements the SimpleTagSupport interface.

JSP and Beyond 2007

81

Digging In

3. Fill in the “Class Name” field. In our example we are using “customtagtest”. Then select the Package that the new class will go into. For our example we are selecting “JSPBeyond”. The click “Next >”. Packages are a helpful way to bundle related class files.

JSP and Beyond 2007

82

Digging In

4. The next screen “TLD Information” does a very nice job of setting the contents in the TLD file automatically for the new tag. Notice the checkbox at the top of the wizard that says “Add Corresponding Tag to the Tag Library Descriptor”. This will automatically append / adjust the file with the information about our new tag. We will also need to browse through the TLD that we want to add the information into. In this case we are going to select “jspandbeyondtags.tld”. 5. We will also add an “attribute” by clicking “New…” in the attributes section, and then create an attribute Name called “username” as a String.

JSP and Beyond 2007

83

Digging In

6. Click “Finish” to save your new custom tag. Notice how when the wizard closes, you now have a new class within the JSPBeyond package called “customtagtest”.

JSP and Beyond 2007

84

Digging In

Now that the wizard is completed, you have a Java file that can be used to make your tag function. The bolded area below is where you can write all of the code to send HTML into your JSP where the tag has been placed. Also notice that the line containing “private java.lang.String username;” references the attribute that we added.

package JSPBeyond; import javax.Servlet.jsp.tagext.*; import javax.Servlet.jsp.JspWriter; import javax.Servlet.jsp.JspException; public class customtagtest extends SimpleTagSupport { /** * Initialization of username property. */ private java.lang.String username; /**Called by the container to invoke this tag. * The implementation of this method is provided by the tag library developer, * and handles all tag processing, body iteration, etc.

JSP and Beyond 2007

85

Digging In

*/ public void doTag() throws JspException { JspWriter out=getJspContext().getOut(); try { // TODO: insert code to write html before writing the body content. // e.g.: // // out.println("<strong>" + attribute_1 + "</strong>"); // out.println(" <blockquote>"); JspFragment f=getJspBody(); if (f != null) f.invoke(out); // TODO: insert code to write html after writing the body content. // e.g.: // // out.println(" </blockquote>"); } catch (java.io.IOException ex) { throw new JspException(ex.getMessage()); } } /** * Setter for the username attribute. */ public void setUsername(java.lang.String value) { this.username = value; } }

Now that you have your custom tag class and TLD file, let’s create a JSP that leverages it. This is the Directive that needs to be added to the JSP to let it know that you have custom tags that it can use
<%@ taglib prefix="customtagtest" uri="/WEBINF/tlds/jspandbeyondtags" %>

Notice the prefix “customtagtest” that indicates that this will be the name of the tag that will be used to implement your custom functionality. For our sample we have changed
JSP and Beyond 2007 86

Digging In the bold area to only include “out.println("<strong>Welcome to JSP " + username + "!</strong>");”. After doing this you can right click on our project “JSPandBeyond” and select “Clean and Build Project”. This compiles the code.

In the above code sample we have added a line of code that references our TLD file, and NetBeans is able to recognize our custom tag. By recognizing the tag, NetBeans lets you know what attributes are part of your custom tag and what information you can send into those attributes. In our sample we are able to set an attribute for “username” with the following code:

<customtagtest:customtagtest username="Bob"></customtagtest:customtagtest>

This code within the JSP will result in the following output when our JSP is requested in a browser.

JSP and Beyond 2007

87

Digging In

Here are the underlying files that were created in the process that made it possible to use our new custom tag. Notice that there is now a tag name called “customtagtest” that has been added.

jspandbeyondtags.tld <?xml version="1.0" encoding="UTF-8"?> <taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee webjsptaglibrary_2_0.xsd"> <tlib-version>1.0</tlib-version> <short-name>jspandbeyondtags</short-name> <uri>/WEB-INF/tlds/jspandbeyondtags</uri> <tag> <name>customtagtest</name> <tag-class>JSPBeyond.customtagtest</tag-class> <body-content>scriptless</body-content> <attribute> <name>username</name> <rtexprvalue>true</rtexprvalue> <type>java.lang.String</type> </attribute> JSP and Beyond 2007 88

Digging In

</tag> </taglib>

TagSample.jsp <%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <%@ taglib prefix="customtagtest" uri="/WEBINF/tlds/jspandbeyondtags" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF8"> <title>JSP Page</title> </head> <body> <h1>JSP Page</h1> <customtagtest:customtagtest username="Bob"></customtagtest:customtagtest> </body> </html>

customtagtest.java package JSPBeyond; import javax.Servlet.jsp.tagext.*; import javax.Servlet.jsp.JspWriter; import javax.Servlet.jsp.JspException; /** * * @author jbrunswi * @version */ public class customtagtest extends SimpleTagSupport { /** * Initialization of username property.

JSP and Beyond 2007

89

Digging In

*/ private java.lang.String username; /**Called by the container to invoke this tag. * The implementation of this method is provided by the tag library developer, * and handles all tag processing, body iteration, etc. */ public void doTag() throws JspException { JspWriter out=getJspContext().getOut(); try { out.println("<strong>Welcome to JSP " + username + "!</strong>");

} catch (java.io.IOException ex) { throw new JspException(ex.getMessage()); } } /** * Setter for the username attribute. */ public void setUsername(java.lang.String value) { this.username = value; } }

Although there is some initial setup required, once you have the basics for tag creation established it is easy to quickly add additional functionality.

Sending Email
Sending email from your JSPs is easy, but requires some configuration. In order to send email from your application you will unfortunately need to add some components to your application. The Java Mail API (http://java.sun.com/products/javamail/) is the most common way to include the toolset to send email. The Java Mail API is accessible via the mail.jar. The latest version of the mail.jar can be downloaded from:
JSP and Beyond 2007 90

Digging In https://maven-repository.dev.java.net/nonav/repository/javax.mail/jars/

Once you have downloaded the jar, it can be placed within the “web-inf/lib” folder within your application server which makes it accessible to any applications running on that application server. The code below will then leverage that information in that jar file to send an email.

<%@ page import="sun.net.smtp.SmtpClient, java.io.*" %> <% String sSender="youremail@yourhost.com"; String sRecipient="reciptient@theirhost.com"; try{ SmtpClient client = new SmtpClient("our.mailserver.com"); client.from(sSender); client.to(sRecipient); PrintStream message = client.startMessage(); message.println("Testing… 123…"); client.closeServer(); } catch (IOException e){ System.out.println("Things did not go as planned"+e); } %>

Looking at the above code it becomes obvious that a scriptlet is probably not the best way to handle this, since it can be error-prone and makes it difficult for a designer to use within an HTML page. This is where using a Customer Tag or JavaBean would be very effective, and using the mail.jar we can easily create one.

File Uploads
Similar to the email functionality covered in the previous section, you will need to go some extra distance to enable file uploads from within your JSP-based application. This is important because most web-based applications will need to accept files at some point, whether a document or image. When a web page is submitted that contains a file to be uploaded, the data is sent as a HTTP POST encoded using the MIME-type

JSP and Beyond 2007

91

Digging In multipart/form-data. You will have to manually handle the stream to combine it back into the original file within your code where it can then be saved on your server.

Thankfully, people have realized this and created pre-packaged beans and classes to handle file uploads. Some are commercial, but fortunately the Apache Foundation has developed a library to help manage uploads that is freely available at:

http://jakarta.apache.org/commons/fileupload/

The code sample below highlights the code from Apache foundation.

public void doPost(HttpServletRequest req, HttpServletResponse res) { DiskFileUpload fu = new DiskFileUpload(); // maximum size before a FileUploadException will be thrown fu.setSizeMax(1000000); // maximum size that will be stored in memory fu.setSizeThreshold(4096); // the location for saving data that is larger than getSizeThreshold() fu.setRepositoryPath("/tmp"); List fileItems = fu.parseRequest(req); // assume we know there are two files. The first file is a small // text file, the second is unknown and is written to a file on // the server Iterator i = fileItems.iterator(); String comment = ((FileItem)i.next()).getString(); FileItem fi = (FileItem)i.next(); // filename on the client String fileName = fi.getName(); // save comment and filename to database ... // write the file fi.write("/www/uploads/" + fileName); }

JSP and Beyond 2007

92

Digging In

Capturing User Input with Forms
Working with forms in JSP is pretty straightforward, but does require a lot of hands-on code weaving. By this I mean that the individual form fields each need extra attention after the post for your application in order to capture and store data. There are some more advanced ways of dealing with handling the data after the post, which will be detailed after this basic example, that reduce the amount of work that needs to be done to handle the transactions.

When we are taking a basic approach to form handling we can use the following methods from the request object to grab each element from the form that was submitted.

getParameter

getParameter allows you to directly access a parameter from the request if you know the name of the parameter. An example that would retrieve the value for a form variable called “username” would be written as follows:
String sUserName = request.getParameter(“username”);

getParameterNames

getParameterNames returns a collection of each parameter name as a string. This is a good tool to use when attempting to debug a form when you are not entirely sure what is being sent to the target page. The following code sample will return a listing of all of the different form items with the parameter names (key) and values (value).

<%@ page contentType="text/html" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <c:forEach var='parameter' items='${paramValues}'> <c:out value='${parameter.key}'/> : <c:forEach var='value' items='${parameter.value}'> <c:out value='${value}'/> </c:forEach> <hr> </c:forEach>

The following modified sample from the reference application uses a very basic, manually handled request process to complete the action of adding a customer account.

JSP and Beyond 2007

93

Digging In The form is just simple HTML and contains form data that will be posted to “CustomerAddCommit-Scriptlet.jsp”.

CustomerAdd-Scriptlet.jsp (modified here for simplicity) <%@page import="java.sql.*" %> <html> <head> <title>JSP and Beyond - Add Customer - Scriptlet Example</title> </head> <body> <h1>Add Customer - Scriptlet Example</h1> <form method="post" action="CustomerAddCommit-Scriptlet.jsp"> Add Customer <input type="text" name="Customer"> <input type="hidden" name="CustomerID" value="<%= request.getParameter("CustomerID") %>"> <input type="hidden" name="action" value="add"> <br><br> <input type="submit" value="Add Note"> </form> </body> </html>

The following code block will then take all of the form data (post data) from the example above and store it in your database.

CustomerAddCommit-Scriptlet.jsp <%@page import="java.sql.*" %> <html> <head> <title>JSP and Beyond - Add Customer - Scriptlet Example</title> </head> <body> <% if (request.getParameter("CustomerName") != null) { try { Connection conn = null; // Reference the JDBC driver JSP and Beyond 2007 94

Digging In

Class.forName("com.mysql.jdbc.Driver").newInstance(); conn = DriverManager.getConnection("jdbc:mysql:///DatabaseName","DatabaseUs er", "Password"); Statement stmt = conn.createStatement(); String sCustomerName = request.getParameter("CustomerName").toString(); stmt.executeUpdate("INSERT INTO tblCustomer (CustomerName) VALUES ('" + sCustomerName + "')"); // Close any connectivity that we had to the database to free resources stmt.close(); conn.close(); } catch (Exception ex) { out.println("An Error has Occured: " + ex.toString()); } %> <h1>Add Customer - Customer Added</h1> <br> <a href="CustomerList-Scriptlet.jsp">Main Menu</a> <% } else { %> <h1>Add Customer - Customer Name Empty</h1> <br> <a href="CustomerAdd-Scriptlet.jsp">Go back and try again</a> <% } %> </body> </html>

Following is the complete example from the reference application where all of the code that allows a customer to be added is included. This is a slightly different approach that helps you reduce the number of JSPs required to create an application. You can see that the form posts to request.getRequestURI(), which is itself! Within the page code, the JSP will then decide whether it must display a data entry screen (if

JSP and Beyond 2007

95

Digging In (request.getParameter("action") == null)) or if it will store the data from the form post back to itself (else if (request.getParameter("action").equals("add"))).

CustomerAdd-Scriptlet.jsp <%@page import="java.sql.*" %> <html> <head> <title>JSP and Beyond - Add Customer - JSTL Example</title> </head> <body> <h1>Add Customer - JSTL Example</h1> <% if (request.getParameter("action") == null) { %> <h1>Add Customer - Scriptlet Example</h1> <form method="post" action="<%= request.getRequestURI() %>"> Add Customer <input type="text" name="Customer"> <input type="hidden" name="CustomerID" value="<%= request.getParameter("CustomerID") %>"> <input type="hidden" name="action" value="add"> <br><br> <input type="submit" value="Add Note"> </form> <% } else if (request.getParameter("action").equals("add")) { Connection conn = null; // Reference the JDBC driver Class.forName("com.mysql.jdbc.Driver").newInstance(); conn = DriverManager.getConnection("jdbc:mysql:///DatabaseName","DatabaseUs er", "Password"); Statement stmt = conn.createStatement(); //String sNote = request.getParameter("Note").toString(); String sCustomerName = request.getParameter("CustomerName"); stmt.executeUpdate("INSERT INTO tblCustomer (CustomerName) VALUES ('" + sCustomerName + "')");

JSP and Beyond 2007

96

Digging In

// Close any connectivity that we had to the database to free resources stmt.close(); conn.close(); %> <h1>Customer Add - Customer Added</h1> <br> <a href="CustomerList-Scriptlet.jsp">Return to Main Menu</a> <% } %> </body> </html>

One of the nice things about JavaBeans is the ability to leverage them for data storage from forms. The examples below highlight using a bean.to collect the data from a form post. This is done by using the following block of code in the FormToStore.jsp shown after the FormToBean.jsp below. It is interesting to note that in this sample code setting, the “property” attribute of the bean to a “*”, the bean will automatically map the input of form fields to attributes with the same names within the bean. It is a huge time saver.

<jsp:setProperty name="FormBean" property="*"/>

FormToBean.jsp <%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <html> <head> <title>Account Signup</title> </head> <body> <h1>Signup for Your Account</h1> <form action="FormToBeanStore.jsp" method=post> Username <input type="text" name="username"><br> Email <input type="text" name="email"><br> <input type="submit" value="Submit"> </form>

JSP and Beyond 2007

97

Digging In

</body> </html>

FormToStore.jsp <%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <html> <head> <title>Account Signup</title> </head> <body> <h1>Thanks!</h1> <jsp:useBean id="FormBean" class="JSPBeyond.FormBeanSample" scope="request"> <jsp:setProperty name="FormBean" property="*"/> </jsp:useBean> This is what you submitted!<br> Username <jsp:getProperty name="FormBean" property="username" /> <br> Email <jsp:getProperty name="FormBean" property="email" /> </body> </html>

Toward the end of this book I will review a very basic MVC framework that makes dealing with forms a bit easier, since you are able to handle the processing in a Java class.

Validating User Input:
JSPs do not inherently have any ability to provide basic form validation. Due to this, there are many different ways in which to augment the core that JSP provides to enable form validation for user input.

JSP and Beyond 2007

98

Digging In

JavaScript
JavaScript is a powerful client side tool that can help to validate forms by understanding each part of a form and comparing the values submitted with those that you would like to require. The only issue with JavaScript form validation is that you need to rely on the client side to process the form correctly. Some users disable JavaScript and malicious users can circumvent JavaScript-based form validation. This means that although it is an option (and perhaps the most common option to implement for web applications), it is not the most secure method of validation.

The sample below illustrates a form that validates a user’s email address to ensure that it conforms to a standard email address pattern.

<html> <head> <script type="text/javascript"> function validate_email(field,alerttxt) { with (field) { apos=value.indexOf("@") dotpos=value.lastIndexOf(".") if (apos<1||dotpos-apos<2) {alert(alerttxt);return false} else {return true} } } function validate_form(thisform) { with (thisform) { if (validate_email(email,"Not a valid e-mail address!")==false) {email.focus();return false} } } </script> </head> <body> <form action="submitpage.htm" onsubmit="return validate_form(this);" method="post"> Email: <input type="text" name="email" size="30"> <input type="submit" value="Submit"> </form>

JSP and Beyond 2007

99

Digging In

</body> </html>

For complete details on a range of JavaScript validation more information can be found at: http://www.w3schools.com/js/js_form_validation.asp

JSTL Form Validation
Validation using JSTL provides a few advantages over the above method. Namely the validation happens on the server side. It is fairly elegant and easy to use.

<%@ page contentType="text/html" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <html> <head> <title>JSTL Validation Test</title> </head> <body> <form action="JSTLValidation.jsp" method="post"> <input type="hidden" name="submitted" value="true"> <c:if test="${param.submitted && empty param.yourName}"> *Please submit a value for your name<br> </c:if> <c:choose> <c:when test='${not empty param.yourName}'> Thanks <c:out value='${param.yourName}'/>!<br> </c:when> <c:otherwise> *Please submit a value for your name<br> </c:otherwise> </c:choose> Your name <input type="text" name="yourName" value="<c:out value="${param.yourName}" />"> <input type="submit" value="submit"> </form> </body>

JSP and Beyond 2007

100

Digging In

Advanced Validation
With all of this being said more intricate frameworks like Struts and JSF provide additional tools to help with form validation as it is a staple of application development. These are beyond the scope of this primer, but we encourage you to dig in and check them out as they are becoming the preferred method for medium to large scale application development. We provide an overview of these frameworks in our Next Steps section.

When Things Go Wrong - Error Handling
JSP has some very nice ways of dealing with error handling. I touched on this a bit in the “Anatomy of a JSP Application” when Implicit Objects were reviewed, but a directive can be set called “errorPage” for the JSP Page to indicate where to go when an error occurs. When an exception happens, the current page forwards an exception object to the page specified.

This subsequent page needs to have the Page directive “isErrorPage” set to true to receive the exception. It can then access all of the attributes of the exception, which is useful for sending in an email or display in a user friendly way.

ThrowError.jsp <%@ page errorPage="CatchError.jsp"%> <!-- Hmmm... what happens if we do this? --> <% out.println((1/0)); %>

CatchError.jsp <%@ page isErrorPage="true" %> <!-- Show how bad we did --> <h1>Ouch! That hurt :(</h1> Here is what was so bad : <b><%= exception.getMessage() %></b>

JSP and Beyond 2007

101

Digging In

Notice that although we specified the CatchError.jsp to show the error, the end user will never see CatchError.jsp in the browser window. The error and output are all done under the covers and are not obvious to the user.

In reality you would probably want to do something more useful with the error, such as storing the error output in a utility bean that sends an email to a system administrator. As you can see, it is fairly straightforward to implement some gentle exception handling within JSP rather than showing an end user a very large, unfriendly stack trace.

Chapter Summary
This chapter has covered a tremendous amount of material about the specifics of elements that you can place into JSPs. Samples and explanations were provided for various technologies like JSTL, and custom tags to abstract any serious business logic or database interactions from our JSPs. You also learned that within your code it is possible to leverage many implicit objects which allow the retrieval of data from forms, the request object, user information from the session object and more. The basics of JDBC were also introduced, providing you with an easy way to connect to and manipulate databases. Common application functions like sending email and receiving a file and upload were also covered. For these special items you were made aware that special libraries need to be added to your projects to provide that functionality. Last, but in no way least, you also learned about gracefully handling errors within your JSPs. Given the amount of material in this chapter, I suggest reviewing any of the topics that might still present some confusion, as these elements comprise the core of JSP.

JSP and Beyond 2007

102

Reference Application

REFERENCE APPLICATION

The following sections will highlight a lot of the material that was covered throughout the book, and pull it together in a way that makes sense. The samples leverage a collection of files separated into a scriptlet sample, JSTL sample and MVC sample. Each one of these is meant to highlight how the same end user experience can be created with many different approaches, as they all ultimately create the same web application experience for end users.

The application that we are going to create is a small Customer Relationship Management (CRM) application. It will allow you to add customers into a database and then append notes onto each customer account. It will show you how to add, update and delete information from your database using a web front end. For each approach there are a few sample sections within this chapter that highlight the differences between each approach.

My hope is that from the code below you will have some good template materials to get started on developing your own web applications with the method that makes the most sense for your needs.

JSP and Beyond 2007

103

Reference Application

You can download the complete code set for the examples at: http://www.jspandbeyond.com/sourcecode

Chapter Goals
• Understand how scriptlets, JSTL and MVC development approaches can all be leveraged to solve the same business issue and provide the same end user experience Review JSTL samples Review scriptlet sample Learn about very basic MVC through a sample

• • •

The Database
For the reference application database we are using MySQL. You can download a copy at http://dev.mysql.com/downloads/. For the purpose of the sample application, I have kept the database very straightforward, only using two tables – one for customer information and the other to hold notes that you will want to append to the customer accounts. The following code will reproduce the database within MySQL.

-- MySQL Administrator dump 1.4 --- ------------------------------------------------------- Server version 5.0.19-nt

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */;

JSP and Beyond 2007

104

Reference Application

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;

--- Create schema DatabaseName -CREATE DATABASE /*!32312 IF NOT EXISTS*/ DatabaseName; USE DatabaseName; --- Table structure for table `DatabaseName`.`tblcustomer` -DROP TABLE IF EXISTS `tblcustomer`; CREATE TABLE `tblcustomer` ( `CustomerID` int(10) unsigned NOT NULL auto_increment, `CustomerName` varchar(255) NOT NULL default '', `CustomerType` int(10) unsigned NOT NULL default '1', PRIMARY KEY (`CustomerID`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; --- Dumping data for table `DatabaseName`.`tblcustomer` -/*!40000 ALTER TABLE `tblcustomer` DISABLE KEYS */; /*!40000 ALTER TABLE `tblcustomer` ENABLE KEYS */;

--- Table structure for table `DatabaseName`.`tblnote` -DROP TABLE IF EXISTS `tblnote`; CREATE TABLE `tblnote` ( `NoteID` int(10) unsigned NOT NULL auto_increment, `Note` varchar(500) NOT NULL default '', `CustomerID` int(10) unsigned NOT NULL default '0', `DateAdded` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`NoteID`)

JSP and Beyond 2007

105

Reference Application

) ENGINE=InnoDB DEFAULT CHARSET=latin1; --- Dumping data for table `DatabaseName`.`tblnote` -/*!40000 ALTER TABLE `tblnote` DISABLE KEYS */; /*!40000 ALTER TABLE `tblnote` ENABLE KEYS */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

Scriptlet Sample
Scriptlets embed Java code directly within the page markup. Although unquestionably useful and powerful, this model makes management of the presentation layer difficult since the program logic becomes interspersed throughout the presentation code.

Customer Listing
In the customer listing below, you can see that database connectivity code in addition to some HTML markup that is programmatically created, exist within this JSP. This makes it a bit difficult to read or adjust if you wanted to look directly at the user interface portion of what was going to be ultimately produced.

CustomerList-Scriptlet.jsp <%@page import="java.sql.*" %> <html>

JSP and Beyond 2007

106

Reference Application

<head> <title>JSP and Beyond - Customer List - Scriptlet Example</title> </head> <body> <h1>Customer List - Scriptlet Example</h1> <% Connection conn = null; // Reference the JDBC driver Class.forName("com.mysql.jdbc.Driver").newInstance(); conn = DriverManager.getConnection("jdbc:mysql:///YourDatabaseName","Databa seUser", "Password"); Statement stmt = conn.createStatement(); // Set the SQL query ResultSet rs = stmt.executeQuery("SELECT * FROM tblCustomer ORDER BY CustomerName"); // Start our table tag out.println("<table width=\"100%\" border=\"1\">"); out.println("<tr><td colspan=\"4\">Customer</td></tr>"); while(rs.next()) { out.println("<tr><td>"); // Render a link that will let this page show notes out.println("<a href=\"" + request.getRequestURI() + "?shownotes=" + rs.getString("CustomerID") + "\">show notes</a>"); // Render the Customer name out.println(rs.getString("CustomerName") + "</td>"); // Render the customer type //out.println(rs.getString("CustomerType") + "</td><td>"); // Render edit link out.println("<td><a href=\"CustomerEditScriptlet.jsp?CustomerID=" + rs.getString("CustomerID") + "\">edit</td>"); // Render add note link out.println("<td><a href=\"NoteAdd-Scriptlet.jsp?CustomerID=" + rs.getString("CustomerID") + "\">add note</td>");

JSP and Beyond 2007

107

Reference Application

// Render delete customer link out.println("<td><a href=\"CustomerDeleteScriptlet.jsp?CustomerID=" + rs.getString("CustomerID") + "\">delete</td>"); out.println("</tr>"); // Check to see if show details is enabled if (request.getParameter("shownotes") != null) { if (request.getParameter("shownotes").equals(rs.getString("CustomerID")) | request.getParameter("shownotes").equals("all")) { Statement stmtDetails = conn.createStatement(); // Set the SQL query ResultSet rsDetails = stmtDetails.executeQuery("SELECT * FROM tblNote WHERE CustomerID = " + rs.getString("CustomerID")); while(rsDetails.next()) { // Render the customer type out.println("<tr><td colspan=\"4\">" + rsDetails.getString("Note") + " - <a href=\"NoteDeleteScriptlet.jsp?NoteID=" + rsDetails.getString("NoteID") + "\">delete</a></td></tr>"); } rsDetails.close(); stmtDetails.close(); } } } // Close our table out.println("</table>"); // Close the connections to database objects to free resources stmt.close(); conn.close(); %> <br> <a href="CustomerAdd-Scriptlet.jsp">Add a New Customer</a>

JSP and Beyond 2007

108

Reference Application

</body> </html>

Deleting a Customer
The following code uses inline Java to connect with the database and delete a customer account. You can see that the majority of the code is spent dealing with JDBC calls.

CustomerDelete-Scriptlet.jsp <%@page import="java.sql.*" %> <html> <head> <title>JSP and Beyond - Delete Customer - Scriptlet Example</title> </head> <body> <% if (request.getParameter("CustomerID") != null) { try { Connection conn = null; // Reference the JDBC driver Class.forName("com.mysql.jdbc.Driver").newInstance(); conn = DriverManager.getConnection("jdbc:mysql:///YourDatabaseName","Databa seUser", "Password"); Statement stmt = conn.createStatement(); String sCustomerID = request.getParameter("CustomerID").toString(); stmt.executeUpdate("DELETE FROM tblCustomer WHERE CustomerID = " + sCustomerID); // Close any connectivity that we had to the database to free resources stmt.close(); conn.close(); } catch (Exception ex)

JSP and Beyond 2007

109

Reference Application

{ out.println("An Error has Occured: " + ex.toString()); } %> <h1>Delete Customer - Customer Deleted</h1> <br> <a href="CustomerList-Scriptlet.jsp">Main Menu</a> <% } %> </body> </html>

JSTL Sample
In comparison to scriptlets, JSTL provides a more elegant approach to your application. You should immediately notice that the pages are cleaner and easier to read.

Customer Listing
Notice that at the very top of the JSP, we use a directive to let the container (Tomcat) know that we are going to use JSTL. Also notice that there is plenty of Expression Language being used within the JSTL to get values that are passed into actions or displayed on the page.

CustomerList-JSTL.jsp <%-- Let the system know that we are using JSTL and load the proper prefixs --%> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <%@ taglib prefix="sql" uri="http://java.sun.com/jstl/sql_rt" %> <html> <head> <title>JSP and Beyond - Customer List - JSTL Example</title> </head> <body>

JSP and Beyond 2007

110

Reference Application

<h1>Customer List - JSTL Example</h1> <%-- Let the system know what datasource we will speak with --%> <sql:setDataSource var="dataSource" url="jdbc:mysql://YourDatabaseServer/YourDatabaseName" driver="com.mysql.jdbc.Driver" user="DatabaseUser" password="Password" /> <sql:query var="queryResults" dataSource="${dataSource}"> <%-- Place our SQL query here within the XML tag "sql:query" --%> SELECT * FROM tblCustomer ORDER BY CustomerName </sql:query> <table width="100%" border="1"> <tr> <td colspan="4">Customer</td> </tr> <%-- Start a loop through the results from the SQL query and mix it with HTML --%> <c:forEach var="row" items="${queryResults.rows}"> <tr> <%-- Notice how with each "row" object we can access the column name by specifying it after the "row" object --%> <td><a href="CustomerList-JSTL.jsp?shownotes=<c:out value="${row.CustomerID}"/>">show notes</a> <c:out value="${row.CustomerName}"/></td> <td><a href="CustomerEdit-JSTL.jsp?CustomerID=<c:out value="${row.CustomerID}"/>">edit</a></td> <td><a href="NoteAdd-JSTL.jsp?CustomerID=<c:out value="${row.CustomerID}"/>">add note</a></td> <td><a href="CustomerDelete-JSTL.jsp?CustomerID=<c:out value="${row.CustomerID}"/>">delete</a></td> </tr> <c:if test="${(row.CustomerID) == (param.shownotes) or (param.shownotes) == 0}"> <sql:query var="queryDetailResults" dataSource="${dataSource}"> <%-- Place our SQL query here within the XML tag "sql:query" --%> SELECT * FROM tblNote WHERE CustomerID = ? <sql:param value="${row.CustomerID}" /> </sql:query> <c:forEach var="rowDetail" items="${queryDetailResults.rows}">

JSP and Beyond 2007

111

Reference Application

<tr><td colspan="4"><c:out value="${rowDetail.Note}"/> - <a href="NoteDelete-JSTL.jsp?NoteID=<c:out value="${rowDetail.NoteID}"/>">delete</a></td></tr> </c:forEach> </c:if> </c:forEach> </table> <br> <a href="CustomerAdd-JSTL.jsp">Add a New Customer</a> </body> </html>

Adding a Customer
Notice that we are using a single page to add a customer. The single page is able to handle this process because EL allows us to check the parameters that are being sent into the page <c:if test="${(param.action) == null}">.

CustomerAdd-JSTL.jsp <%-- Let the system know that we are using JSTL and load the proper prefixs --%> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <%@ taglib prefix="sql" uri="http://java.sun.com/jstl/sql_rt" %> <html> <head> <title>JSP and Beyond - Add Customer - JSTL Example</title> </head> <body> <c:if test="${(param.action) == null}"> <h1>Add Customer - JSTL Example</h1> <form method="post" action="<%= request.getRequestURI() %>"> Customer Name <input type="text" name="CustomerName"> <input type="hidden" name="action" value="add"> <br><br> <input type="submit" value="Add Customer"> </form> </c:if>

JSP and Beyond 2007

112

Reference Application

<c:if test="${(param.action) != null}"> <c:out value="${param.CustomerName}" /> <%-- Let the system know what datasource we will speak with --%> <sql:setDataSource var="dataSource" url="jdbc:mysql://YourDatabaseServer/YourDatabaseName" driver="com.mysql.jdbc.Driver" user="DatabaseUser" password="Password" /> <sql:update dataSource="${dataSource}" > INSERT INTO tblCustomer (CustomerName) VALUES (?) <sql:param value="${param.CustomerName}" /> </sql:update> <h1>Add Customer - Customer Added</h1> <br> <a href="CustomerList-JSTL.jsp">Main Menu</a> </c:if> </body> </html>

Model View Controller (MVC) and JavaBeans
Up until this point, we have examined many ways to help separate code and business logic from your JSPs. JSTL, JavaBeans and custom tags all go a long way toward doing this. As applications grow in size, it also make sense to abstract additional things like page flow and security, in addition to making any separation of design and code even further pronounced. The Model View Controller framework is the result of a natural evolution toward this approach.

This sounds magical! How does it work?

Think of an MVC framework like a person traveling by train throughout Europe.

JSP and Beyond 2007

113

Reference Application When people want to travel from one place to another, they need to see the conductor with their ticket and baggage. The ticket informs the conductor where they are headed, and perhaps it is to the city of Paris or London. After checking to make sure that the person is okay to travel to the requested destination, the conductor helps to load their baggage to ensure that it is sent with them. Once the person has arrived, the conductor assists them off the train where they are surrounded by new sights.

How does that relate back to MVC?

The “C” or controller in MVC is the conductor. The controller, which is generally a Servlet, intercepts all requests that an end user makes and captures the data that is sent with the requests. In an MVC framework, the requests are sent with an “action” which is the equivalent of the ticket, and the baggage is the equivalent of the data that is paired with the request. The controller also ensures that people are authorized to access a particular action. The controller will then let any business take place as it connects with the Model or “M” which controls database and external resource access. Once the processing in the model is completed, the controller will route people to a particular View or “V”. The view is generally a JSP that correlates to the action requested of the controller.

In the example below, we take a basic approach to MVC, using a single Servlet to capture and deal with all requests. In a more formal implementation a framework like Jakarta Struts would probably be used to manage the application, especially as the size of the application increases.

Controller Servlet
The controller Servlet is the heart of the MVC version of the reference application. It takes almost all of the Java code out of the JSPs, leaving only some JSTL and EL to assist with the presentation. You do not need to memorize the example below, but you can quickly see that the controller cues off of the “action” that is requested of it such as::

else if ("customerlist".equals(action))

When a request is sent to the controller, it is formatted like: http://localhost:8084/JSPandBeyond/MVCSample/ServletExample?action=customerlist
JSP and Beyond 2007 114

Reference Application This tells the application that you would like to see the customer list. The controller will then get an array of customer beans ready to be sent back to the JSP, where you can render the results to the end user via JSTL and EL.

What you will also notice in the controller Servlet is that it will delegate all database work to another class, thereby enhancing the readability of the code in your controller.

ServletExample.java /* * JSP and Beyond * Servlet example for simple Model View Controller */ package JSPBeyond; // Below are the default namespaces that are used for Servlets import java.io.*; import java.net.*; import javax.Servlet.*; import javax.Servlet.http.*; import java.util.ArrayList; import java.util.Collection; import java.util.List; public class ServletExample extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Get the action argument from the URL String action = request.getParameter("action"); // Set the default page for the Servlet to redirect to String jspPage = "CustomerList.jsp"; // Advanced error / request handling if ((action == null) || (action.length() < 1)) { action = "default"; } if ("default".equals(action)) { jspPage = jspPage; } else JSP and Beyond 2007 115

Reference Application

if ("customerlist".equals(action)) { // Create arraylist to house the customer listing java.util.ArrayList alCustomers; try { alCustomers = JSPBeyond.ServletExampleData.getCustomers(); // Set the "CustomerListing" attribute so it can hold the array for access later within this page request.setAttribute("CustomerListing", alCustomers); } catch (Exception ex) { // Exception } jspPage = "CustomerList.jsp"; } else if ("addcustomer".equals(action)) { jspPage = "CustomerAdd.jsp"; } else if ("deletecustomer".equals(action)) { if (request.getParameter("CustomerID") != null) { try { // Call our data method to handle the deletion JSPBeyond.ServletExampleData.deleteCustomer(Integer.parseInt(request. getParameter("CustomerID").toString())); } catch (Exception ex) { // Exception handle } } jspPage = "CustomerDelete.jsp"; } else if ("savecustomer".equals(action)) { if (request.getParameter("CustomerName") != null)

JSP and Beyond 2007

116

Reference Application

{ try { // Call our data method to handle the deletion JSPBeyond.ServletExampleData.addCustomer(request.getParameter("Cust omerName")); } catch (Exception ex) { // Exception handle } } jspPage = "CustomerAdd.jsp?status=complete"; } else if ("addnote".equals(action)) { if (request.getParameter("CustomerID") != null) { request.setAttribute("CustomerID", request.getParameter("CustomerID").toString()); } jspPage = "NoteAdd.jsp"; }

else if ("customerdetails".equals(action)) { if (request.getParameter("CustomerID") != null) { try { Integer iCustomerID = Integer.parseInt(request.getParameter("CustomerID")); String sCustomerName = ""; sCustomerName = JSPBeyond.ServletExampleData.getCustomerName(iCustomerID); // Create arraylist to house the customer listing java.util.ArrayList NoteRecords; NoteRecords = JSPBeyond.ServletExampleData.getNotes(iCustomerID); // set the customer ID to head into the page request.setAttribute("CustomerID", iCustomerID.toString()); request.setAttribute("noteListing", NoteRecords); request.setAttribute("customerName", sCustomerName);

JSP and Beyond 2007

117

Reference Application

} catch (Exception ex) { // Handle exceptions here } } jspPage = "CustomerDetails.jsp"; } else if ("editcustomer".equals(action)) { if (request.getParameter("CustomerID") != null) { try { Integer iCustomerID = Integer.parseInt(request.getParameter("CustomerID").toString()); String sCustomerName = JSPBeyond.ServletExampleData.getCustomerName(iCustomerID); // set the customer name request.setAttribute("CustomerName", sCustomerName); request.setAttribute("CustomerID", iCustomerID.toString()); } catch (Exception ex) { // Handle the exception } } jspPage = "CustomerEdit.jsp"; } else if ("saveeditcustomer".equals(action)) { if (request.getParameter("CustomerID") != null) { try { Integer iCustomerID = Integer.parseInt(request.getParameter("CustomerID")); String sCustomerName = request.getParameter("CustomerName"); JSPBeyond.ServletExampleData.updateCustomer(iCustomerID, sCustomerName); } catch (Exception ex) {

JSP and Beyond 2007

118

Reference Application

// Exception handle here } } jspPage = "CustomerEdit.jsp?status=complete"; } else if ("savenote".equals(action)) { if (request.getParameter("CustomerID") != null) { try { String sNote = request.getParameter("Note").toString(); Integer iCustomerID = Integer.parseInt(request.getParameter("CustomerID").toString()); JSPBeyond.ServletExampleData.addNote(sNote, iCustomerID); } catch (Exception ex) { // Exception handle here } } jspPage = "NoteAdd.jsp?status=complete"; }

dispatch(jspPage, request, response); } protected void dispatch(String jsp, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (jsp != null) { RequestDispatcher rd = request.getRequestDispatcher(jsp); rd.forward(request, response); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); }

JSP and Beyond 2007

119

Reference Application

private void println(String string) { throw new UnsupportedOperationException("Not yet implemented"); } }

ServletExampleData.java package JSPBeyond; import import import import import import java.io.*; java.net.*; java.sql.*; java.util.ArrayList; java.util.Collection; java.util.List;

/** * * @author jbrunswi */ public class ServletExampleData { /** Creates a new instance of ServletExampleData */ public ServletExampleData() { } private static Connection getConnection () { Connection conn = null; try { // Reference the JDBC driver Class.forName("com.mysql.jdbc.Driver").newInstance(); conn = DriverManager.getConnection("jdbc:mysql:///DatabaseName","DatabaseUs er", "Password"); } catch (Exception ex) { return null; } return conn; } public static void deleteCustomer (Integer iCustomerID) JSP and Beyond 2007 120

Reference Application

{ try { Connection conn = getConnection(); Statement stmt = conn.createStatement(); stmt.executeUpdate("DELETE FROM tblCustomer WHERE CustomerID = '" + iCustomerID.toString() + "'"); stmt.close(); conn.close(); } catch (Exception ex) { } } public static void updateCustomer (Integer iCustomerID, String sCustomerName) { try { Connection conn = getConnection(); Statement stmt = conn.createStatement(); stmt.executeUpdate("UPDATE tblCustomer SET CustomerName = '" + sCustomerName + "' WHERE CustomerID = '" + iCustomerID.toString() + "'"); stmt.close(); conn.close(); } catch (Exception ex) { // Exception handling } } public static void addNote (String sNote, Integer iCustomerID) { try { Connection conn = getConnection(); Statement stmt = conn.createStatement(); stmt.executeUpdate("INSERT INTO tblNote (CustomerID, Note) VALUES (" + iCustomerID.toString() + ", '" + sNote + "')"); stmt.close();

JSP and Beyond 2007

121

Reference Application

conn.close(); } catch (Exception ex) { // Handle exception } } public static void addCustomer (String sCustomerName) { try { Connection conn = getConnection(); Statement stmt = conn.createStatement(); stmt.executeUpdate("INSERT INTO tblCustomer (CustomerName) VALUES ('" + sCustomerName + "')"); stmt.close(); conn.close(); } catch (Exception ex) { // Exception handling } } public static ArrayList getCustomers() throws Exception { Connection conn = getConnection(); Statement stmt = null; ResultSet rs = null; ArrayList CustomerRecords = new ArrayList(); // Create a string that has the SQL statement gets records from 'emp' String sqlString = "SELECT * FROM tblCustomer ORDER BY CustomerName"; stmt = conn.createStatement(); rs = stmt.executeQuery(sqlString); try { // Add the ResultSet value to an ArrayList. 'ename','job' while (rs.next()) { CustomerRecord myCustomerRecord = new CustomerRecord();

JSP and Beyond 2007

122

Reference Application

myCustomerRecord.setCustomerID(Integer.parseInt(rs.getString("Custom erID"))); myCustomerRecord.setCustomerName(rs.getString("CustomerName")); CustomerRecords.add(myCustomerRecord); } } catch (Exception ex) { throw ex; } rs.close(); stmt.close(); conn.close(); return CustomerRecords; } public static ArrayList getNotes(Integer iCustomerID) { Connection conn = getConnection(); ArrayList NoteRecords = new ArrayList(); try { Statement stmt = conn.createStatement(); stmt = conn.createStatement(); String sqlString = "SELECT * FROM tblnote WHERE CustomerID = '" + iCustomerID.toString() + "'"; ResultSet result = stmt.executeQuery(sqlString); try { while (result.next()) { NoteRecord myNoteRecord = new NoteRecord(); myNoteRecord.setNoteID(Integer.parseInt(result.getString("NoteID"))); myNoteRecord.setNote(result.getString("Note")); NoteRecords.add(myNoteRecord); }

JSP and Beyond 2007

123

Reference Application

} catch (Exception ex) { throw ex; } result.close(); stmt.close(); conn.close(); } catch (Exception ex) { // Handle the exception } return NoteRecords; } public static String getCustomerName (Integer iCustomerID) { String sCustomerName = ""; try { Connection conn = getConnection(); Statement stmt = conn.createStatement(); ResultSet result = stmt.executeQuery("SELECT * FROM tblCustomer WHERE CustomerID = '" + iCustomerID.toString() + "'"); if(result.next()) { sCustomerName = result.getString("CustomerName"); } } catch (Exception ex) { // Handle exception } return sCustomerName; }

}

JSP and Beyond 2007

124

Reference Application

Customer Listing
In the following example you can immediately notice how clean the JSP becomes as all data work has been abstracted away from anything in the JSP.

CustomerList.jsp <%@ page contentType="text/html" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <html> <head> <title>JSP and Beyond - Customer List - MVC Example</title> </head> <body> <h1>Customer List - MVC Example</h1> <table width="100%" border="1"> <tr> <td colspan="4">Customer</td> </tr> <%-- Start a loop through the contents sent by the controller Servlet and mix it with HTML --%> <c:forEach var="row" items="${CustomerListing}"> <tr> <%-- Notice how with each "row" object we can access the column name by specifying it after the "row" object --%> <td><c:out value="${row.customerName}"/> <a href="ServletExample?action=customerdetails&CustomerID=<c:out value="${row.customerID}"/>">show details</a> </td> <td><a href="ServletExample?action=editcustomer&CustomerID=<c:out value="${row.customerID}"/>">edit</a></td> <td><a href="ServletExample?action=addnote&CustomerID=<c:out value="${row.customerID}"/>">add note</a></td> <td><a href="ServletExample?action=deletecustomer&CustomerID=<c:out value="${row.customerID}"/>">delete</a></td> </tr> </c:forEach> </table> <br> <a href="ServletExample?action=addcustomer">Add a New Customer</a>

JSP and Beyond 2007

125

Reference Application

</body> </html>

Adding a Customer
To add a customer you will still make use of some JSTL to leverage a single JSP. The code is much cleaner and easy to understand.

CustomerAdd.jsp <%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <html> <head> <title>JSP and Beyond - Add Customer - JSTL Example</title> </head> <body> <c:if test="${param.status != 'complete'}"> <h1>Add Customer - JSTL Example</h1> <form method="post" action="ServletExample?action=savecustomer"> Customer Name <input type="text" name="CustomerName"> <br><br> <input type="submit" value="Add Customer"> </form> </c:if> <c:if test="${param.status == 'complete'}"> <h1>Add Customer - Customer Added</h1> <br> <a href="ServletExample?action=customerlist">Main Menu</a> </c:if> </body> </html>

JSP and Beyond 2007

126

Reference Application

Updating a Customer
Editing a customer is just as simple as adding the customer. When you begin editing a customer account, the controller Servlet takes care of fetching the data that you want to be placed into the form.

CustomerEdit.jsp <%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <html> <head> <title>JSP and Beyond - Customer Edit - MVC Example</title> </head> <body> <c:if test="${param.status != 'complete'}"> <h1>Edit Customer Name - MVC Example</h1> <form method="post" action="ServletExample?action=saveeditcustomer"> Add Note <input type="text" name="CustomerName" value="${CustomerName}"> <input type="hidden" name="CustomerID" value="${CustomerID}"> <br><br> <input type="submit" value="Save Edit"> </form> </c:if> <c:if test="${param.status == 'complete'}"> <h1>Customer Edit Complete - MVC Example</h1> <br> <a href="ServletExample?action=customerlist">Main Menu</a> </c:if> </body> </html>

JSP and Beyond 2007

127

Map of Technology

MAP OF TECHNOLOGY

The diagram below represents a logical diagram of JSP architectural components.

JSP and Beyond 2007

128

Next Steps

NEXT STEPS

Hopefully at this point you should have a good handle on the various components that have been covered in this book. The benefits of Java for the web, the history of the tools that have been used to generate dynamic web content, the ins and outs of application servers, how JSPs are processed, an understanding of what development tools can help deliver solutions, interaction with databases, email and other basics of Java web application development should now seem familiar.

From here it is possible to become acquainted with and explore additional technologies that build on top of the foundation that has been laid. These additional technologies continue to make Java a mainstay in enterprise application development.

The following sections were designed to help bring you up to speed on these additional tools at a conceptual level. I hope that it acts as a launch pad for you to dive into and leverage these additional tools in your development efforts.

JSP and Beyond 2007

129

Next Steps

Jakarta Struts
Jakarta Struts is maintained by the Apache Foundation. The Struts concept is somewhat similar to the MVC example discussed in the previous chapter, but it leverages an XML configuration file which maps actions to JSPs and “action” classes. This makes it a much better choice for managing applications of any real complexity.

More information about Jakarta Struts can be found at: http://jakarta.apache.org/struts

Java Server Faces
As you now know, JSP has many tools that allow you to help separate developer and designer tasks during a web application project. Java Server Faces allows web applications to be developed using “components” that make accessing information between requests much easier, because the information is made accessible through objects that represent the components in a “backing bean”. It is very similar to the way that ASP.NET works. The example below highlights a scenario where Java code in a special class handles the press of a button component in a JSP represented by the snippet below...
<ui:button action="#{MyJSFSample.btnPressMe_action}" binding="#{MyJSFSample.btnPressMe}" id="btnPressMe" text="Press Me!"/>

...and based on that event, a label component’s value is changed. The code below shows a component called “lblMyLabel” that registers the change based on the way the button press was handled in a special Java class which is detailed in the next code sample.
<?xml version="1.0" encoding="UTF-8"?> <jsp:root version="1.2" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:ui="http://www.sun.com/web/ui"> <jsp:directive.page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"/> <f:view> JSP and Beyond 2007 130

Next Steps

<ui:page binding="#{MyJSFSample.page1}" id="page1"> <ui:html binding="#{MyJSFSample.html1}" id="html1"> <ui:head binding="#{MyJSFSample.head1}" id="head1"> <ui:link binding="#{MyJSFSample.link1}" id="link1" url="/resources/stylesheet.css"/> </ui:head> <ui:body binding="#{MyJSFSample.body1}" id="body1"> <br/> <ui:form binding="#{MyJSFSample.form1}" id="form1">Our JSF Example<br/> <ui:label binding="#{MyJSFSample.lblMyLabel}" id="lblMyLabel"/> <br/> <ui:button action="#{MyJSFSample.btnPressMe_action}" binding="#{MyJSFSample.btnPressMe}" id="btnPressMe" text="Press Me!"/> <br/> </ui:form> </ui:body> </ui:html> </ui:page> </f:view> </jsp:root>

In order to make the above JSP page work and the value for “lblMyLabel” change, the following class assists that page with its processing.
/* * MyJSFSample.java */ package myjsftest; import import import import import import import import import import com.sun.rave.web.ui.appbase.AbstractPageBean; com.sun.rave.web.ui.component.Body; com.sun.rave.web.ui.component.Button; com.sun.rave.web.ui.component.Form; com.sun.rave.web.ui.component.Head; com.sun.rave.web.ui.component.Html; com.sun.rave.web.ui.component.Label; com.sun.rave.web.ui.component.Link; com.sun.rave.web.ui.component.Page; javax.faces.FacesException;

/** * <p>Page bean that corresponds to a similarly named JSP page. This

JSP and Beyond 2007

131

Next Steps

* class contains component definitions (and initialization code) for * all components that you have defined on this page, as well as * lifecycle methods and event handlers where you may add behavior * to respond to incoming events.</p> */ public class MyJSFSample extends AbstractPageBean { private int __placeholder; private void _init() throws Exception { } private Page page1 = new Page(); public Page getPage1() { return page1; } public void setPage1(Page p) { this.page1 = p; } private Html html1 = new Html(); public Html getHtml1() { return html1; } public void setHtml1(Html h) { this.html1 = h; } private Head head1 = new Head(); public Head getHead1() { return head1; } public void setHead1(Head h) { this.head1 = h; } private Link link1 = new Link(); public Link getLink1() { return link1; }

JSP and Beyond 2007

132

Next Steps

public void setLink1(Link l) { this.link1 = l; } private Body body1 = new Body(); public Body getBody1() { return body1; } public void setBody1(Body b) { this.body1 = b; } private Form form1 = new Form(); public Form getForm1() { return form1; } public void setForm1(Form f) { this.form1 = f; } private Label lblMyLabel = new Label(); public Label getLblMyLabel() { return lblMyLabel; } public void setLblMyLabel(Label l) { this.lblMyLabel = l; } private Button btnPressMe = new Button(); public Button getBtnPressMe() { return btnPressMe; } public void setBtnPressMe(Button b) { this.btnPressMe = b; } public MyJSFSample() { }

JSP and Beyond 2007

133

Next Steps

public void init() { super.init(); try { _init(); } catch (Exception e) { log("MyJSFSample Initialization Failure", e); throw e instanceof FacesException ? (FacesException) e: new FacesException(e); } } public void preprocess() { } public void prerender() { } public void destroy() { } protected ApplicationBean1 getApplicationBean1() { return (ApplicationBean1)getBean("ApplicationBean1"); } protected SessionBean1 getSessionBean1() { return (SessionBean1)getBean("SessionBean1"); } protected RequestBean1 getRequestBean1() { return (RequestBean1)getBean("RequestBean1"); } public String btnPressMe_action() { lblMyLabel.setText("You pressed the button. Amazing!"); return null; } }

The line highlighted above manages the lblMyLabel label component and updates its value.

We are only scratching the surface of JSF here, but the above example illustrates some very basic elements of its operation. For more details on JSF please visit: http://java.sun.com/javaee/javaserverfaces/
JSP and Beyond 2007 134

Next Steps

Hibernate
Remember all of the lines of code that were needed to write in the Dealing with Data – JDBC section? Hibernate creates an object layer over your database that makes all of the connection creation, querying, adding, updating, deleting and more a breeze because it removes the need to write any SQL code. This abstraction methodology is called Object Relational Mapping. Using Hibernate, you are able to use plain old Java objects (POJOs) to manipulate any information in the database as Hibernate will automatically create the POJOs that will map to your database structure.

The example below shows a theoretical situation where we are trying to store a new user.

With Hibernate User user = new User(); user.setFirstName("Doug"); Transaction saveUser = session.beginTransaction(); session.save(user); saveUser.commit();

Without Hibernate // Obtain a statement object Statement stmt = cnDB.createStatement(); // Execute the block of SQL code stmt.executeUpdate("INSERT INTO tblUser VALUES ('Doug')"); // Close the result set stmt.close(); // Close the connection cnDB.close();

After reviewing the above examples, it is obvious that the Hibernate approach is much more elegant, especially when you start to work with more complex transactions and data structures.

JSP and Beyond 2007

135

INDEX
A Actions .......................................................49 forward...................................................49 getProperty ............................................49 include ...................................................49 param.....................................................49 plugin .....................................................49 setProperty ............................................49 useBean.................................................49 Active Server Pages (ASP Classic or ASP 3.0).........................................................16 Another Neat Tool (Ant).............................37 Ant ............................See Another Neat Tool Apache Tomcat....................................29, 31 Application Server Architecture .................28 ASP.NET ...................................................20 B BEA WebLogic...........................................32 C Classpath...................................................41 Coldfusion Markup Language (CFM) ........18 Comment ...................................................50 Common Gateway Interface (CGI) ............15 Custom Tags .............................................79 D Declaration.................................................48 Development Tools....................................34 Eclipse ...................................................36 NetBeans ...............................................35 Directive.....................................................45 Include ...................................................46 Page ......................................................45 Taglib .....................................................46 Django .......................................................22 E Eclipse .................... See Development Tools Email Sending..................................................92 Error Handling..........................................103 Expression .................................................47 Expression Language (EL) ....................... 74 F Forms Collecting Data...................................... 95 getParameter ........................................ 95 getParameterNames............................. 95 Validation ............................................ 101 G GlassFish .................................................. 31 H Hibernate ................................................ 139 Hypertext Preprocessor (PHP) ................. 17 I IBM WebSphere........................................ 32 Implicit Objects.......................................... 52 application............................................. 53 config .................................................... 53 exception............................................... 53 out ......................................................... 53 page ...................................................... 53 pageContext.......................................... 54 request .................................................. 52 response ............................................... 52 session.................................................. 53 J J2EE ......................................................... 33 J2ME ......................................................... 34 J2SE ......................................................... 34 Jakarta Struts.......................................... 134 JAR Files................................................... 41 Java EE..................................................... 33 Java Server Faces .................................. 134 Java Server Pages (JSP) ......................... 19 Java Server Pages Standard Tag Library (JSTL) ................................................... 69 Conditionals .......................................... 72 Exception Handling ............................... 74 Expression ............................................ 71 Iteration ................................................. 72

Taglib Directive ......................................71 URL Management..................................73 Variables................................................71 JavaBean...................................................61 Accessing a Bean ..................................65 Attributes................................................64 Building and Deploying..........................67 JBoss .........................................................31 JDBC .........................................................54 Adding Data ...........................................58 Connecting to a Database .....................54 Deleting Data .........................................59 Retrieving Data ......................................56 Updating Data........................................59 JDK ............................................................33 JRE ............................................................33 JVM............................................................34 M Macromedia JRun......................................32 Model View Controller (MVC) ..................117 Controller Servlet .................................118 N NetBeans ................ See Development Tools O Oracle Application Server ..........................32

R Reference Application Database............................................. 107 JSTL Sample ...................................... 113 Model View Controller (MVC) ............. 117 Scriptlet Sample.................................. 109 REFERENCE APPLICATION................. 106 Ruby on Rails............................................ 21 S Scriptlet ..................................................... 43 Servlets ..................................................... 24 Struts................................See Jakarta Struts U Uploading Files ......................................... 93 V Validating User Input .............................. 101 JavaScript ........................................... 101 JSTL.................................................... 102 W WAR Files ................................................. 40 Web Application Structure ........................ 38

ABOUT THE AUTHOR
John Brunswick is a Practice Manager within BEA System’s Business Interaction Division Professional Services Group. Managing their Enterprise Portal and Business Process Management practice in Canada and New England, he helps Fortune 500 companies create solutions to a wide range of business challenges.

He actively contributes to the enterprise software business community and has authored a series of articles about optimal business involvement in portal development, examining ways of helping organizations move away from monolithic application development.

In 2006, he developed ServiceMountain, a commercial software package to help manage small service businesses, which was acquired by a medium-sized software vendor.

John actively leads the Boston Computing Review user group which he founded in 2005, educating members about emerging technologies and industry trends. Prior to working at BEA, John directed Jniche Technology Associates, a small web application development and networking group. John graduated from Boston University with a degree in Business Administration with a concentration in Management Information Systems.

Sign up to vote on this title
UsefulNot useful