Java servlets are classes that implement the Servlet interface and can be invoked by a web page that defines a URL containing the class name of a servlet. David discusses two ways you can use servlet technology to create server-based Java applications with the ability to interact with web-based clients using HTML or serialized Java objects.
December 01, 1998
URL:http://www.drdobbs.com/windows/java-qa/184410755
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.
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.
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.
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).
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.
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
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; }
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); } } }
/* 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(); }
/* 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; }
/* 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"); }
/* 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(); }
/* 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; }
DDJ
Dr. Dobb's Journal December 1998
Dr. Dobb's Journal December 1998
Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.