SCOUG Logo


Next Meeting: TBD
Meeting Directions


Be a Member
Join SCOUG

Navigation:


Help with Searching

20 Most Recent Documents
Search Archives
Index by date, title, author, category.


Features:

Mr. Know-It-All
Ink
Download!








SCOUG:

Home

Email Lists

SIGs (Internet, General Interest, Programming, Network, more..)

Online Chats

Business

Past Presentations

Credits

Submissions

Contact SCOUG

Copyright SCOUG



warp expowest
Pictures from Sept. 1999


The views expressed in articles on this site are those of their authors.

warptech
SCOUG was there!


Copyright 1998-2022, Southern California OS/2 User Group. ALL RIGHTS RESERVED.

SCOUG, Warp Expo West, and Warpfest are trademarks of the Southern California OS/2 User Group. OS/2, Workplace Shell, and IBM are registered trademarks of International Business Machines Corporation. All other trademarks remain the property of their respective owners.

The Southern California OS/2 User Group
P.O. Box 26904
Santa Ana, CA 92799-6904, USA

SCOUG OS/2 For You - May 1998


Programming for the Net: Serverside Java

by Terry Warren

Introduction

In previous articles we have looked at client-webserver interaction based on the CGI model. The client (usually a browser) transmits an HTTP request which optionally includes a set of parameters from the web page. The webserver starts a process, passes the parameters to the process and then sends the output from the process back to the client.

The CGI program which processes the request can be developed using a number of different "languages" such as C, PERL or even REXX. While all of these work reasonably well, there are several limitations:

  1. the overhead at the webserver in starting up a separate process for each request can be significant, especially when high-volume transaction loads exist.
  2. if the interaction requires multiple transactions, it can be problematic to retain persistent data (usually this is accomplished by passing "hidden" variables back and forth which not only increases the transmission volume but is also not secure).
  3. to a certain extent programs developed in these languages tend to be platform specific. This is especially true with C and less true with scripting languages such as PERL.

In this article, we will look at a new alternative to developing CGI programs (or webserver processes in general) using Java and see how this approach eliminates the limitations listed above.

Java Servlets - What Are They?

Java server request processing is supported by extension packages to the JDK. Currently they are available as separate classes but will be included in JDK 1.2 and beyond releases. The packages are:

  • javax.servlet (generic transaction processing)
  • javax.servlet.http (http transaction processing and subject of this article)

The http package is designed to encapsulate the properties and requirements of processing http requests. For example, the class supplies methods for getting request headers, creating response headers and writing the response data.

In general, one servlet class will be written for each different process (as with CGI programs) and will be an extension of HttpServlet. The methods that commonly need to be coded are:

init(...) - performs onetime initialization doGet(...) - if the GET request method is to be supported doPost(...)- if the POST request method is to be supported doPut(...) - if the PUT request method is to be supported

The parameters for each of the doXXX methods (details later on) are the same:

  • HttpServletRequest object - for obtaining request information
  • HttpServletResponse object - for building and transmitting the response

What makes this design powerful is how it is implemented. When a servlet class is first referenced in an http request (or if configured to be autostarted), the webserver creates an instance of the class and executes its init() method, passing any configuration parameters defined for the servlet. This allows the class to perform global initialization and create class variables that are available to all requests. The doXXX() method is then invoked to process the request, based on the request type.

After processing the first request, the class object remains active. As additional requests for the same servlet are received, a new request and response pair of objects is created and the appropriate doXXX() method of the existing class object is invoked (normally in a separate thread).

A summary of the benefits of this approach is:

  • There is minimal startup overhead to process the request (after the first)
  • Parallel request processing is automatically threaded
  • Global (or persistent) data is easy to access/modify
  • You get to write in Java

But How Do I Actually Write a Servlet?

Most of the work is done in the doXXX() method(s). As mentioned above, each receives a request and response object. The request object contains methods for obtaining the http headers, CGI parameters, and so forth; the response object provides for writing the output stream to the client. This work is essentially the same as is done in a traditional CGI program but is usually much easier to do using the Java framework.

For example, if a browser form (remember those from article 1?) sends fields for "firstname", "lastname" (using the POST method), the following simple servlet will send back a "welcome" response:

