JavaServer Pages with JBuilder

Christopher M. Judd - Judd Solutions, LLC.
http://www.juddsolutions.com


Introduction

History

Web Development

Java's Role in Web Development

JSP Overview

JSP Advantages

Development Process

JSP Anatomy

Template Formats

Directives

Scripting Elements

Actions

JavaBeans

Implicit Objects

Web Container

Deployment

Deployment Descriptors

Debugging

Architectures using JSP

Summary

Resources


Introduction

Like it or not, the Internet and especially the World Wide Web (WWW) have changed our lives (or at least affected it). For instance, Christmas shopping has never been easier. This past Christmas my wife and I shopped from the comfort of our own home. We were able to shop for the gifts we wanted and have them delivered without having to fight the crowds or driving though the snow. We even had access to products that are not available in our area, such as Ben and Jerry's ice cream gift certificates. Yummy!!!

History

The WWW originally gained popularity as a means of sharing documents. Even though there were other Internet based document sharing protocols such as Gopher, the WWW took a new and improved approach. The WWW was built on HTTP (Hypertext Transfer Protocol). HTTP allows client software called browsers to request documents from server-side software called a Web Server. The Web Server locates the requested documents defined in HTML (Hypertext Markup Language) or common image formats and returns it to the browser. The HTML format allows rich documents that could be interconnected though hyperlinks. The browser is responsible for interpreting the HTML, including the graphics and rendering it for the user. This makes the association between the browser and web server nothing more than a common client/server relationship.

Sharing documents in a client/server environment provides significant advantages of consistency and low-cost distribution. Changing the document on the web server immediately gives everybody access to the current document. Furthermore, accessing documents via the web is less expensive than printing the materials and sending them though interoffice mail, US postal mail or internationally.

Web Development

Sharing static documents is still a common use of the WWW. However, this is no longer the only aspect or use of the Internet today. Organizations quickly began making their web presence interactive improving the web surfer's experience and providing value through additional functionality. Retail firms began making the Internet an increasingly important channel for marketing and selling products. Consider Amazon.com, it doesn't just provide a static list of publications but allows the consumer to purchase and rate books.

Because of the client/server nature of the Internet, there are two options to make web pages interactive. Interactive functionality can either be offloaded to the client machine by running instructions inside the process of the web browser or performed on the server-side creating dynamic web pages by accessing resources behind a firewall. Server-side resources might include relational databases or business logic. Usually, interactive web sites require a combination of both server and client-side interaction.

There are many options for providing functionality on both the client-side and server-side each with its own advantages and disadvantages. The options on the client-side include Applets, JavaScript, VBScript, ActiveX or browser plug-ins. There are many more options to choose from on the server-side. Part of the decision of what to use may be determined by the types of resource that must be accessed. Common resources would include relational database or application servers. Server-side options include CGI, Perl, Servlets, JSP, ASP, PHP, Server-side JavaScript and proprietary solutions such as Macromedia ColdFusion, BroadVision and Vignette.

Web Technologies
Figure 1 - Web Technologies

Java's Role in Web Development

Java provides three technologies to enable interactive web site development: Applets, Servlets, and JavaServer Pages (JSP). These technologies provide all the desirable characteristics that compel organizations to use Java: robustness, security and platform independence.

Applets are often the first Java technology to which people are introduced. In fact, many people believed Applets represent the extent of Java's capabilities. Applets provide client-side functionality by running in the context of an applet container. The most common applet container is a web browser. Browsers download the class files from a web server either one at a time or as a group in a jar file. The browser is responsible for starting a Java Virtual Machine (JVM) or plug-in and giving it the class files. The browser is responsible for handling the lifecycle of the Applet. As a technology, Applets have experienced the typical "pendulum-swing" of usage. Initially nearly everything seemed to be implemented as an applet. Then their use seemed to diminish. Today they are being used more closely to their original designed intent: small light-weight visual utility elements on web pages.

Figure 2 - Grade Point Average Applet

Servlets provide dynamic functionality on the server-side as a compiled class. The servlet class is managed by a server process called a web container. The web container understands the HTTP protocol and excepts requests from a browser. The web container is responsible for loading the necessary servlet classes and passes the request on to them. The servlet uses the request, additional resources and services such as relational databases or application servers to build a dynamic HTML page. The resulting HTML page is returned to the web browser. Servlets may also be used to generate other document formats such as XML. It is also becoming popular to use Servlets to transform XML into XHTML using XSLT. The web container continues to manage the lifecycle of the servlet after the request. Most web containers can be configured to unload the servlet after a period of inactivity.

