Chapter 17. Introduction to Servlets

CGI—The First Generation of Dynamic Content Generation Tools

In the early days of the World Wide Web, most content available was static in nature. One of the first Web servers available came from CERN, the European Organization for Nuclear Research in Switzerland. It released httpd, its Web server, in June 1991. At that time, a Web author would create pages, often with just a text editor, and publish them on a Web site. Most sites were very small by today’s standards and could be easily maintained by a few people. Changes to the content of a page or of the site had to be changed by hand by the content authors.

However, Web authors quickly realized that it was also important to make dynamic content available. For example, a content author may want to present information stored in a database. In November 1993 the CERN httpd Web server was updated to include what would eventually be known as the Common Gateway Interface or CGI.

CGI specifies an interface between a Web server and an external program. The external program could, for example, query a database, generate an HTML table of the results, and supply the HTML stream back to the Web server. The Web server would then send the stream back to the browser client.

CGI solves much of the problem of generating dynamic content. However, it is not without its faults. The primary issue with CGI is that it is traditionally implemented via a separate operating system process from the Web server. This means that for every request for dynamic content a new operating system process has to be created, initialized, and run. Then the results from that external process are fed back into the Web server to be passed on to the browser. The separate process then ends, losing any work already done, such as creating database connections.

A secondary issue is the definition of the interface itself. Because of its roots, CGI defines a very simple interface between the Web server and the CGI program that is being run. Basically a set of key/value pairs are passed from the Web server to the CGI program and the CGI program is responsible for generating the entire HTTP response. Although this simplifies implementation, it does not encourage good programming practices like using object-oriented programming.

There have been improvements in the CGI model over the years. The main improvement is building interpreters such as Perl or PHP into the Web server. This allows, for example, Perl CGI scripts to run in the same process space as the Web server, improving the scalability of the server. Because the server no longer has to create a new process for every request for dynamic content, a single server can handle a greater number of client requests. However, because these languages are still interpreted there are still scalability issues with this solution.

A Better Way—Servlets

J2EE defines a very complete solution to the challenge of generating dynamic content. The first line of client interaction is the servlet.

What Is a Servlet?

A servlet is a small J2EE component designed to run on a Java Web server. It can receive and respond to requests from clients usually using HTTP. Servlets extend the capabilities of the Web server by having access to the entire spectrum of J2EE services including database access and security. Because they are written in Java, they take advantage of the portability and security that Java offers.

Servlets are created and initialized once and are generally not removed from the Web server during normal operation. Because they have a lifetime that is greater than that of a single HTTP request, there is not the overhead of creating additional operating system processes. This can greatly improve the scalability of the Web server.

Most servlets are able to serve multiple clients simultaneously. The server in which the servlet runs creates a new thread for each client request and dispatches the request to the same instance of the servlet. This is a vast departure from CGI where the Web server creates an entire new operating system process.

Handling HTTP Clients—The HttpServlet Class

Servlets have a specialized class for dealing with HTTP clients such as browsers. The javax.servlet.http.HttpServlet class simplifies the delivery of dynamic content with a unified programming interface to the Web stream. It can drastically simplify the programming task of handling and generating dynamic content.

Servlet Technologies

The servlet classes all exist under the javax.servlet package, part of a standard J2EE distribution. For WebLogic 7.0 this package is in the weblogic.jar file. The servlet class hierarchy is straightforward having just three main classes or interfaces. Figure 17.1 shows the hierarchy and the methods within the classes and interfaces.

The Servlet class hierarchy through the HttpServlet class.

Figure 17.1. The Servlet class hierarchy through the HttpServlet class.

The Servlet API—Commonly Used Methods

The most common way to use the servlet package is by extending HttpServlet. You then override one or more of the following methods as needed by your application.

Note

