HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

Serving Web Pages, by Robert J. Brunner

After reading the previous articles in this series, we're now ready to apply our Java database knowledge to real-world applications. Perhaps the simplest example is utilizing JSP to dynamically present data stored in our database over the Internet.

While many commercial systems exist that can facilitate the entire development and deployment process (e.g., JDeveloper and Oracle 8i), I'll focus instead on one of the products from the Apache Software Foundation (ASF). The Tomcat server provides the reference implementation for both JSPs and Servlets. Because it's an open-source organization, all Apache products are free and include all source code, so you can look under the hood.

In this article, we'll first go over the basics of JSP, including the overall architecture and most commonly used JSP tags. Then we'll look at how to connect JSPs and databases to provide dynamic data presentation.

Just the Facts
Before we proceed any further, it's always a good idea to clarify the fundamentals or, in this case, outline the basics of the JSP, including what it is and how it works. As part of the Enterprise edition of the Java language, JSP is not included with the standard edition of the Java language (J2SE). As a result, it's in a standard extension package (i.e., its root package is javax, not java), and due to the manner in which it works, it's actually a subpackage of the servlet standard extension package (javax. servlet). Unlike servlets, which are 100% Java, JSP pages combine HTML and Java (or other languages that conform to the JSP model) into a single server processed file. The Java code is distinguished by being enclosed in specific JSP tags, which look similar to HTML, and can be easily generated by an IDE. As a result, JSP is extremely easy to use and provides a rapid design, development, and deployment cycle.

In fact the JSP file is effectively processed in two stages. When the JSP file is first loaded by the JSP engine, the file is initially processed and the Java source code is compiled into a Java class file, which is generally a Servlet class. This step, formally known as the HTTP translation stage, is where all HTML tags and some of the simpler JSP tags are processed.

The second stage occurs when a user actually makes a request from the JSP page (e.g., a Web browser requests the JSP file), and the JSP engine processes the request by executing the compiled JSP file. This step is formally known as the request processing stage and allows the user to send specific data to the JSP file. The Java code that's executed is known as a scriptlet and is dynamically executed with each user request, allowing the content to be different depending on each specific request. This ability can be used to build dynamic web sites, such as e-commerce, by generating the results of a request from a database.

In the interests of brevity and not insulting your intelligence, I won't cover the HTML aspects of a JSP file, in other words, HTML tags like <HTML> or <H2>. If you want more information about HTML, visit the home page of the World Wide Web, www.w3c.org, where you can find information on all sorts of things related to the Web. I'll go over some of the basics of the JSP tags, which, unlike the HTML tags, are case sensitive.

Since a JSP file has HTML and Java code intermixed, it's important to know how to quickly identify the JSP tags. This is actually straightforward, since JSP tags start with only two different character sequences, either <% or <jsp. In addition, the characters that follow these identifiers indicate the exact nature of the JSP tag, which completely specifies its behavior.

The first tag in a JSP file is generally the page directive, which defines the global attributes of the file, such as the scripting language, and allows the JSP developer to import java packages. For example, the following page directive indicates that the JSP page uses Java (which is the default, and of course, what we're interested in using!) and imports the java.util package:

<%@ page
language="java"
import="java.util.*"
%>

After this, we can start to include Java code in our file, which can be explicitly done in three different tags: the declaration, the expression, and the scriptlet. The first two tags are processed during the HTTP translation stage, while the third is processed for each user request, although certain optimizations can be applied by your JSP server. This can have important design and performance implications, so take care when using them.

The declaration tags are used for variables and methods used later within the current JSP file. For example, the following tag declares a connection object that we can use throughout the JSP file:

<%! Connection connection %>

The expression tags are important because they're evaluated, and the result replaces the expression tag in the resulting JSP page. For example, given the following JSP line:

Our output = <%= "Hello World" %>,

after the JSP HTTP translation stage, the resulting line will be:

Our output = Hello World

To really perform some serious dynamic processing, however, you need to utilize a scriptlet, which can do a lot more than either the declaration or expression tags allow. For example, given the previous declaration tag that declared our connection object, we can obtain an actual connection object in the following scriptlet:

<% connection =
DriverManager.getConnection(
"jdbc:acme://localhost:1234/jdbc",
"java", "sun") ;
%>

An important issue with scriptlets is that they can span multiple lines and even be intermixed with HTML tags, as in the following example:

<UL>
<% while(rs.next()){ %>
<LI> <%= rs.getString(1) %> </LI>
<% } %>
</UL>

where we iterate through a result set, printing out the first column in each row as an HTML list item from an unordered list. Notice how the scriptlet is split over three separate lines, with HTML tags and an expression JSP tag intermingled. In particular, we have the closing curly brace for our result set iteration on a separate line in its own scriptlet tag.

To improve the overall maintainability of the Java code in a JSP file, you should, of course, liberally comment the programming structure and algorithms. You could do this with an HTML comment known as an output comment in JSP parlance, like this:

<!--This will establish a connection
to the Corporate payroll database -->

But since HTML comments are sent to the browser where they can be viewed along with the rest of the source code for the HTML page, this may not be what you want. Fortunately, there's another choice for commenting your JSP file, namely hidden comments, which are removed by the JSP processor and therefore not sent to the browser. To convert the preceding output comment to a hidden comment, change the enclosing tags as follows:

<%--This will establish a connection
to the Corporate payroll database --%>

Output comments can still be quite useful, however, since placing JSP expression tags inside them can dynamically alter the resulting comment. In this example (albeit a bit contrived), we can dynamically create an HTML comment that indicates which day of the current month the page was generated:

<!-- This page was generated on
<%=Calendar.get(
Calendar.Day_Of_Month)
%>

If that's all there was to JSP files, they'd still be quite useful, if not lengthy and somewhat unwieldy to implement. JSP was, however, designed to work within the JavaBeans framework. As a result, you can encapsulate specific concepts inside a JavaBean and access the object using the JavaBeans framework. Furthermore, JSP allows development of custom tags to encapsulate routine operations. As these topics could span several books in their own right, we won't cover them here, but look online at the JSP home page (http://java.sun.com/products/jsp) for more information.

Letting the Cat Out
To actually use JSP, you need to run a server process that can convert JSP files into HTML pages that can be rendered on an ordinary browser. This server can be a web server that's able to serve Java pages, an application server, or even be incorporated into an IDE (e.g., JDeveloper). I strongly recommend, however, that you use the Tomcat server from the Apache Software Foundation. Before discussing how to connect to a database using JSP, we need to get the server and set it up.

The first thing we need to do is download the entire server package. Figure 1 shows the home page for the Jakarta-tomcat server project (http://jakarta.apache.org/tomcat/index.html), where you can obtain the latest version of the software (currently 3.1, but maybe something different by the time you read this article). The Tomcat server is the official reference implementation for both JavaServer Pages and Servlets. From the Tomcat home page you'll want to click on the "Download Binaries:" link, which takes you to the binary downloads web page. Click the first Tomcat link under the "Release Builds" heading. This should take you to a directory listing for the current release builds for several Jakarta projects. The only one we're interested in right now is the Jakarta-Tomcat project; hence click on the jakarta-tomcat.zip file to download the necessary files.

Figure 1
Figure  1:

Once you've downloaded the correct file you'll need to extract the zip file's contents. By default, all files will be created in a new directory named jakarta-tomcat. Thus if you extract everything to the C:\ drive, all will be in the directory "C:\jakarta-tomcat\". While you can actually configure the Tomcat server to properly integrate with a variety of different production-quality web servers, including Apache or IIS, you can also have it run as its own web server.

The Jakarta-Tomcat server is a Java application and, as a result, runs in a Java Virtual Machine. To start the server, however, we need to run only the startup batch file (or startup.sh on Unix systems), which sets up all the necessary environmental variables before actually creating a new JVM and running the Tomcat server. Conversely, to shut down the server we need to run only the shutdown batch file (or shutdown.sh on Unix).

Since JSP files need to be compiled by the server, there's one last caveat before running the startup script; the java compiler (i.e., the class file that contains javac) needs to be in the classpath environmental variable. This can be done by directly modifying the appropriate script files, by placing the tools.jar file in the jakarta-tomcat\lib directory, or by placing the tools.jar file in your classpath and running the startup script from a command prompt. I prefer the command prompt mode for startup as shown in Figure 2, since I generally have other jar files that need to be in the classpath of the JVM that's running the Jakarta-Tomcat server (e.g., JDBC driver jar files). For example, as demonstrated in Figure 2, we first set up the classpath to include both tools.jar (which in this example is in the C:\jdk\lib directory) that contains the javac class file, and also acme.jar (which in this case is in the C:\java\lib directory). Remember that acme is the fictional JDBC driver we've used in previous articles. For completeness sake, the shutdown sequence is also shown.

Figure 2
Figure  2:

If the server starts up properly, you'll be able to view the reference information as well as demonstrations of both Javaserver pages and Servlets. This can be accomplished by browsing to the URL: http://localhost:8080/.

The result for version 3.1 of the Tomcat server is shown in Figure 3. By following the links to JSP examples, you'll be able to see JSP demonstrations. If the JSP examples don't work, the tools.jar file is probably not in your classpath variable.

Figure 3
Figure  3:

Hooking into a Database
Now we can finally get down to the business at hand, namely dynamically extracting data from a database into our JSP file. Assuming we have already created and populated a database with the following schema:

CREATE TABLE Contacts (
First VARCHAR(20) NOT NULL,
Middle VARCHAR(20) NOT NULL,
Last VARCHAR(20) NOT NULL,
Phone INT,
Age INT
) ;

we now want to build a web page that displays all the contacts in our database as an HTML table.

The first step is to write out our page directive:

<%@ page
errorPage="error.jsp"
language="java"
import="java.sql.*"
%>

This directive first specifies that all errors will be handled by a special JSP file called error.jsp (more on this later). The rest of the directive indicates that we'll be using Java (big surprise) and that we want to import the java.sql package. After this we have some variable declarations that go in their own declaration directive:

<%!
Connection connection ;
Statement statement ;
ResultSet rs ;
ResultSetMetaData rsmd ;
%>

We can now include our normal HTML tags that start our HTML files (you may have something more fancy that relies on cascading stylesheets):

<HTML>
<HEAD>
<TITLE>
ACME Database JSP Demonstration
</TITLE>
</HEAD>
<BODY>

Now we need to do some of the heavy lifting, so we'll place our JDBC code in a scriptlet:

<%
Class.forName(
"com.acme.sql.JDBCDriver") ;

connection =
DriverManager.getConnection(
"jdbc:acme://localhost:1234/jdbc",
"java", "sun") ;

statement =
connection.createStatement() ;

rs =
statement.executeQuery(
"SELECT * FROM Contacts") ;

rsmd = rs.getMetaData() ;

%>

In this scriptlet we load our acme JDBC driver into the JVM, establish a connection to our database, create a JDBC statement object, execute the SQL statement that populates our ResultSet object, and obtain the ResultSet Metadata information. We can now start our HTML table:

<TABLE
WIDTH="100%"
BORDER="+5"
>

and dynamically output the header row for our table, which we get from the Result Set Metadata ColumnLabel method.

<TR>
<%
for(int i = 1 ;
i <= rsmd.getColumnCount() ;
i++) {
%>

<TH>
<%= rsmd.getColumnLabel(i) %>
</TH>

<% } %> </TR>

We'll now want to iterate over all rows in our ResultSet, converting each row of our ResultSet into a row in our HTML table:

<% while(rs.next()) { %>

<TR>

<% for(int i = 1 ;
i <= rsmd.getColumnCount() ; i++) {
%>

<TH>
<%= rs.
getString(i) %>
</TH>

<% } %>

</TR>
<% } %>

We can now finish off our HTML tags:

</TABLE>
</BODY>
</HTML>

The last step is to save all these JSP and HTML tags into a file called mdb.jsp. to have the Tomcat serve this file to our web browser, we need to put it into an HTML hierarchy. While we could configure Tomcat to automatically look in our development directories, I'll take the easier approach and just copy mdb.jsp to the directory where Tomcat looks for its example JSP files. in our installation scenario, this is the C:\jakarta-tomcat\webapps\examples\jsp directory. Once you've copied our JSP file to the correct directory, restart the web server and browse to http://localhost:8080/examples/jsp/mdb.jsp. When I modify mdb.jsp to connect to my contacts database, I get the result shown in Figure 4. To make this example work, you'll need to have the contacts data in a database table, modify mdb.jsp to use the appropriate JDBC driver and database, and finally, add your JDBC driver to the classpath before starting up the Tomcat server.

Figure 4
Figure  4:

You may recall that at the start of our JSP page, we had the errorPage= "error.jsp" line in our page directive. You may also have noticed that none of the usual try...catch blocks were wrapping our database code. If so, kudos, you're very observant. In any event, these two are intimately linked, and one of the things that makes JSP so quick to develop Web applications is that you don't need any exception- handling code in your JSP file. Instead, you designate an error page that handles all error conditions. You can have one error page for all JSP files or separate error pages for every JSP file. The level of detail is up to you. Since the error page is a JSP file, you can do quite a bit inside them, including simple things like changing the color or fonts of the HTML page to automatically contacting administrators with error conditions.

Conclusion
While this example is somewhat contrived, it demonstrates all the relevant concepts needed to connect a JSP page to a database. In a production system a better approach would be to encapsulate the database operations in JavaBeans, which would simplify their reuse and maintainability. Since JSP files can also be connected to Servlets (which can maintain state and are higher performance than JSP), we could also push our query interactions to a Servlet and leave the JSP to handle the user interactions. Clearly there's a lot more to explore here than I can fit into one article. Hopefully you'll now feel confident to play with this example and the other JSP articles in this issue.

Author Bio
Robert Brunner is a member of the research staff at the California Institute of Technology, where he focuses on very large (multiterabyte) databases, particularly on KDD (Knowledge Discovery in Databases) and advanced indexing techniques. He has used Java and databases for more than three years and has been the Java database instructor for the Java Programming Certificate at California State University, Pomona, for the past two years. [email protected]

 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.