Servlets and Applets are beyond the scope of this paper. If you wish to learn more about these technologies please visit www.javasoft.com or the Borland Community Site. The third technology is JavaServer Pages (JSP) and the focus of this paper. The next section will introduce JavaServer Pages.

JSP Overview

JavaServer Pages (JSP) are a flexible template driven format used to produce dynamic text output. The most common template is HTML.  Therefore, JSP is often used to produce flexible cross-platform presentation layers for the web. JSP combine the template, scripting elements, actions and access to the full Java API to produce output. Similar to Servlets, JSP pages may use resources such as relational database and application servers to provide the dynamic content. We will explore the anatomy of JSP later in the paper. A simple example of a JSP is listed in Listing 1.

<%@page import="java.util.*" %>
<html>
<head>
  <title>Hello World</title>
</head>
<body>
  <h1>Hello World</h1>
  <p>Today's date is <%= new Date().toString() %></p>
</body>
Listing 1 - Simple JSP example

 To get the full understanding of JSP requires the knowledge that a JSP ultimately becomes a Servlet.  The first time a JSP is requested, the web container generates a Servlet from it (see listing 2). The container then compiles and loads the resulting Servlet. The servlet is passed the request and it's executed to produce the output. All subsequent requests of the JSP are then handled directly by the servlet. This combines the advantage of development productivity with the speed of executing bytecode.

Figure 3 - JSP request cycle
package org.apache.jsp;

import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import org.apache.jasper.runtime.*;


public class HelloWorld$jsp extends HttpJspBase {


    static {
    }
    public HelloWorld$jsp( ) {
    }

    private static boolean _jspx_inited = false;

    public final void _jspx_init() throws org.apache.jasper.runtime.JspException {
    }

    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;
        String  _value = null;
        try {

            if (_jspx_inited == false) {
                synchronized (this) {
                    if (_jspx_inited == false) {
                        _jspx_init();
                        _jspx_inited = true;
                    }
                }
            }
            _jspxFactory = JspFactory.getDefaultFactory();
            response.setContentType("text/html;charset=ISO-8859-1");
            pageContext = _jspxFactory.getPageContext(this, request, response,
			"", true, 8192, true);

            application = pageContext.getServletContext();
            config = pageContext.getServletConfig();
            session = pageContext.getSession();
            out = pageContext.getOut();

            // HTML // begin [file="/HelloWorld.jsp";from=(0,31);to=(7,21)]
                out.write("\r\n<html>\r\n<head>\r\n  <title>Hello " +
                          "World</title>\r\n</head>\r\n<body>\r\n " +
                          " <h1>Hello World</h1>\r\n  <p>Today's date is ");

            // end
            // begin [file="/HelloWorld.jsp";from=(7,24);to=(7,47)]
                out.print( new Date().toString() );
            // end
            // HTML // begin [file="/HelloWorld.jsp";from=(7,49);to=(11,0)]
                out.write("</p>\r\n</body>\r\n</html>\r\n\r\n");

            // end

        } catch (Throwable t) {
            if (out != null && out.getBufferSize() != 0)
                out.clearBuffer();
            if (pageContext != null) pageContext.handlePageException(t);
        } finally {
            if (_jspxFactory != null) _jspxFactory.releasePageContext(pageContext);
        }
    }
}
Listing 2 - Servlet code for listing 1

JSP Advantages

Since JSPs ultimately become Servlets and provide the same server-side functionality, you many wonder why not just write Servlets. But JSPs provide many advantages over Servlets and other server-side solutions. Some of them include development simplicity, separation of responsibilities and the ability to use common HTML tools.

JSPs and Servlets development is intended for different audiences. Because Servlets are compiled Java code in the form of classes it really requires the knowledge of a skilled Java developer. Servlet developers need to understand the Java language, Object-Oriented principles and the Java development process including compiling and configuration. In addition, servlet developers should have a good understanding of web development. JSP on the other hand is intended for web designers or less skilled developers. If structured correctly, software developers build tag libraries the designers use to build the final page. Using JSP actually provides a good separation of responsibilities. Most software developers do not want to spend their time adding and modifying HTML in System.out.println() calls. Furthermore, I know from experience that it is difficult for designer's to convey their full intent to developers. Unfortunately, developers typically make poor designers and vise-versa (No offense). In addition, designers and developers do not enjoy performing each other's responsibilities.