Commonly a HttpServlet only overrides init(), destroy(), and either doPost() or doGet(): If you have one servlet that is handling multiple HTTP actions (such as GET and POST), you may want to consider separating the functionality of the servlet into multiple different servlets. Alternatively, you should look closely at how the servlet is being used. Is there really a need for both a doPost() and a doGet() method? Often you just want one or the other.

  • init()—. Called once when a servlet is initialized. It is used to initialize any variables in the servlet that will be used by other methods. Additionally, this is usually the place to read any servlet configuration information. We will examine how to do that later.

  • service()—. Called by the J2EE server when a request directed at the servlet is received. This allows the servlet to respond to the request. When used in an HttpServlet, the service() method automatically calls the appropriate service method (such as doGet()) depending on the type of HTTP request received. As HttpServlet defines methods for all of the HTTP actions, you commonly don’t override this method.

    Tip

    If your application requires that multiple service methods do the same thing it is better to have them each call a common method rather than override this method. Different servlet containers may do bookkeeping or other work within the service() method and, by overriding it, you lose some of that functionality.

  • destroy()—. Called when a servlet is being taken from the J2EE server. This can happen automatically if the server chooses or it can happen because of an administrative user removing the servlet manually. The server may choose to remove the servlet for a variety of reasons including lack of use of the servlet (that is, no clients are requesting it and haven’t for a long time) or to try to recover memory.

  • doGet()—. Called for HTTP GET messages. This is the most common form of HTTP requests. HTTP GET requests are sent, for example, from a browser requesting a particular URL.

  • doPost()—. Handles HTTP POST messages. A message of this type is commonly sent from an HTML form. Additionally, Web services often use the POST method to communicate with a service provider (see Chapter 29, “Web Services and the WebLogic Platform,” for more information).

The Servlet Container

Servlets are executed in a servlet container. A servlet container manages the life cycle of the servlet from its creation through its destruction. Unlike normal Java classes, you will never directly create a servlet class; it is created for you by the container on an event-driven model. This simplifies development, as the servlet author does not have to be concerned about creating and managing a servlet. Its lifecycle is taken care of by the servlet container.

The Servlet Lifecycle

When the servlet container needs to create a servlet, it first invokes the init() method on the servlet. This is where you would set up any resources that may be shared across multiple invocations of the service methods for your servlet. For example, we may initialize a database connection pool in the init() method so that other methods are able to use it.

After a servlet is initialized, it is ready to serve client requests. The servlet container automatically calls the service() method of a servlet when the URL requested matches the URL that the servlet has been registered to handle. The service() method is overridden in the HttpServlet and in turn, it calls the appropriate service method on the servlet based on the type of HTTP request. If your servlet has overridden the method, your method is called instead. As long as the servlet is still in the servlet container, the service() method will be called for each request.

Servlets can be removed for a variety of reasons:

  • They can be removed manually by an administrator.

  • The servlet container itself might remove them if the server is running low on resources.

  • A method within the servlet throws an UnavailableException. The container has the option of removing the servlet at that time.

  • They are removed when a container is shutting down.

When any of these events occur, the destroy() method is called on the servlet. This is where the servlet should release any resources it has acquired, such as database connections.

Caution

Use the init()/destroy() method pair with caution. A servlet may never be removed from the container. If the application server is not running low on memory and doesn’t have a facility to remove rarely used servlets, (most don’t including WebLogic 7.0), the destroy() method will never be called during normal operation. For example, if a servlet gets a database connection at init() time and does not release it until the destroy() method is called, it probably will not release the connection as long as the server is running. Database connection pooling is one way to handle this situation so that you do not take up shared resources for as long.

Servlets and Threads

An important advantage of servlets over CGI programs is that servlets are, by default, multi-threaded. This means that regardless of how many clients are attempting to access the servlet there is only one instance of the servlet class in the container. In CGI, a new process is spawned for each request. Although it is important to keep in mind threading issues when developing a servlet, the reuse of a single servlet greatly expands the scalability of a servlet-based server.

If a particular servlet cannot have multiple simultaneous accesses to it, the developer can have it implement the SingleThreadModel. This is a flag to the servlet container that tells it to serialize access to the servlet so that only one thread at a time uses it. The container is also allowed to create a pool of the single threaded servlets to help with scalability.

Why would you ever need a single-threaded servlet? The biggest reason would be if the servlet was a facade on a resource that itself could not handle multiple simultaneous client requests. For example, consider that you created a print servlet that sends whatever you have in your browser over a parallel port to a printer. In this case, you would want only one client accessing that servlet at a time. If you did not you might get parts of one printout intermixed with another. However, even this may not work as the container is allowed to create a pool of these servlets and dispatch client requests to one of the instances. The WebLogic 7.0 servlet container does just this with SingleThreadModel servlets and so you would need additional synchronization outside of the servlet itself.

Creating Your First Servlet

When a user asks for a page in a browser, he commonly uses the HTTP GET method. This means that the browser asks the server to “get” the item described by the universal resource locator or URL. The corresponding HttpServlet service method is doGet(). This method is called on the servlet by the container when an HTTP GET request is made. You will cover how the container maps a servlet to a URL in a later section.

A doGet() Servlet Example

