Skip Headers

Oracle Application Server Containers for J2EE User's Guide
10g (9.0.4)

Part Number B10322-01
Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Go to previous page Go to next page

5
Servlet Primer

In Oracle Application Server 10g, OC4J includes a servlet container that is fully compliant with the servlet 2.3 specification. This chapter covers the basics of running servlet applications in the OC4J environment. There is also a brief servlet review, although it is assumed that you are at least somewhat familiar with servlet technology.

There are a few assumptions before you try running the primers. See "Introduction to OC4J".

This chapter includes the following sections:

For detailed information about the Oracle servlet implementation, see the Oracle Application Server Containers for J2EE Servlet Developer's Guide.

A Brief Overview of Servlet Technology

The following sections provide a quick servlet overview:

What Is a Servlet?

In recent years, servlet technology has emerged as a powerful way to extend Web server functionality through dynamic Web pages. A servlet is a Java program that runs in a Web server (as opposed to an applet, which is a Java program that runs in a client browser). Typically, the servlet takes an HTTP request from a browser, generates dynamic content (such as by querying a database), and provides an HTTP response back to the browser. Alternatively, it can be accessed directly from another application component, or send its output to another component. Most servlets generate HTML text, but a servlet might instead generate XML to encapsulate data.

More specifically, a servlet runs in a J2EE application server, such as OC4J. Servlet is one of the main application component types of a J2EE application, along with JavaServer Pages (JSP) and Enterprise JavaBeans (EJB), which are also server-side J2EE component types. These are used in conjunction with client-side components such as applets (part of the Java 2 Standard Edition specification) and application client programs. An application might consist of any number of any of these components.

Using Java servlets allows you to use the standard servlet API for programming convenience, and enables you to employ any of the numerous standard Java and J2EE features and services, including JDBC to access a database, RMI to call remote objects, or JMS to perform asynchronous messaging.

Servlets outperform previous means of generating dynamic HTML. Once a servlet is loaded into memory, it is able to run as a single lightweight thread. The ability to run as a continuous process has led to servlets largely replacing older technologies such as server-side includes and CGI as a means of running code in the server.

Servlet Portability

Because servlets are written in the Java programming language, they are supported on any platform that has a Java virtual machine and has a Web server and J2EE containers. You can use servlets on different platforms without recompiling, and you can package servlets together with associated files such as graphics, sounds, and other data to make a complete Web application. This greatly simplifies application development.

A servlet-based application that was developed to run on any J2EE-compliant application server can be ported to OC4J with little effort.

The Servlet Container

Unlike a Java client program, a servlet has no static main() method. Therefore, a servlet must execute under the control of an external container.

Servlet containers, sometimes referred to as servlet engines, execute and manage servlets. It is the servlet container that calls servlet methods and provides services that the servlet needs when executing. A servlet container is usually written in Java and is either part of a Web server (if the Web server is also written in Java) or otherwise associated with and used by a Web server. OC4J includes a fully standards-compliant servlet container.

The servlet container provides the servlet easy access to properties of the HTTP request, such as its headers and parameters. When a servlet is called or invoked, the Web server passes the HTTP request to the servlet container. The container, in turn, passes the request to the servlet.

Figure 5-1 illustrates the communication path between a client (such as a Web browser), the Web listener in the Web server, the servlet container, a servlet, and a back-end database.

Figure 5-1 Servlet and the Servlet Container

Text description of o_1076.gif follows.

Text description of the illustration o_1076.gif

Request and Response Objects

In Java, an HTTP request is represented by an instance of a class that implements the standard javax.servlet.http.HttpServletRequest interface. Similarly, an instance of a class that implements the javax.servlet.http.HttpServletResponse interface is used for an HTTP response. These interfaces specify methods to be used in processing requests and responses.

A servlet extends one of two standard servlet base classes: javax.servlet.GenericServlet or javax.servlet.http.HttpServlet. Key HttpServlet methods such as doGet(), to process an HTTP GET request, and doPost(), to process an HTTP POST request, take an HttpServletRequest instance and an HttpServletResponse instance as input parameters. The servlet container passes these objects to the servlet and receives the response back from the servlet to pass on to the client or to another server object such as an EJB.

The servlet overrides the access methods implemented in GenericServlet and HttpServlet classes, as appropriate, in order to process the request and return the response as desired. For example, most servlets override the doGet() and doPost() methods (or both) of HttpServlet.

Learning More About Servlets

For a first step in learning more about servlets, see the Oracle Application Server Containers for J2EE Servlet Developer's Guide. This guide tells you what you need to know to develop servlets and Web applications in the OC4J environment.

For complete documentation of the J2EE APIs, including servlets, visit the Sun Microsystems Web site at:

http://java.sun.com/j2ee/docs.html

You can also find a great deal of tutorial information there about servlets as well as other aspects of J2EE application development.

Running a Simple Servlet

A good way to learn about servlets and how to code them is to view a basic servlet example. This section shows you how to create and run a simple "Hello World" servlet.

Create the Hello World Servlet

Here is the Hello World code, showing the basic servlet framework. This servlet just prints "Hi There!" back to the client browser. The numbered comments along the right side correspond to the code notes below.

Save this servlet in a file called HelloWorldServlet.java and compile it.


Note:

Before compiling the servlet, be sure that servlet.jar, supplied with OC4J, is in your classpath. This contains the Sun Microsystems javax.servlet and javax.servlet.http packages.


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

public class HelloWorldServlet extends HttpServlet {               // 2

  public void doGet (HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {                         // 3
    resp.setContentType("text/html");                              // 4

    ServletOutputStream out = resp.getOutputStream();              // 5
    out.println("<html>");                                         // 6
    out.println("<head><title>Hello World</title></head>");
    out.println("<body>");
    out.println("<h1>Hi There!</h1>");
    out.println("</body></html>");
  }
}
Code Notes

  1. You must import at least java.io.*, javax.servlet.*, and javax.servlet.http.* for any servlet you write. Additional packages are needed for SQL operations or to support Oracle JDBC drivers.

  2. The servlet extends the HttpServlet class, which has base implementations of the methods that a servlet uses in processing HTTP requests and responses.

  3. The doGet() method, which services HTTP GET requests, overrides the base implementation in HttpServlet. Like almost all HttpServlet methods, doGet() takes a request object and a response object as parameters. In this example, no methods are called on the request object (req), because this example requires no input data (that is, request data).

  4. The servlet calls the setContentType() method of the response object to set the response content MIME type in the header. Here it is text/html.

  5. The getOutputStream() method of the response object (resp) is called to get an output stream to use in sending the output from the server back to the client. Alternatively, you could call the getWriter() method to get a java.io.PrintWriter object.

  6. The remainder of the servlet consists of output statements with HTML code to write a simple Web page to display "Hi There!" in a Heading 1 (<h1>) format. The Web browser will display this output when it receives the response object from the server.

Deploy the Hello World Servlet

Archive HelloWorldServlet.class into the WAR file for the servlet primer samples, and deploy the WAR file using the Oracle Enterprise Manager deployment wizard. This is all described in "Creating and Deploying the Servlet Primer Samples WAR File".

Run the Hello World Servlet

Assuming you specify a context path of /hello, as described in "Deploy the WAR File", you can run the Hello World servlet with a URL such as the following:

http://host:port/hello/servlet/HelloWorldServlet

The /servlet part of the URL employs an OC4J feature that starts up a servlet, such as HelloWorldServlet in this case, according to its class name. The servlet-webdir attribute in the <orion-web-app> element of the global-web-application.xml file or orion-web.xml file defines this special URL component. Anything following it in the URL is assumed to be a servlet class name, including applicable package information, within the appropriate servlet context. By default in OC4J, the setting for this URL component is "/servlet".


Important:

Invoking a servlet in this way is recommended only for development and testing scenarios. Allowing the invocation of servlets by class name presents a significant security risk; OC4J should not be configured to operate in this mode in a production environment. See the Oracle Application Server Containers for J2EE Servlet Developer's Guide for information.


Automatic Compilation

For easier test development, use the OC4J auto-compile feature. Set development="true" in the <orion-web-app> element of the global-web-application.xml configuration file, as follows:

<orion-web-app ... development="true" ... >
   ...
</orion-web-app>

If development is set to "true", then each time you change the servlet (the .java or .class file) and save it in a particular directory, or change the web.xml file, the OC4J server automatically redeploys (essentially, restarts) the servlet or Web application. A modified .java file is also automatically recompiled upon first access.

The directory is determined by the setting of the source-directory attribute of <orion-web-app>. The default is "WEB-INF/src" if it exists, otherwise "WEB-INF/classes".

Running a Data-Access Servlet

The HelloWorldServlet example shows a minimal servlet with only static output. The power of servlets, however, comes from the ability to retrieve data from a database, generate dynamic content based on the data, and send that content to the client. (Of course, a servlet can also update a database, based upon information passed to it in the HTTP request.)

In this next example, a servlet gets some information from the client (the Web browser), uses this information in constructing a database query, and reports the query results back to the client.

Although there are many ways that a servlet can get information from its client, this example uses a very common method: reading a query string from the HTTP request.


Note:

This example works only if the HR schema has been installed in the Oracle database. This schema is part of the sample Common Schemas set available with the Oracle Database.


Create the HTML Form

First, create an HTML page that acts as the front end for the servlet. This page includes an HTML form through which the end user specifies the query parameters.

Enter or copy the following text into a file and name the file EmpInfo.html.

<html>

<head>
<title>Query the Employees Table</title>
</head>

<body>
<form method=GET ACTION="/hello/servlet/GetEmpInfo">
The query is<br>
SELECT LAST_NAME, EMPLOYEE_ID FROM EMPLOYEES WHERE LAST NAME LIKE ?.<p>

Enter the WHERE clause ? parameter (use % for wildcards).<br>
Example: 'S%':<br>
<input type=text name="queryVal">
<p>
<input type=submit>
</form>

</body>
</html>

Create the GetEmpInfo Servlet

The servlet called by the preceding HTML page constructs a SELECT statement (query), with the end user being prompted for the WHERE clause to complete the SELECT statement. For database access, this example uses JDBC connection, result set, and statement objects. If you are not familiar with JDBC, see the Oracle9i JDBC Developer's Guide and Reference.

This code also assumes default OC4J data source configuration in the data-sources.xml file, as in the following example:

<data-source
        class="com.evermind.sql.DriverManagerDataSource"
        name="OracleDS"
        location="jdbc/OracleCoreDS"
        xa-location="jdbc/xa/OracleXADS"
        ejb-location="jdbc/OracleDS"
        connection-driver="oracle.jdbc.driver.OracleDriver"
        username="hr"
        password="hr"
        url="jdbc:oracle:thin:@localhost:1521:orcl"
        inactivity-timeout="30"
/>


Note:

For the URL, change localhost to an appropriate host name (such as according to the hosts file on UNIX), as applicable. Change orcl to the name of the Oracle database instance, if different.


For introductory information about data sources, see Chapter 4, "Data Sources Primer". For further information, see the Oracle Application Server Containers for J2EE Services Guide.

Here is the code for the servlet. Numbered comments along the right side correspond to the code notes below.

Enter or copy the code into a file called GetEmpInfo.java and compile it.

import javax.servlet.*;
import javax.servlet.http.*;
import javax.naming.*;                                             // 1
import javax.sql.*;                                                // 2
import java.sql.*;
import java.io.*;

public class GetEmpInfo extends HttpServlet {

  DataSource ds = null;
  Connection conn = null;

  public void init() throws ServletException {                     // 3
    try {
      InitialContext ic = new InitialContext();                    // 4
      ds = (DataSource) ic.lookup("jdbc/OracleDS");                // 5
      conn = ds.getConnection();                                   // 6
    }
    catch (SQLException se) {                                      // 7
      throw new ServletException(se);
    }
    catch (NamingException ne) {                                   // 8
      throw new ServletException(ne);
    }
  }

  public void doGet (HttpServletRequest req, HttpServletResponse resp)
                     throws ServletException, IOException {

    String queryVal = req.getParameter("queryVal");                // 9
    String query =                                                 //10
      "select last_name, employee_id from employees " +
      "where last_name like " + queryVal;

    resp.setContentType("text/html");

    PrintWriter out = resp.getWriter();
    out.println("<html>");
    out.println("<head><title>GetEmpInfo</title></head>");
    out.println("<body>");

    try {
      Statement stmt = conn.createStatement();                     //11
      ResultSet rs = stmt.executeQuery(query);                     //12

        out.println("<table border=1 width=50%>");
	  out.println("<tr><th width=75%>Last Name</th><th width=25%>Employee " +
                   "ID</th></tr>");
 
        int count=0;
        while (rs.next()) {                                        //13
         count++;
         out.println("<tr><td>" + rs.getString(1) + "</td><td>" +rs.getInt(2) +
                    "</td></tr>");
       
        }
         out.println("</table>"); 
         out.println("<h3>" + count + " rows retrieved</h3>");
         
      rs.close();                                                  //14
      stmt.close();
}
    catch (SQLException se) {                                      //15
      se.printStackTrace(out);
    }

    out.println("</body></html>");
  }

  public void destroy() {                                          //16
    try {
      conn.close();
    }
    catch (SQLException se) {                                      //15
      se.printStackTrace();
    }
  }
}
Code Notes

  1. Import javax.naming.* to support the JNDI API.

  2. Import JDBC standard interfaces in java.sql and extended interfaces in javax.sql (for support of data sources and connection pooling).

  3. Override the HttpServlet init() method.

  4. Get a JNDI initial context. For more information about using JNDI with OC4J, see the Oracle Application Server Containers for J2EE Services Guide.

  5. Look up the data source with the JNDI name jdbc/OracleDS, which is configured by default in the data-sources.xml file.

  6. Use the data source to get a connection to the database.

  7. Catch any SQL exception from the connection attempt, and throw it as a ServletException instance.

  8. Catch any JNDI naming exception and throw it as a ServletException instance.

  9. Get the parameter that was passed in the request from the HTML form. This is the WHERE clause for the query.

  10. Construct a SQL query using the WHERE clause specified by the user.

  11. Create a JDBC statement object.

  12. Execute the query, with the results going into a JDBC result set object.

  13. Loop through the rows of the result set. Use the result set getString() and getInt() methods to get the particular data values and then output the values to the browser.

  14. Close the result set and statement.

  15. Catch any SQL exceptions from the query, processing of the result set, or closing of the statement object or connection object (two locations). Print the stack trace.

  16. The destroy() method closes the database connection.

Deploy GetEmpInfo and the HTML Page

Archive EmpInfo.html and GetEmpInfo.class into the WAR file for the servlet primer samples, and deploy the WAR file using the Oracle Enterprise Manager deployment wizard. This is all described in "Creating and Deploying the Servlet Primer Samples WAR File".

Run GetEmpInfo

Assuming you specify a context path of /hello, as described in "Deploy the WAR File", you can access the front-end HTML page for the GetEmpInfo servlet with a URL such as the following:

http://host:port/hello/EmpInfo.html

When your browser invokes this page, you should see output like the following:

Figure 5-2 Query Output

Text description of gsimg1.gif follows.

Text description of the illustration gsimg1.gif

Pressing Submit Query calls the GetEmpInfo servlet. If you first enter 'S%' (for example) in the form for the WHERE clause, you will get the following results:

Figure 5-3 Submit Query Results

Text description of gsimg3.gif follows.

Text description of the illustration gsimg3.gif

Creating and Deploying the Servlet Primer Samples WAR File

Two examples have been covered in this chapter: a simple Hello World servlet and a servlet that accesses a database. For simplicity, we suggest that you package and deploy them in a single WAR file. This section shows the required files for the examples and how you can package and deploy them.


Note:

Web components, such as JSP pages and servlets, are archived in WAR files. An application consisting of only Web components can be deployed as a WAR file directly, as shown here for simplicity; however, the primary J2EE deployment vehicle is an EAR file. An EAR file can include a WAR file as well as other types of archive files for other types of components, such as EJBs. (For the sample applications here, you also have the option of placing the WAR file within an EAR file, then deploying the EAR file.) See "Creating and Deploying the JSP Primer Samples EAR File" for an example of an EAR file.


For additional information about building and deploying servlet applications, refer to the Oracle Application Server Containers for J2EE Servlet Developer's Guide.

WAR File Structure

Here is the structure of the WAR file for the examples in this chapter:

EmpInfo.html
WEB-INF/
   classes/
      HelloWorldServlet.class
      GetEmpInfo.class

If you use an IDE for your development, the IDE can usually create the WAR file for you. Otherwise, you can create it manually using the Java JAR utility.

No special web.xml entries are required for the examples in this chapter.

Deploy the WAR File

Use Oracle Enterprise Manager, the Application Server Control, to deploy the examples. Select the Applications page. Click the Deploy WAR file button and follow the directions for the deployment wizard.

The following figure shows the key portion of the Oracle Enterprise Manager Deploy Web Application Page, which is the page for deploying a WAR file.

Figure 5-4 Deploy the Web Application

Text description of oemdepwa.gif follows.

Text description of the illustration oemdepwa.gif

Click the Browse button to select the WAR file to deploy. Then specify the application name along with a URL mapping for the application. This specified mapping will become the context path portion of the URLs to run the examples in this chapter. In preceding sections showing how to run the examples, we assume that /hello is the URL mapping.


Go to previous page Go to next page
Oracle
Copyright © 2002, 2003 Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index