With the simplicity and template nature of JSP, designers can use familiar tools such as Macromedia Dreamweaver. Since JSP uses tags, common shrink-wrapped tools can be extended to support custom JSP tags. Designers do not even need to know how to compile a Java class. When they are finished with a page that includes JSP tags they just copy it to a web container and test it.

The most significant argument for using JSP is productivity. I have found that I can be much more productive using JSP. There are a couple of reasons. First, I don't have to wrap all the HTML produced with my HTML editors in Java. This means I can reduce a major step required in servlet development. Second, because the web container handles the compiling for me I don't have to recompile. Furthermore, I don't need to restart the application server or redeploy the web application when changes are made.  The web container automatically recognizes the changes and forces a recompile on the following request.

Development Process

One of the biggest advantages of JSPs over Servlets is the ease of the development process. Unlike Servlets, the web container does not have to be stopped and restarted every time there is a change. Just making a change to a JSP and re-requesting it from the browser will cause the web container to notice it has been updated causing the web container to recompile the page. Therefore the JSP development process is as follows:

  1. Write the JSPs in a text editor such as Borland JBuilder, Macromedia Dreamweaver, Macromedia HomeSite, Microsoft FrontPage or VI.
  2. Unit test the pages interactively by using a web browser to request the JSPs from a web container.
  3. Build a web archive.
  4. Deploy the web archive for quality assurance (QA) testing.
  5. Upon successful test completion, deploy the web archive to the production server(s).

JSP Anatomy

Now for the definition of JavaServer Pages. A JSP page is a collection of the following: template text, scripting elements, directives and actions managed and processed by a web container for then intent to produce dynamic web content. JSP could be considered a cross between Microsoft's Active Server Pages (ASP) and Macromedia's ColdFusion. Like ASP, JSP are usually HTML documents with embedded source code. ASP uses VBScript as its language while JSP uses Java. JSP also has a concept of a tags similar to ColdFusion.  The differentiator between JSP and these other server-side template driven formats is JSP pages access to the entire Java API. In the next couple of sections, I will explain these parts in detail and the aspects of using JavaBeans, the implicitly available objects, web containers and deployment descriptors.

Template Formats

While most organizations use JSP for its HTML-output capabilities, it is not restricted to that format alone. JSP can really produce any text format. Other common formats would include XML, XHTML, WML and Formatting Objects.

Directives

Within a JSP, instructions can be given to the web container through directives. The directives page, include and taglib tell the container how to locate resources and manage the page. The syntax for a directive is <%@ directive_name {attr="value"} %>.

The page directive tells the web container how to manage the page in which it is declared. Listing 3 shows a typical page directive. The page directive has many optional attributes. For the entire list check out the JavaServer Pages Specifications or JavaServer Pages (JSP) Syntax Card. The info attribute is a descriptive name for the page. The import attribute is identical in functionality to a Java import statement; however the syntax is a little different. It contains a comma delimited list of packages or fully qualified class names. Do not put multiple import attributes in a single page directive or all but the first will be ignored. If the import attribute value becomes too long, use multiple page directives each containing its own import attribute. A session object is one of the implicit objects to be discussed later. If a reference to the session object is required, the session attribute must be included in the page directive with a value of true. Exceptions in JSP are handled by forwarding the request to an error page. The error attribute tells the web container where to forward the request. The error page requires a page directive containing the attribute isErrorPage to be able to reference the implicit exception object. Listing 4 shows an example of a JSP error page.

<%@page
   info = "CommonTags.jsp V1.0"
   import = "java.util.*,java.sql.*"
   session = "true"
   errorPage="CommonError.jsp"
%>
Listing 3 - Typical page directive (CommonTags.jsp)
<%@page
   isErrorPage="true"
   import = "java.io.*"
%>
<html>
<head>
  <title>Common Tags Error Page</title>
</head>
<body>
  <h1>Error</h1>
  <p>
    <font color="red"><b>A serious error has occured.<b></font>
  </p>
  <p>
    Exception Type: <b><%= exception.getClass().getName() %></b><br/>
    Exception Message: <b><%= exception.getMessage() %></b><br/>
    Stack Trace:<br/><br/>
    <%
      PrintWriter pw = new PrintWriter(out);
      exception.printStackTrace(pw);
    %>
  </p>
</body>
</html>
Listing 4 - Typical error page (CommonError.jsp)

The include directive is used to substitute the tag with the specified file. Common uses for the include directive are menus, headers, footers or shared JSP code. Listing 5 shows an example of including a menu.

<%@ include file="menu.jsp" %>
Listing 5 - Include directive example (CommonTags.jsp)

The taglib directive is used to specify tag libraries. This directive is detailed in Action section of this paper.

Scripting Elements

For simple web applications, scripting elements can be used to embed Java code. Within the scripting elements is full access to the rich Java APIs. I have created several web pages in the past that used JDBC and JavaMail in scripting elements. One word of caution, as I found out, it is very tempting to put all your code into scripting elements. Unfortunately, scripting elements do not provide for good reuse between JSP pages or other types of applications. Later we will investigate how to get reuse by using custom actions and JavaBeans. So, if you find yourself using scripting elements excessively, consider creating custom actions or JavaBeans.

There are three types of scripting elements; expressions, scriptlets and declarations. The expression scripting element is really a short cut for out.println(). The syntax <%= ... %> contains an expression to be outputted as part of the template. Listing 6 shows an example of a expression element. If you come from an ASP background you may be concerned about using expressions elements. Don't be. Unlike ASP, JSP is compiled to a servlet the first time it is requested. Therefore, you don't have to worry about the parser starting and stopping every time it reaches a scripting element because it only happens the first time.

5 + 7 = <%= 5 +  7 %>
Listing 6 - Expression element (CommonTags.jsp)

Scriptlets are elements denoted by a opening and closing <% ... %>. Any valid Java code can be placed between <% ... %>. Listing 7 shows an example.

<%
  out.println("Current time in milliseconds is ");
  out.println(System.currentTimeMillis());  
%>
Listing 7 - Scriptlet element (CommonTags.jsp)

A declaration can be used to initialize variables and methods. The declaration must come prior to the scriptlets using them. Listing 8 shows an example of a declaration. Be aware, variables are instance members of the resulting servlet.  The value of the variable is retained between invocations of the same instance.  The value is reinitialized if the servlet is unloaded due to expiration or container recycling. In addition, the value may become unpredictable under heavy loads when multiple instances of the servlet are loaded to meet demand.

<%! 
    int i = 1; // declaration variable
    String msg = "Common Tags"; // another declaration variable
    // declare a method
    String foo() { 
      return "foo was called";
    } 
%> 
Listing 8 - Declaration (CommonTags.jsp)

Actions

Actions are tags that can and should be used to replace scripting elements. They were introduced to separate the division of labor between a developer and a designer. A designer would use the tags within their design tools of choice preventing them from having to write Java code in scripting elements to produce dynamic content. Because of JSP's history and documentation I am often asked by developers, "If I don't have designers on my team why would I use action tags?" They usually follow the question up with, " I am a developer I want to code." My response is rhetorical, "Do you write methods?" Of course they do, methods provide reuse. Action tags should be used for the same reason. Action tags can be used by multiple JSP pages and scripting elements cannot. Action tags also provide a good method of achieving the design goal of removing code from the presentation layer.

Action tags follow the XML namespace syntax of <prefix:action_name {attr="value"}* /> or <prefix:action_name {attr="value"}* > </prefix:action_name>. Some action tags are build into the JSP specification.  They are noted by a jsp prefix. Some of them will be discussed in the JavaBeans section. 

A collection of action tags is called a tag library. There are may sources of tag libraries. The Apache's Jakarta Project includes tag libraries for dealing with JavaMail, JDBC, regular expressions, logging and other common activities. There is also an effort called JavaServer Pages Standard Tag Library intended to standardize tags that have been duplicated in multiple tag libraries. The JSP Standard Tag Library is in the final stages of the Java Community Process (JCP). Another alternative is to create custom tag libraries. Custom tag libraries will be discussed in the Tag Library section.  

JBuilder includes the InternetBean Express tag library for using its DataExpress components in JSP. As with all tag libraries the first step in using the InternetBean Express is adding a taglib directive that identifies the prefix and the URI of the library (see Listing 9). The JSP Wizard simplifies adding the InternetBean taglib directive by providing the Declare InternetBeans tag library checkbox (see Figure 4). The wizard also adds the necessary taglib elements to the web.xml (explained in Deployment Descriptors) and the internetbeans.jar to the WEB-INF/lib directory (explained in Deployment).

<%@ taglib uri="/internetbeans.tld" prefix="ix" %>
<%@ taglib uri="/internetbeans.tld" prefix="ix" %>
Listing 9 - InternetBean Express tablib directive

Figure 4 - Including the InternetBean Express taglib directive

InternetBean Express contains the tags: database, query, control, image, submit and table. Combing these tags can produce dynamic web pages from database result sets. To learn more about the required and optional attributes of each tag double click on the internetbeans.tld node added by the JSP Wizard.  Listing 10 demonstrates using InternetBean Express to display an employee phone list from the JDataStore sample employee database. This example uses the database, query and table tags. The database tag is equivalent to the DataExpress Database component.  It identifies the JDBC driver and URL to connect to the data source.  It may also require a username and password if appropriate.  A query tag is equivalent to the DataExpress Query component. It represents a result set based on a sql statement in the statement attribute. Any query tags contained within a database tag will use it for the database connection.  The table tag uses the result set from the dataSet attribute to dynamically build an HTML table.  To get the proper look, the table tag contains an HTML table. It uses the HTML table as a template. The table tag associates HTML columns to result set columns by conducting a best match on the HTML column headers (<th>) to the result set column names.

<%@ page import="com.borland.internetbeans.*,com.borland.dx.dataset.*,com.borland.dx.sql.dataset.*" %>
 <%@ taglib uri="/internetbeans.tld" prefix="ix" %>
 <html>
 <head>
  <title>Employees Phone List</title>
 </head>
 <body>
  <h1>Employee Phone List</h1>
  <ix:database id="employeeDB" driver="com.borland.datastore.jdbc.DataStoreDriver"
    url="jdbc:borland:dslocal:F:/java/jbuilder5/samples/JDataStore/datastores/employee.jds"
    username="sample"
  >
   <ix:query id="employees" statement="select FIRST_NAME,LAST_NAME,PHONE_EXT from employee">
    <ix:table dataSet="employees">
     <table id="employees" cellspacing="0" border="1" cellpadding="7">
      <tr>
       <th>First Name</th><th>Last Name</th><th>Phone Ext</th>
      </tr>
      <tr>
       <td>Chris</td><td>Judd</td><td>654</td>
      </tr>
     </table>
    </ix:table>
   </ix:query>
  </ix:database>
 </body>
 </html>  
Listing 10 - InternetBean Express example (Employees.jsp)

Figure 5 - Employee phone list (Employees.jsp)

JavaBeans

Because of the proliferation of JavaBeans, the JSP specification requires that all compliant web containers implement specific action tags for manipulating them. Using JavaBeans with JSP can provide reuse among web applications and other applications. Bean action tags as well as the rest of the required action tags use the jsp and do not require a taglib declarative.

An example of the JavaBean action tags can be found in Listing 11. To get a reference to a JavaBean, use the useBean action. The id attribute is the name of the bean's instance reference. The reference can be used by other action tags or within a scripting element. The scope attribute defines the lifetime of the bean. The options for scope are page, request, session or application. The page scope means the objects are only available within the page they were created.  The request scope makes references available to pages processed in the same request. It should be used when forwarding requests to additional JSP or Servlets. The session scope means objects are accessible as long a valid session exists between a browser and web container.  The application scope references exists as long a the web container is running. The class name is the fully qualified name of the bean. The getProperty and setProperty tags are used to call the getter and setter methods of the bean. The name attribute identifies the bean from the id attribute of the useBean tag. The property attribute identifies the property on the bean that should be invoked. The value attribute of the setProperty tag is the value that will be passed to the setter method. A shortcut to including a setProperty for every input field is setting the value attribute to *. Using this shortcut associates the value of an input field with a property of the same name on the bean.

<html>
<head>
<jsp:useBean id="DebugMessagesBeanId" scope="session" 
             class="com.juddsolutions.example.beans.DebugMessagesBean" />
<jsp:setProperty name="DebugMessagesBeanId" property="*" />
<title> Debug Messages </title>
</head>
<body>