Listing 17.1 shows a very simple HTTP servlet that displays the parameters of a client request. The example code shows how to use the doGet() method to interact with the browser or other Web-based client.

Example 17.1. MyFirstServlet.java—A Servlet to Print Browser Information

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class MyFirstServlet extends HttpServlet
{
public void doGet( HttpServletRequest request,
    HttpServletResponse response )
    throws ServletException, IOException
    {
//
// get a simple way of putting text into the response
//
ServletOutputStream    out = response.getOutputStream();
//
// tell the client (possibly a browser) what type of document is being returned
//
response.setContentType("text/html");
//
// generate the required HTML elements
//
out.println("<html><head><title>Hello!</title></head><body>" );
//
// generate some dynamic content. the method getRemoteHost() on HttpServletRequest
// returns the host name (i.e. www.objectmind.com) from where the request came from
//
out.println( "Welcome " + request.getRemoteHost() + ".<br>" );
//
// print out the user agent information from the browser
//       out.println( "Your user agent string is " +
                    request.getHeader( "User-Agent" ) );
//
// finish the html page
//
out.println( "</body></html>" );
    }
}

Adding doPost() to the Servlet

The other commonly used service method is doPost(), which is called via the HTTP POST method. One way that this method could be called is if an HTML form specified “post” as its method, and gave the URL of the servlet as the action; for example, if you had an HTML file that looked like Listing 17.2.

Example 17.2. formTest.html—A Form to Post to Your Servlet

<html>
<head>
<title>A sample form handled by a servlet</title>

<body>
<form action="http://localhost:7001/myFirstWebApp/myfirstservlet" method="post">
    Please enter your name: <input type="text" name="username">
    <input type="submit" value="Submit">
</form>

</body>
</html>

This specifies a small HTML form that would send an HTTP POST to the URL http://localhost:7001/myFirstWebApp/myfirstservlet, the same one you used for the doGet() method. The doPost() method of the servlet would be called with the same arguments as the doGet() method. However, an important difference in this example is that you want to get content that the user entered (in this case a text field labeled as “username”). The HttpServlet makes this task extremely easy, as shown in Listing 17.3.

Example 17.3. MyFirstServlet.java Addition of doPost() Method

public void doPost( HttpServletRequest request,
                    HttpServletResponse response )
    throws ServletException, IOException
{
//
// get a simple way of putting text into the response
//
ServletOutputStream    out = response.getOutputStream();
//
// tell the browser what type of document is being returned
//
response.setContentType("text/html");
//
// generate the required HTML elements
//
out.println("<html><head><title>Hello!</title></head><body>" );
//
// generate dynamic content based on the user input. the method getParameter()
// on HttpServletRequest returns the value of the named parameter from the
// POST request.
//
out.println( "Welcome to my site " + request.getParameter( "username" ) );
//
// finish the html page
//
    out.println( "</body></html>" );

}

Notice that you can get the data from the form by calling the getParameter() method on the HttpServletRequest. In this very simple example, the doPost() method is called when the user clicks on the Submit button on the HTML form. The browser packages up the parameters and sends an HTTP POST to the URL specified. It is the responsibility of the HttpServlet to then pull those parameters apart to allow access to them in the servlet.

An important part of the HttpServlet is the HttpServletRequest and the HttpServletResponse. These classes enable the developer to interact with the input and output of the Web stream. HttpServletRequest has methods that parse the HTML data stream and return these values to the caller. This is faster and less error prone than parsing the HTML directly. In our previous example, you called request.getRemoteHost() to return the name of the client that requested this servlet. This information came from the server-side socket connection that the client is using. Obviously, it is much simpler to call this method than have to deal directly with the socket semantics.

Other methods available through HttpServletRequest include the following:

  • getLocale()—. Returns the java.util.Locale of the browser based on the “Accept-Language” HTTP header. This allows easier internationalization based on the language that the browser is using.

  • getCookies()—. Returns an array of all of the javax.servlet.http.Cookie objects that the client sent.

  • getSession()—. An incredibly useful method that helps the servlet developer maintain state across multiple client calls. The servlet container automatically assists with session management by either including cookies in the HttpServletResponse or by using URL rewriting. Either way it insulates the developer from the complex task of maintaining state across multiple invocations of the servlet.

The HttpServletResponse class has methods that do the opposite—build the HTTP header so that the developers do not have to generate it themselves. The ones used in our previous example, response.setContentType() and response.getOutputStream(), are the two most commonly used.