public class MyServlet extends HttpServlet { ... // at startup, perform initialization for class public void init(ServletConfig config) throws ServletException { super.init(config); } // process POST request public void doPost(HttpServletRequest req, HttpServlerResponse resp) throws ServletException, IOException { ServletOutputStream out = resp.getOutputStream(); //get outputstream resp.setContentType("text/html"); //indicate output type out.println("<HTML>"); String firstName = req.getParameter("firstname"); //firstname String lastName = req.getParameter("lastname"); //lastname out.println("<h2>Welcome " + firstName + " " + lastName + "</h2>"); out.println("</HTML>"); out.close(); } }

The next code, if inserted in the doXXXX method will print out the http headers and CGI parameters from the request:

Enumeration hdrs = req.getHeaderNames(); //gets all headers while (hdrs.hasMoreElements()) { String hdrname = hdrs.nextElement(); //next header name out.println("<br>" + hdrname + ": " + req.getHeader(hdrname)); } Enumeration parms = req.getParameterNames(); //get all param names while (parms.hasMoreElements()) { //show each parm String pname = parms.nextElement(); out.println("<br>" + pname + " = " + req.getParameter(pname)); }

Can I Have a Cookie Now?

A lot of existing webserver applications depend on passing Cookie information to/from client. If these types of applications are being replaced by servlets, it might still be necessary to preserve the Cookie processing. The serlvet package contains a Cookie class for this purpose. A Cookie can be created using the constructor and set methods for defining its properties. For example:

Cookie myCookie = new Cookie("mine", "valueofmine"); myCookie.setPath("http://www.scoug.com"); would create a new Cookie for any requests going to scoug.com. This can be attached to the http response by: resp.addCookie(myCookie);

The request object provides a method to obtain all the Cookies in the request. The following sample method would return a Cookie with a specified name:

public Cookie findCookie(String name, HttpServletRequest req) { Cookie cookieArray[] = req.getCookies(); for (int i=0; i<cookieArray.length; i++) { if (cookieArray[i].getName().equals(name)) //compare name return cookieArray[i]; } } return null; }

I Want to Persist

It was mentioned above (more than once) that the servlet model provided a way of retaining a client's data between requests. This is implemented through a set of classes in the servlet package which include HttpSession, HttpSessionContext, HttpSessionBindingEvent and HttpSessionBindingListener. Unfortunately, these classes are not yet supported in most of the webservers, although the Sun Java WebServer (written entirely in Java) does provide SessionID parameter for each client.

A simple alternative is to use a Cookie to contain a "sessionid" value and to then use this value as a lookup in a hashtable (or some other collection class) to reference the client data. The hashtable would be defined at the class level and would be accessible by each request. The object in the table would normally be a custom class that defines properties and methods for the client.

For example:

//define a special class to handle the client data, EG class clientData { String id; String firstname, lastname; String address; ... public ClientData(String s) { id = s; } public String getId() { return id; } public void setFirstname(String s) { firstname = s; } public String getFirstname() { return firstname; } ... } //in the global area of servlet class definition: Hashtable clients = new Hashtable(); //persistent data // at the beginning of the doXXXX method, we would look for the // sessionid Cookie and use its value as the lookup ClientData cd; Cookie sessCookie = findCookie("sessionid", req); if (sessCookie == null) { //if not found String newId = createUniqueId(); //method to get a new id sessCookie = new Cookie("sessionid", newId); resp.addCookie(sessCookie); cd = new ClientData(newId); clients.put(newId, cd); //add client to Vector } else { cd = (ClientData) clients.get(sessCookie.getValue()); //if cookie, get the clientdata } // in the doXXX method, can then reference specific client data as needed ... String name = cd.getFirstName() or cd.setFirstName(name);

This technique is quite powerful since the persistent data can be more than just data, such as actual class objects.

How To Use Servlets

To use them, a webserver must be enabled with appropriate Java runtime and servlet configuration capabilities. Most of the commercially available webserver products (eg Lotus Domino, Netscape, Apache, Sun Java Webserver) contain this support to some degree. There are also a number of standalone packages (servlet runners) which allow servlets to be tested without a webserver environment.

When a servlet class file has been created, it needs to be moved into the webserver's servlet directory (a special directory for servlets). For performance improvements, usually the servlet can also be configured to the webserver. This involves attaching a name to it, indicating that it is to be automatically started when the webserver starts (or not), and/or specifying parameters that are to be passed to it when it does start.

The servlet can be invoked from the client in one of several ways:

  1. Directly from the location (address) given to the browser, e.g.,
    http://www.myWebServer.com/servlet/MyServlet
    (this could also be specified in a FORM Action tag)
  2. Embedded in HTML - this is done using the <servlet>...</servlet> tags, similar to how an applet is invoked via <applet> tag. The differences for servlets are:
    • the servlet executes on the webserver (so Java support does not need to be on the client)
    • the HTML file in this case must actually be named as .shtml rather than .html EG <servlet name=serv1 code=MyServlet.class> <... request parameters ...> </servlet>

The servlet's output will replace the tags in the transmitted response.

Summary

In this article, we have seen how to implement Java webserver processes using the javax.servlet.http extension package and reviewed some of the benefits which arise from using this approach. The primary advantage is that because the processes are coded in Java, you only need to learn the process environment itself (ie, http) to be able to create the servlet code.


The Southern California OS/2 User Group
P.O. Box 26904
Santa Ana, CA 92799-6904, USA

Copyright 1998 the Southern California OS/2 User Group. ALL RIGHTS RESERVED.

SCOUG is a trademark of the Southern California OS/2 User Group.
OS/2, Workplace Shell, and IBM are registered trademarks of International Business Machines Corporation.
All other trademarks remain the property of their respective owners.