<form method="get">
  <br>Enter new value   :  <input name="sample"><br><br><br>
  <input type="submit" name="Submit" value="Submit">
  <input type="reset" value="Reset"><br>
  Value of Bean property is :<jsp:getProperty
                 name="DebugMessagesBeanId" property="sample" />
</form>

</body>
</html>
Listing 11 - JavaBean action tags (DebugMessage.jsp)

Implicit Objects

Implicit Objects are object to which you automatically have a reference. It's as if a reference was passed to you in a method call. In certain cases it actually is. Remember JSP are compiled to Servlets an therefore the references to the request and response object are passed in the service method calls. Table 1 contains a list of the implicit objects available to JSP pages.

Reference Type Scope Description
request javax.servlet.ServletRequest Request Request information from the browser 
response javax.servlet.ServletResponse Page Response to the request.  Not often used in JSP.
pageContext javax.servlet.jsp.PageContext Page Contains convenience methods.
session javax.servlet.http.HttpSession Session Object representing the session between the browser and web container.
application javax.servlet.ServletContext Application Used for communicating with the web container.
out javax.servlet.jsp.JspWriter Page Output stream contain the HTML returned to the browser. 
config javax.servlet.ServletConfig Page Initialization information including the name and initial parameters.
exception java.lang.Throwable Page Uncaught exception.
Table 1 - Implicit Objects

Listing 12 is an example of using the implicit application reference. The example uses the getInitParameter method to get the value of the debug context-param from web.xml (discussed in Deployment Descriptor)

<html>
<head>
<jsp:useBean id="DebugMessagesBeanId" scope="session" class="com.juddsolutions.example.beans.DebugMessagesBean" />
<jsp:setProperty name="DebugMessagesBeanId" property="*" />
<title> Debug Messages </title>
</head>
<body>
  <h1>Application Object and Context Parameters</h1>
<p>This page demonstrates how a particular type of debugging might be implemented
using the implicit application object and context deployment descriptors.
If the context parameter is set to true, the request query string will be
included in a HTML comment. </p>

<form method="get">
  <br>Enter new value   :  <input name="sample"><br><br><br>
  <input type="submit" name="Submit" value="Submit">
  <input type="reset" value="Reset"><br>
  Value of Bean property is :<jsp:getProperty name="DebugMessagesBeanId" property="sample" />
</form>

<!--
<%
  Boolean debug = new Boolean(application.getInitParameter("debug"));
  if (debug.booleanValue()) {
    out.println("Query String: " + request.getQueryString());
  }
%>
-->
</body>
</html>
Listing 12 - Using Implicit Application Object (DebugMessage.jsp)

Web Container

A web container is the process which proxies HTTP requests from a web browser for JSP and Servlets. Web containers are sometimes referred to as JSP/servlet container, engine or server. Throughout this paper I refer to them generically as a web container, which is how the J2EE specification refers to them. Because the web container proxies the request it is able to manage the lifecycle and provide security. With JSP the web container has one additional responsibility. When the web container receives a request for a JSP it determines whether the JSP has been updated since it was compiled. If it has, it generates servlet code from the JSP and compiles it.

There are many web containers available some stand-alone and others as part of a J2EE implementation. Some of the most common ones are even open source implementations. The most popular is Tomcat, the official reference implementation from the Apache Group. Tomcat is so popular that several J2EE vendors use it as their web container.  This includes Borland Application Server. Seeing commercial J2EE application server vendors rely on open-source proves two theories. First, price is not related to quality. Second, J2EE's goal of best-of-breed solutions are a reality not a dream. Other well-known containers are Resin and Jetty. JSP written to the specification will be able to run without change in any compliant web container.

See Resources for information concerning where to download these web containers.

Deployment

There are two ways to deploy JSP applications. The first method is to copy the JSP file to the document root of the web container. The next time the page is requested from a browser the web container will find the JSP and compile it to a servlet. This works well for small applications or development, but it is not feasible for large applications. Nor is it consistently and reliably duplicated.