The setContentType() method enables the developer to tell the browser what kind of content will be returned. Often this is “text/html” for HTML documents, but it can also be any “mime type” that you need. Mime is an abbreviation for Multipurpose Internet Mail Extensions. These are defined methods for how messages are exchanged between two parties. Although they were originally used for electronic mail, they are also used on Web resources to describe them. RFC 2045 has pointers to more information.

The getOutputStream() method gets a javax.servlet.ServletOutputStream that allows the developer to handle the output stream the same way as any other Java stream. Simple println() methods assist in generating output.

Other methods in the HttpServletResponse class include

  • setStatus()—. Enables the developer to set the status that is contained in the HTTP response. This is something like “200” for an OK response.

  • setContentLength()—. Sets the Content-Length field in the HTTP header to the number of bytes in the body of the response message.

J2EE Packaging for Servlets—Web Applications

J2EE defines a standardized structure in which to deploy servlets; JavaServer Pages (covered in the next chapter); static content, such as images and static HTML pages; and any libraries that are needed to use these components. Web applications, or Webapps, can be packaged in either an exploded directory structure (that is, a normal directory structure with files and subdirectories), or in a war (Web archive) file. A war file is a Java jar file that contains a particular directory structure—the same one as the exploded directory.

Web Application Hierarchy

If you have a Web Application named myFirstWebApp, the directory structure would start out with a top-level directory named the same—myFirstWebApp. The directory structure would then look like this:

myFirstWebApp/
  • WEB-INF/web.xml—This is the Web application deployment descriptor. A deployment descriptor is a J2EE standard way of configuring the Web application. It contains, for example, configuration information for your servlet.

  • WEB-INF/weblogic.xml—This file contains configuration information that is specific to WebLogic Server. This includes information on how to map resources in the web.xml file to resources that exist elsewhere in the physical WebLogic Server environment.

  • WEB-INF/classes—Contains the classes that are part of the Web application. Our sample servlet will be placed under this directory.

  • WEB-INF/lib—Contains jar files and any other needed libraries for this Web application. For this first servlet the lib directory will not be used.

Caution

Directory and file names are case sensitive. On a case-insensitive platform such as Windows your application will run if you have an incorrectly named directory or file. However, on a system with a case-sensitive file system such as Unix, the same application will not work. For portability always ensure that you have the correct case.

Running Your First Servlet in WebLogic 7.0

WebLogic makes it very easy to install and run this sample servlet. For test purposes, we will install this servlet into its own “Webapp” or Web Application.

In our example, WebLogic Server is installed in /usr/local/bea/wlserver700 in a Unix environment or C:eawlserver700 in a Windows environment. Your configuration can be different, but these directories will define the environment variable WL_HOME for WebLogic Server.

To simplify our test we will put our sample servlet into a directory that ships with WebLogic 7.0. This is not required but simplifies this first Web application.

Caution

The example assumes that you have full control over WebLogic Server and it is not used for anything but development. Do not attempt to use these examples on a WebLogic server that is used by others or is used in a production environment.

