Channels ▼
RSS

.NET

Java Q&A

Source Code Accompanies This Article. Download It Now.


Dec98: Java Q&A

David is a Java mentor working for CrossLogic Corp., an object technology consulting firm that specializes in distributed computing. He can be contacted at wpitt@ crosslogic.com.


Java Servlets are web server plug-ins that allow dynamic web content to be created using Java on the server side. When an HTTP URL is issued, a Servlet-aware web server identifies and invokes the Servlet class, which executes on the server -- not in the client's process space. In other words, Java class files are not sent to the client machine; instead, Servlets are started in separate threads on the server. This is one benefit Servlets have over CGI, which starts an operating-system process for each client request. Moreover, all Servlets run under a single Java Virtual Machine (JVM), allowing an object state to be shared among multiple client requests; see Figure 1.

The Servlet interface requires the implementation of methods that are invoked at different times during the life cycle of a Servlet instance; see Listing One (located at the end of this article). The init() method is called the first time a Servlet class is invoked by a client when the bytecodes are moved into the VM. Operations such as database or resource connection/initialization are typically done at this point. Each client request results in a new instance of the Servlet class running in its own thread, and the invocation of the service() method. The service() method is where Servlet behavior is implemented. This instance and its thread live as long as the method is on the process stack. When the method returns, the thread is stopped and the instance garbage collected. Therefore, you are responsible for creating and synchronizing thread behavior against shared resources or objects. Servlets provide an opportunity for you to perform cleanup and housekeeping chores via the destroy() method. This method is invoked at the discretion of the web server.

In this article, I'll discuss two approaches to using Servlet technology to create server-based Java applications with the ability to interact with web-based clients using HTML or serialized Java objects.

You invoke Servlets by defining a URL that contains the Servlet's class name. A naming convention is applied to notify the web browser of the Servlet class name and path: After the address, the text pattern "Servlet" appears, along with a fully qualified Servlet class name, such as:

http://127.0.0.1:8080/servlet/ simple.SimpleServlet

Of course, the location to which the URL points must be a Servlet-aware web server.

Servlet behavior is implemented in the service() method. Information is passed and communicated to and from a client invoking a Servlet by arguments defined in this method. These arguments are of types ServletRequest and ServletResponse. Instances of these types are used to push and pull information from a client's web page.

Responding to a client page using a ServletResponse object is accomplished by requesting an output stream and putting MIME type or text content onto it. Likewise, information is obtained from a client page by obtaining an input stream from the request object and pulling information using the stream protocol.

When the Servlet is loaded and instantiated, the init() method is exercised. Resource allocation (such as connecting to a database) can be performed at this point. Subsequent calls to the Servlet will exercise the service() method only.

Before the JVM on the server shuts down, the destroy() method is called, allowing housekeeping chores to be performed.

"Hello World" Servlet Using the JSDK

The Java Server Development Kit (JSDK), freely available from JavaSoft (http://www.sunsoft.com/), provides Servlet support for web servers such as Microsoft's IIS, Netscape, and Apache. Additionally, the JSDK includes an HTTP web server written in Java and invoked as a Java application. This sample server lets you test Servlets from your machine without a web server.

Servlets must implement the Servlet interface. The JSDK provides a Servlet abstraction by supplying a hierarchy of Servlet classes (Figure 2), which implement general Servlet behavior. Specific Servlet behavior can be implemented by extending this hierarchy.

GenericServlet implements basic init() and destroy() behavior requiring subclasses to implement only the service() method. These methods can be overridden if required. More specifically, the HTTPServlet class implements a protocol to process HTTP post and get commands.

A Servlet that simply displays "Hello World" in a client's browser space can be created by extending GenericServlet and overriding the service() method. A client's browser is accessed by obtaining an output stream from the Response object passed in as an argument. The specific instance of the Servlet is shared by all HTTP clients performing the request. Each request does not result in the Servlet class being run on an independent JVM, in a separate operation system process as with a CGI request. Instead, each request is given a more efficient thread; see Listing Two.

Invoking a Servlet

The JSDK implements an HTTPServer class that you can use to test Servlets from your workstation. Assuming a JVM is installed, and your classpath set, you start the the server using: Java HTTPServer -v -p 8080. Once invoked, the SimpleServlet class is executed from a browser using the URL http://127.0.0.1:8080/ servlet/simple.SimpleServlet.

Responding with Dynamically Generated HTML

Since not all browsers reliably handle Java applets, Java on the client can be removed from the equation by having Servlets respond to clients by generating dynamic HTML. Having an HTTP connection to the client machine accommodates the generation and displaying of HTML from a Servlet.

Responding to HTTP post and get requests from a Servlet is accomplished by subclassing from HTTPServlet, supplied with the JSDK. HTTP get requests are intercepted in a Servlet by overriding the doGet() method. Arguments to the method are the same as the service() method; they are of type ServletRequest and ServletResponse. A response of HTML text is communicated to the web server by setting the Servlet response object's setContentType() attribute to text/html; after that, it is simply a matter of putting valid HTML tags/text onto the output stream (Listing Three).

Retrieving Objects from a Servlet

Another interesting way to apply Servlets involves streaming objects asynchronously from a Servlet to a client-side applet. This is accomplished using the serializing behavior built into the JDK.

An applet can communicate with a Servlet by using the networking programming support provided by the language. An HTTP connection is accomplished in Java using the URL object to invoke a Servlet (see Listing Four). Instead of putting text or HTML on the Response objects stream passed into the service method (Listing Five), Java objects are created and deflated (Listing Six) into a byte array using serialization. The applet in turn inflates the byte array into objects (Listing Seven).

It is not reasonable to assume that a client will require all available objects from a Servlet. In most cases, the applet will need to communicate some kind of query information to the Servlet. In the same fashion that objects are serialized and sent to an applet, the applet can serialize objects containing query information and append them to the HTTP stream sent to a Servlet instance. The Servlet can then inflate these objects and obtain query information.

Conclusion

Servlets let you implement browser-based applications to exploit Internet connectivity. Java's platform-independent thread-safe programming makes it an excellent language for server-side application development. Although the examples I've presented are simplistic, they should provide a starting point in creating interactive Internet applications.

The source files that implement the Servlets described here are available electronically (see "Resource Center," page 3). The Servlets can be accessed using the example HTTPServer provided with the JSDK or copied to a Servlet-enabled web server. The HelloWorld Servlet displays "Hello World" to an accessing browser. EmployeeHTMLTableServlet generates an HTML table and displays it in a web browser. The third Servlet communicates with SerializingEmployeeApplet by serializing objects and streaming to a client browser using an HTTP get command.

DDJ

Listing One

public abstract interface Servlet {
public abstract void destroy();
public abstract javax.servlet.ServletConfig getServletConfig();
public abstract java.lang.String getServletInfo();
public abstract void init(javax.servlet.ServletConfig arg1) 
                                throws javax.servlet.ServletException;
public abstract void service(javax.servlet.ServletRequest arg1,
               javax.servlet.ServletResponse arg2) 
                   throws javax.servlet.ServletException, java.io.IOException;
}

Back to Article

Listing Two

package simple;import java.io.*;
import javax.servlet.*;
public class HelloWorldServlet extends GenericServlet 
{
    public void service( javax.servlet.ServletRequest req,
                                      javax.servlet.ServletResponse res){
    try {
    PrintStream out = new PrintStream( 
    res.getOutputStream());
    out.println("Hello World");}
    catch( java.io.IOException e) {System.out.println(e); }
   }            
}       

Back to Article

Listing Three

/* doGet method is called when an HTML form accesses this servlet using GETmethod where all information is encoded in QUERY_STRING environment variable.
*/      
public synchronized void 
doGet(HttpServletRequest httpServletRequest, 
                                HttpServletResponse httpServletResponse)
throws IOException
  {
    String  jobValue = null, 
    deptValue = null;
    // We will be returning an HTML page
    httpServletResponse.setContentType("text/html");
    // Get the output stream        
    ServletOutputStream servletOutputStream = 
                httpServletResponse.getOutputStream();
    //  Start writing the HTML output       
    htmlHeader(servletOutputStream);
    // Process the arguments
    processArguments(httpServletRequest, servletOutputStream);
    // Get Vector of Employee Objects
    Vector aVector =  employeeObjects();
    // Write Employee Objects to an HTML table
    htmlResultTable(aCollection, servletOutputStream);
    // Write ending HTML
    htmlTrailer(servletOutputStream);
    servletOutputStream.close();
}

Back to Article

Listing Four

/* Retrieve Employees from Servlet. * @return Vector
 */
public Vector getEmployeesFromServlet() {
    URL url = null;
    try{
        //  Create the URL
       String urlStr = "http://127.0.0.1:8080/servlet/proof.
                                        servlet.SerializeEmployeesServlet";
        url = new URL( urlStr + "?");   
        }   catch( MalformedURLException e) {
            System.out.println(" URL: " + e.toString());
            e.printStackTrace();
            return null;
            }
    // Open the stream -- this starts the service() method in the servlet
    InputStream inStream = null;
    try{
        inStream = url.openStream();
    }   catch( IOException e){
        System.out.println("EmpolyeeApplet Exception: " + e.toString());
        e.printStackTrace();
        return null;
        }
    // Get Vector of Employees...
    Vector employees = null;    
    // Inflage Vector of Employee Objects
    employees = 
            (Vector) inflate( inStream);
        return employees;
}

Back to Article

Listing Five

/* Create a Vector of Employees, deflate and stream back to applet */   public void service(HttpServletRequest req, HttpServletResponse res) 
                                      throws IOException, ServletException
{
    // Create the output stream for communicating with the Applet   
    FilterOutputStream objOut = 
                          new FilterOutputStream( res.getOutputStream());
    byte[] errorDeflatedExam = null;
    
    context = getServletContext();
    if (context != null) {
        context.log("LOG:ReqInfoServlet:service START");
    }   
    // Process arguments sent on the URL request
    processURLArguments(req);
    // Get a deflated Employee Object
    byte[] aDeflatedVector = (byte[]) buildDeflatedEmployees(employees);
    //      Write it to the applet      
    objOut.write(aDeflatedVector);
    objOut.close();
    context.log("LOG:EmployeeServlet:service  Employees written");
    context.log("LOG:ExamServlet:service END");
}

Back to Article

Listing Six

/* Turn Vector into a byte array. * @return java.io.ObjectOutputStream
 * @param anExam COM.cl.onlineExam.domain.Exam
 */
private byte[] buildDeflatedEmployees(Vector aVector) {
    //  Deflate the object to an output stream
    ObjectOutputStream objOut = null;
    ByteArrayOutputStream bOut = null;
    try {
        bOut = new ByteArrayOutputStream();
        objOut = new ObjectOutputStream(bOut);
        objOut.writeObject(employees);
        objOut.close();
    } catch (java.io.IOException e) {
        e.printStackTrace();
        return null;
        }       
    return bOut.toByteArray();
}

Back to Article

Listing Seven

/* Inflate input stream */  Object inflate( InputStream in){
    Object obj = null;
    try{
        while( in.available() == 0)
        }   catch( IOException e){
            System.out.println("Error in debug code: " + e.getMessage());
        }
        try{
            ObjectInputStream objIn = new ObjectInputStream( in);
            obj = objIn.readObject();
        }   catch( IOException e){
            responseTextArea.setText("Error inflating 
                                     object: " + e + " " + e.getMessage());
        }   catch( ClassNotFoundException e){
            responseTextArea.setText("Error finding 
                                      class: " + e.getMessage());
        }
        return obj;
    }

Back to Article

DDJ


Copyright © 1998, Dr. Dobb's Journal

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video