The second method of deploying an application is defined by the JSP and Servlets specifications.  The specification requires compliant web containers to implement a specific mechanism for packaging a web application. A web application is a collection of JSP pages, Servlets, images and configuration files called deployment descriptors. The collection of files is placed into a jar file with a war extension (web archive). In the case of Tomcat the war file can be deployed by placing the war file in the document root directory (webapps) and recycling the server. Additionally, Tomcat uses the name of war to set the application context. Therefore if the war file is named 2004JSP.war the JSP pages will be requested using the host name and 2004JSP directory, such as http://localhost:8080/2004JSP/ServerSideProps.jsp. Other web containers differ, consult the web container documentation for details regarding web archive deployment.  According to the J2EE specification all J2EE compliant application servers can deploy web applications.

JBuilder simplifies the creation of a war file through the Web Application Wizard (see figure 6) found in the Object Gallery.  The wizard requires a name which is used as the war filename and application context.  It also requires a directory that identifies the document root of the collection that makes up the web application. In JBuilder, web application projects created using the wizard are given a document root directory name of defaultroot by default.  If an alternative name is chosen (I sometimes use websrc), JBuilder creates a defaultroot directory containing an empty web.xml file when the project is build or run.  The empty defaultroot directory maybe discarded.  The wizard also contains a Generate WAR check box.  When selected, JBuilder automatically updates the war when the project is built.  If Generate WAR is not selected, right clicking on the web archive node and selecting rebuild to update the war. 

Figure 6 - Web Application Wizard dialog

After the web application wizard completes it adds a web archive node to the project (see 2004JSP in figure 7).  The web archive node includes a Deployment descriptors, Root directory, a war (optional) nodes.  The Deployment descriptors node contains the web.xml, web application deployment descriptor, node (discussed in the Deployment Descriptors section).

Figure 7 - Web archive node

Deployment Descriptors

Deployment Descriptors are configuration settings describing how a container should manage its components. In the case of a web application they determine how a web container should manage JSP and Servlets. Web application deployment descriptors reside in the web.xml file found in the WEB-INF directory. Some web containers may also require an additional file for proprietary descriptors. Consult the documentation of your web container.

With respect to JSP, deployment descriptors may be minimal. In many cases they may not be necessary at all or they may be as simple as the example in Listing 13.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app />
Listing 13 - Common web.xml file

To simplify the process of building the web.xml file for web applications, JBuilder has added the WebApp DD Editor. The WebApp DD Editor (Figure 8) provides a Swing based interface for changing values of the web.xml file. Previously this would have been done by modifying XML tags in a text editor. This editor works a little differently than other JBuilder editors I have used. When an item is selected in the structure pane the editor changes to show an appropriate editor for the selected item.

WebApp DD Editor

Figure 8 - WebApp DD Editor

Configurations you might set in the WebApp DD Editor that relate to JSP are Tag Libraries and Context Parameters. If you are building J2EE applications you may also need to become familiar with Resource References, EJB References, Login and Security descriptors.

As mentioned earlier, tag libraries are important for removing logic from the presentation layer and reusing code. The taglib deployment descriptor identifies a name used to identify the library in the JSP (taglib-uri) and the location of where the library resides (taglib-location). These tags provide an important layer of abstraction in the JSP architecture. It allow the jar containing the Tag Libraries to be moved without having to modify any code.

<taglib>
  <taglib-uri>/internetbeans.tld</taglib-uri>
  <taglib-location>/WEB-INF/lib/internetbeans.jar</taglib-location>
</taglib>
Figure 14 - Tag Library Example

Context Parameters can be a great place to put application specific configurations. In the past, I have used them to store JDBC information. Then within the JSP you can gain access to the information by using the application.getInitParameter(). and passing the parameter name. Additionally, I sometimes include debug statements in the resulting HTML pages stored in HTML comments so they do not affect the rendering of the page in the browser. In the Listing 15 example that follows I used a Context Parameter to control whether debugging is on or off.

<context-param>
  <param-name>debug</param-name>
  <param-value>true</param-value>
  <description>Determines whether debug messages are shown.</description>
</context-param>
Listing 15 - Context Parameter Example

JSP often use other resources such as JDBC that require specific classes to be in the classpath. Adding classes to the classpath of a typical Swing or command-line application is as simple as adding a jar or directory to the -cp vm argument or adding them to the systems CLASSPATH environment variable.  Web applications provide a challenge because a web container may host multiple web applications requiring different versions of the same classes. The JSP specification addresses this by identifying two special directories. Jars put in the WEB-INF\lib directory are automatically added to a web applications classpath.  Likewise, classes in the WEB-INF\classes directory are also automatically added to the web application's classpath.  Because each web application is loaded in its own class loader they are permitted to have different versions of the same classes. 

Debugging

Leave it to Borland to simplify JSP debugging. If you have ever debugged any Java code in JBuilder then you already know how to debug JSPs in JBuilder. Debugging in JBuilder involves setting breakpoints on executable statements of code in the JSP. A breakpoint can be set by clicking in the gutter, pressing F5 or using the editor context menu item Toggle Breakpoint. Next start the debugger. Right clicking on a JSP node in the Project Pane reveals Web Debug menu item. Selecting Web Debug will cause Tomcat to run until a breakpoint is encountered. Use the buttons on the debug toolbar to navigate through the Java portions of JSP. If you are unsure if a particular line is executable or not just run it in debug mode and JBuilder will identify the executable lines with a blue dot in the gutter.

JBuilder uses an embedded web browser to support debugging. After starting running Web Run or Web Debug a Web View tab is added to the content window. This browser is not a full featured browser but it has enough features for JSP development. A Web View Source tab is also added containing the HTML that is rendered in the Web View. The Web View Source is an excellent debugging tool.

I am not sure if the following anecdote truly fits under the topic of debugging but it was a very valuable web development lesson for me. I had created a website using PHP3 for a small start-up company. Because the company was just starting off, it made sense to have somebody else host the site. The application ran fine for months when suddenly I got an urgent call from my client saying the website was not working at all. Fortunately, PHP3 comes with a script that prints out the PHP3, web server and host machine configurations. Fortunately, I had printed of a copy of these configurations when I first started the project. Comparing my printout with the output of a current run of the script, I discovered PHP3 had been reconfigured by the hosting service. Recognizing this minor but significant difference allowed me to make a minor change to the scripts and the website was up and running quickly. I have not yet experienced this in my JSP development, but nonetheless, I keep a copy of an equivalent JSP to help identify changes made by operations or someone else. It helps identify differences between development, test and production environments. I have included with the examples a JSP named ServerSideProps.jsp that is such a file.

Architectures using JSP

There are four common JSP architectures: JavaBeans, JDBC, Model 2 and J2EE.

The first architecture is so common that it was built into the JSP specification. The specification provides tags to easily set and get properties of JavaBeans. This provides an easy way of creating reusable business logic classes accessible from JSP as well as other Java applications.

JavaBeans

Figure 9 - Using JSP and JavaBeans

Many websites store information in relational databases. The second architecture involves accessing the JDBC API for data retrieval directly bypassing JavaBeans.

JDBC

Figure 10 - Connecting to JDBC

The architecture receiving the most press recently is Model 2. Model 2 is a specific implementation of the Model/View/Controller (MVC) design pattern for the web. This follows a similar architecture as is used with Java Swing components. The Model 2 separates responsibilities into three parts as does MVC but adds a slight twist because of the web. As with MVC the model represents the data that comes from JavaBean properties. The view is the presentation layer and the part usually implemented by JSPs. The control is handled by the web container and the non-view portion of the servlet. They act as the glue between the JavaBean and JSPs. There is a popular framework for this architecture called Struts . It is a part of the Apache Jakarta Project like Tomcat.

Model 2

Figure 11 - Model 2 or Model/View/Control

JavaServer Pages (JSP) also play a major role in the Java 2 Enterprise Edition (J2EE). The implementation of a web container supporting JSPs and Servlets is actually required by the specification. JSP are included as a part of the server-side presentation layer. They have access to all of the services offered by a J2EE application server such as JavaMail, JNDI, JDBC, EJB, JMS or XML.

J2EE

Figure 12 - J2EE

Summary

JavaServer Pages (JSP) provide an elegant and simple way to produce websites and other template driven applications. Using JSP separates responsibilities allowing employees to focus on their particular skill set. Furthermore, JSP is a first class citizen of enterprise development as a major component in the J2EE specification.

Resources

Download source code

JavaServer Pages
JavaServer Pages Specifications

JavaServer Pages (JSP) Syntax Card
JSP Standard Tag Library (JSTL)
HTML 4.01 Specification
HTTP/1.1 Specification

Web Containers

JSP Tutorials

JSP Websites

Apache Jakarta Project

Copyright © 2002 Judd Solutions, LLC