To deploy the Sample Servlet in WebLogic 7.0, follow these steps:

  1. You need to set up the deployment environment. MyFirstServlet.java, the source code for the sample servlet in Listings 17.1 and 17.3, will reside in the directory samples/server/config/applications/myFirstWebApp/WEB-INF/src (from WL_HOME above). This is the code you created with the doPost() and doGet() methods. The directory firstWebApp and anything under it will not exist and will need to be created for this example. Create the file MyFirstServlet.java using the sample code and save it into the src directory.

    Unix:

    cd $WL_HOME/samples/server/config/applications
    mkdir –p myFirstWebApp/WEB-INF/src
    

    Windows:

    cd %WL_HOME%sampleserverconfigapplications
    mkdir myFirstWebAppWEB-INFsrc
    
  2. Next you need to compile the sample servlet. The compilation process requires you to have the javac command on the path of your command-line interface. The process to do this varies with your operating system. Please see the documentation that is included with your Java distribution for information on how to do this. Alternatively, a Java development kit (JDK) is shipped with WebLogic and can be used instead.

    To compile your servlet in Unix, use the following:

    cd $WL_HOME/samples/server/config/applications/myFirstWebApp/WEB-INF
    mkdir classes
    javac –d classes –classpath 
    $WL_HOME/server/lib/weblogic.jar src/MyFirstServlet.java
    

    In Windows:

    cd %WL_HOME%samplesserverconfigapplicationsmyFirstWebAppWEB-INF
    mkdir classes
    javac –d classes –classpath %WL_HOME%serverlibweblogic.jar 
    srcMyFirstServlet.java
    

    This should create a file named MyFirstServlet.class in the classes directory.

  3. Now you have to create the deployment descriptor for your servlet. In the same directory, (samples/server/config/applications/myFirstWebApp/WEB-INF under the root directory of the WebLogic Server install), use a text editor to create a file named web.xml that has the contents shown in Listing 17.4.

    Example 17.4. web.xml File for myFirstWebApp

    <!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>
    
        <display-name>My First Servlet</display-name>
        <description>
        This is a simple Web application to display some dynamic
       content via a servlet.
        </description>
    
        <servlet>
            <servlet-name>myFirstServlet</servlet-name>
            <servlet-class>MyFirstServlet</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>myFirstServlet</servlet-name>
            <url-pattern>/myfirstservlet</url-pattern>
        </servlet-mapping>
    
    </Web-app>
    

    For this simple example you do not need the weblogic.xml file.

  4. Next, copy the HTML form code from Listing 17.2 into the myFirstWebApp directory and name it formTest.html. Do not put it into the WEB-INF directory but rather as a sibling of the WEB-INF directory.

  5. Now you have the files needed to run the servlet but you have to tell WebLogic that there is a new Web Application to run. It is easiest if you just let WebLogic Server find the Web Application on its own and run it. This can be done most easily by restarting the WebLogic Server. There are a variety of ways to do this that do not require restarting the server, but for this example we will try to keep it simple. If your WebLogic server is running, shut it down by killing the Java process associated with WebLogic Server. Then change to the “samples/server/config/examples” directory (again, under WL_HOME), and run ./startExamplesServer.sh (Unix) or startExamplesServer.bat (Windows). You will see messages about the server starting up and the last few lines will look similar to the following code:

    Starting WebLogic Server...
    ...
    <Jul 12, 2002 11:28:41 AM MDT> <Notice> <WebLogicServer> <000365>
        <Server state changed to RUNNING>
    <Jul 12, 2002 11:28:41 AM MDT> <Notice> <WebLogicServer> <000360>
        <Server started in RUNNING mode>
    

Note

Please see Chapter 10, “Installing and Configuring the WebLogic Server 7” for more detailed information on starting and stopping the WebLogic Server.

To exercise the doGet() method of your servlet go to the URL http://localhost:7001/myFirstWebApp/myfirstservlet. You should see output in your browser that looks like Figure 17.2.

Output from the doGet() method on your sample servlet.

Figure 17.2. Output from the doGet() method on your sample servlet.

To exercise the doPost() method of your servlet, you will access it via the HTML file created in step 4. Go to the URL http://localhost:7001/myFirstWebApp/formTest.html. You should see output similar to that shown in Figure 17.3.

Output from the doPost() method on your sample servlet.

Figure 17.3. Output from the doPost() method on your sample servlet.

When you click the Submit button you will get something that looks like Figure 17.4.

Visitors to your site who submit their names will see this greeting.

Figure 17.4. Visitors to your site who submit their names will see this greeting.

Servlet Advanced Features

Servlets have other features that greatly improve their maintainability in the J2EE environment.

Initialization Parameters for Servlets

One way you could expand your servlet would be to add a connection to a database to retrieve, for example, the user’s account balance when he enters his username in the HTML form. The servlet reading from the database would need information such as the JDBC driver name being used along with the URL of the database.

There are many ways you could conceive of to pass initialization parameters to the servlet. You could have a file living in a particular directory or some other method. However, some of the best things that J2EE provides are simplicity and consistency across different vendor’s application server implementation.

The J2EE method of passing initialization parameters to a servlet is very simple. In the web.xml file that you created you add an XML stanza that looks like this:

<init-param>
        <param-name>dbClass</param-name>
        <param-value>org.postgresql.Driver</param-value>
</init-param>

This addition enables you to get, in this case, the class name of the database driver that you will use to connect to the database. Your code to access this initialization parameter would look like this:

public void init( ServletConfig config ) throws ServletException
{
    super.init( config);

    String dbClass = getInitParameter( "dbClass" );
}

The init() method of a servlet enables the developer to do any sort of initialization that is required before any requests are processed. As shown, this can include reading configuration parameters, but can also include, for example, getting a connection to a database to be used during processing.

Database Access Using WebLogic Server 7.0 Services

As shown earlier in this chapter, you could use the init() method on a servlet to get the parameters needed to connect to the database. You would have to have parameters for the class name as we have shown, the database URL, and probably a user name and password to access the database. With this information you could modify your servlet as follows:

import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
import java.io.*;

public class MyFirstServlet extends HttpServlet
{
    private    Connection    connection = null;
. . .

We have added an import statement to get the JDBC-related classes and we have added a private member variable of type Connection.

Now you could modify the init() method to include the following (exception and error handling has been removed to simplify the view):

String dbURL = getInitParameter( "dbURL" );
String dbUserName = getInitParameter( "dbUserName" );
String dbUserPassword = getInitParameter( "dbUserPassword" );
Class.forName( dbClass ).newInstance();
connection = DriverManager.getConnection( dbURL, dbUserName, dbUserPassword );

Now anywhere in your servlet that you needed access to a database you could use the member variable “connection”. However, there are several problems with this approach. The biggest problem is that not all JDBC connections are thread safe. Remember that, by default, servlets are multi-threaded and that many threads could be executing your service methods simultaneously. This could lead to disastrous results in the database or at least a greatly enhanced possibility that our database would become corrupt.

What if we modified the code so that the connection was not a member variable but instead we created a new one each time we needed it? This would solve our thread problem. Each thread would get its own database connection so there would be no concurrency issues. However, creating a database connection is a fairly expensive operation. Because most Web transactions are short-lived, we would be creating and destroying connections at a fairly high rate. Additionally, what if 1,000 clients requested access to our servlet at the same time? We would quickly overload the database with client connections.

WebLogic 7.0 has two ways of improving this situation drastically: database connection pools and the J2EE DataSource.

Using WebLogic 7.0 Connection Pools

In WebLogic 7.0, a developer can use the JDBC connection pool provided by WebLogic. This pool contains identical connections to a database for use within WebLogic Server. Developers that need a database connection access it from the pool, use it as a normal JDBC Connection, and return it when they are done. This prevents the constant opening and closing of database connections, increasing the speed and scalability of the application.

To use the pool, follow these steps:

  1. Load the pool driver. The pool driver works in the same way that a normal JDBC driver works. The driver name is weblogic.jdbc.pool.Driver. So, where our earlier code loaded the driver the only difference is the name:

    Class.forName("weblogic.jdbc.pool.Driver").newInstance();
    
  2. Create a connection using the URL for the driver. The URL of the pool driver is jdbc:weblogic:pool. Use it as we did above. A difference is that WebLogic JDBC pools are named so you will need to append the name of your pool onto the previous URL:

    connection = DriverManager.getConnection( "jdbc:weblogic:pool:myServletPool",
                                             dbUserName, dbUserPassword );
    
  3. When you are done with the connection, close it.

Make sure that you call the close() method on the Connection object when you finish with your JDBC calls, so that the connection is returned to the pool:

connection.close();

It is important to note that the WebLogic 7.0 connection pool is not a J2EE standard. You should not use it where portability to other application servers is a concern.

Using a DataSource for Database Connections

A DataSource is a J2EE server-side class that refers to a connection pool. A DataSource is slightly harder to configure and access than a WebLogic pool, but it is part of the J2EE standard and should be used when J2EE portability is important.

Configuring a DataSource is beyond the scope of this chapter. However, to use the DataSource you have to do the following:

  1. Look up the DataSource in the JNDI tree:

    Context ctx = new InitialContext(ht);
    // Look up the DataSource object
    javax.sql.DataSource ds =
     (javax.sql.DataSource) ctx.lookup ("myServletDataSource");
    
  2. Get a JDBC connection from the DataSource:

    java.sql.Connection connection = ds.getConnection();
    
  3. Use the connection as normal.

Servlet Implementation Limitations

Servlets can manage almost all client interaction. However, there are issues that are not easily addressed with servlets. The biggest problem with servlets and traditional HTML-based interaction is that embedding HTML within Java code is cumbersome and error prone. A cleaner design would allow for the separation of the HTML code from the Java code. Fortunately, such a technology exists in a J2EE standard that is closely related to servlets called JavaServer Pages. JavaServer Pages are meant to be primarily HTML with Java language snippets as needed. They address the separation of presentation from business logic. See Chapter 18, “JavaServer Pages and Tag Libraries” for more information.

Summary

Servlets are an incredible advance in the realm of Web server-side programming. They allow a developer to fully interact with the HTML data stream for both inbound (from a client such as a browser) and outbound (to be rendered by a browser). Their combination of simplicity and consistency allows fast implementation of server-based service providers for browsers and other Web-based clients. When combined with their close relative JavaServer Pages, they make for a formidable tool in the Web developer’s toolbox.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset