Sun Java Solaris Communities My SDN Account
 
Article

JavaServer Technologies, Part I

 
 

Articles Index


Up until now, the Java story has largely been a client-side story. That's about to change. Now web servers can be extended through Java power just like web browser clients.
 
In the context of client-server software solutions--including the serving and browsing of Internet web pages--Java applets have enabled client browsers to extend their behavior by downloading compiled code from network servers. Applets have changed the nature and meaning of distributed computing. Applets have opened new worlds by enabling the convenient distribution of compiled code from a central server.
 
There's no reason that servers can't take advantage of Java in the same way that desktop applications have been able to take advantage of Java. To this end, JavaSoft has introduced server technology that is written in 100% Pure Java and that is capable of being extended dynamically by loading compiled Java code known as a servlet. While applets provide a way of dynamically extended the functionality of client-side browsers, servlets let you dynamically extend the functionality of network servers.
 
At JavaOne, David Brownell encouraged programmers to think of servlets as server-side components. Servlets are to servers what applets are to browsers. Servlet code can be downloaded into a running server to extend its behavior in order to provide new, or temporary, services to network clients.
 
Hello, CGI World
At the most simple level, JavaServers can be used to replace standard web servers such as Apache. Since JavaServers can handle CGI scripts, you can use existing Perl code, shell scripts, or compiled C programs, and do HTML forms processing the way you always have.
 

Topic: 'examples'
File: examples.txt
Attributes:


'G:/cool1-opt/JavaServerBeta/servlets' browseDirectory.
(ListingManager new
    directory: 'G:/cool1-opt/JavaServerBeta\servlets';
    addFile: 'TestJdcSurvey01.html';
    addFile: 'JdcSurvey01.java';
    yourself;
    open).

Cmd execute: 'C:\Program Files\PLUS!\Microsoft Internet\IEXPLORE.EXE ',
    'G:\cool1-opt\JavaServerBeta\servlets\TestJdcSurvey01.html'.

'G:/cool1-opt/JavaServerBeta\servlets' change: $/ to: $\
 'G:\cool1-opt\JavaServerBeta\servlets'

--> There are two sides to form processing: specifying the input fields and widgets to be presented to the users in an HTML file, and processing the fields of data that have been filled in by the user once the submit button for the form has been pressed. First consider a form that looks like Figure 01.
 


Figure 01. Full Size
 

Writing the CGI code to process this code could be quite complex. However writing a Java servlet class to handle the task is straightforward.
 
First, look at the HTML code used to present the form to the user:
 
<html>
<head><title>JDC Survey Number 1</title></head>
<body>
<form action=http://cool1:8080/servlet/JdcSurvey01
                                     method=POST>
<input type=hidden name=survey value=Survey01Results>
<BR>
<BR>How Many Employees in your Company?<BR>
<BR>
1-100<input type=radio name=employee value=1-100>
<BR>
100-200<input type=radio name=employee value=100-200>
<BR>
200-300<input type=radio name=employee value=200-300>
<BR>
300-400<input type=radio name=employee value=300-400>
<BR>
500-more<input type=radio name=employee value=500-more>
<BR>
<BR>General Comments?<BR>
<BR>
<input type=text name=comment>
<BR>
<BR>What IDEs do you use?<BR>
<BR>
JavaWorkShop<input type=checkbox name=ide value=
               JavaWorkShop> <BR>
J++<input type=checkbox name=ide value=J++>
<BR>
Cafe'<input type=checkbox name=ide value=Cafe'>
<BR>
<BR><input type=submit><input type=reset></form>

</body></html>


File: TestJdcSurvey01.html


This code file should be placed in the servlets directory, immediately below the root directory where you installed your JavaServer. The form specifies three basic questions to be answered by users. First, the question "How Many Employees in your Company?" offers a set of five radio buttons for potential responses.
    <BR>How Many Employees in your Company?<BR>
    <BR>
    1-100<input type=radio name=employee value=1-100>
    <BR>
    100-200<input type=radio name=employee value=100-200>
    <BR>
    200-300<input type=radio name=employee value=200-300>
    <BR>
    300-400<input type=radio name=employee value=300-400>
    <BR>
    500-more<input type=radio name=employee value=500-more>

Second, the question "General Comments?" provides a single text input field for the users to type in a general comment.
    <BR>General Comments?<BR>
    <BR>
    <input type=text name=comment>
Third, the question "What IDEs do you use?" provides a set of three check boxes. Unlike the radio buttons, these are not mutually exclusive choices as the users may use all three products: Java WorkShop, J++, and Cafe.
    <BR>What IDEs do you use?<BR>
    <BR>
    JavaWorkShop<input type=checkbox name=ide value=
        JavaWorkShop> 
        <BR>
    J++<input type=checkbox name=ide value=J++>
    <BR>
    Cafe'<input type=checkbox name=ide value=Cafe'>

Finally a submit button is provided to cause the form to be submitted and processed when the user has finished answering questions. A reset button appears next to the submit button in case the user wants to reset all fields to the original default values.
    <BR><input type=submit><input type=reset></form>
Once you press the submit button, the data in the form is passed as an argument to the servlet specified in the form tag at the top of the HTML file:
 
    <form action=http://cool1:8080/servlet/
                          JdcSurvey01 method=POST>
This code is very similar to the way in which you would specify that the data in the HTML form was to be processed by a CGI script (whether Perl, shell, or compiled C program).
 
After submitting the form shown in Figure 01, the text in file /tmp/Survey01Results.txt on host cool1 should look like this:
 
<BEGIN>
ide: JavaWorkShop
survey: Survey01Results
employee: 500-more
comment: Great Stuff!
<END>

File: /tmp/Survey01Results.txt


 


After submitting the form, the JavaServer will display a new web page based on the output written to the response argument passed to the service method. In this case a thank you message is displayed.
 


Figure 02. Full Size
 

So Long, CGI
The big difference you will notice, if you are accustomed to CGI script programming, is how much simpler it is to write a servlet class to process the data, than it is to write a comparable CGI script.
 
Here's the code required to process the form once submitted from the page described by the TestJdcSurvey01.html file.
import java.io.*;
import java.servlet.*;
import java.servlet.http.*;
import sun.server.http.*;
import sun.misc.*;
import java.util.*;


public class JdcSurvey01 extends HttpServlet
{
    private String _baseDir;

  /**
  * Initialize the Servlet and set the html pages. Also
  * start the cached cookie expires thread.
  * @param stub Arguments passed by the Servlet loader
  * @return void
  */
    public void init (
      ServletConfig config) throws ServletException
    {
       super.init(config);
       _baseDir = config.getInitParameter ("baseDir");
    }

    /**
     * Write survey results to output file.
     * @param request The Servlet request.
     * @param response The Servlet response.
     * @return void.
     */
    public void service (HttpServletRequest request, 
                 HttpServletResponse response) throws 
                    ServletException, IOException
    {
      PrintWriter printWriter = null;
      FileWriter results = null;
      Enumeration values = request.getParameterNames();
      PrintStream out = new PrintStream 
                         (response.getOutputStream());
      String surveyName =
         request.getParameter ("survey");
      String cookieHeader =
         request.getHeader ("Cookie");

       response.setContentType ("text/html");
        try
        {
         results = 
           new FileWriter (_baseDir + System.getProperty
            ("file.separator") + surveyName + ".txt", true);
            printWriter = new PrintWriter (results);
            printWriter.println ("<BEGIN>");
            while ( values.hasMoreElements() )
            {
                String name, value;
                name = (String)values.nextElement();
                value = request.getParameter (name);
                if ( name.compareTo ("submit") != 0 )
                {
                  printWriter.println (
                             name + ": " + value);
                }
            }
           printWriter.println ("<END>");
           out.println ("Thank-You for participating");
        }
        catch (IOException e)
        {
            e.printStackTrace();
            out.println (
              "A problem occured while recording your 
                 answers. Please try again.");
        }
        try
        {
            if ( results != null )
            {
                results.close();
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        out.close();
        response.getOutputStream().close();
    }
}

File: JdcSurvey01.java




This servlet source file and the compiled servlet class should also be placed in the servlets directory immediately below the root directory where you installed your JavaServer. Before clients can make use of the extended server functionality added by the JdcSurvey01 servlet class, you will also have to install the servlet using the JavaServer administration applet.
 


Serving up Servlets
Topic path:  | Root-C:\usr\topic\
             | Work 1997
             | Week 97/04/21  (16)
             | JavaServer
             | java-server-jdc-article.html
             | Scratch 01


Directory path: C:\usr\topic\Work1997\Wk970421\JavaSrvr\jvsrvrjd


Evaluate the following code to clone
the current TopicManager on the
selected topic

    TopicManager new
     directory: 'C:\usr\topic\Work1997\Wk970421\JavaSrvr\jvsrvrjd';
     zipPrefix: 'jvs';
     windowTitle: 'Topic: java-server-jdc-article.html';
     initialSize: (452 @ 278 rightBottom: 1210 @ 609);
     autoClose: false;
     open.
Topic: 'Scratch 01'
File: Scrtch01.txt
Attributes:

--> A quick code walkthrough should clarify the way in which the form is processed by the service method of the JdcSurvey01 class.
 
First, two different output streams are opened for writing text, one to give feedback to the users, and the other to record the results of the survey.
 
    public void service (HttpServletRequest request, 
                  HttpServletResponse response) throws 
                    ServletException, IOException
    {
        PrintWriter printWriter = null;
        ...
        PrintStream out = new PrintStream 
                         (response.getOutputStream());
        ...
    }

Recall that the public interface for PrintWriter is the same as for PrintStream. The primary difference is the way that buffer flushing is handled when println is called. The main thing to keep in mind here is that anything written to printWriter will be saved in the survey results file, while anything written to out will be printed on the HTML form automatically generated by the JavaServer as a result of processing the form.
 
To allow the survey results to be written to a file a FileWriter object is associated with a PrintWriter object.
 

        results = new FileWriter (
                        _baseDir + System.getProperty
         ("file.separator") + surveyName + ".txt", true);
            printWriter = new PrintWriter (results);

Recall that _baseDir holds the string that was passed in as the value of the baseDir property.
      _baseDir = config.getInitParameter ("baseDir");
The value of the baseDir property was set in the Server Administration applet to baseDir=/tmp when the JdcSurvey01 was added to the list of supported servlets. See Figure 06.
 
Thus the name of the file created by
 
     results =
      new FileWriter (_baseDir + System.getProperty
        ("file.separator") + surveyName + ".txt", true);
is /tmp/Survey01Results.txt since the value of the surveyName property was set TestJdcSurvey01.html.
 
    <input type=hidden name=
                      survey value=Survey01Results>
If you want to change the name of the output file, edit the above line accordingly.
 
Now output that is written to printWriter such as
 
      printWriter.println ("<BEGIN>");
      ...
      printWriter.println (name + ": " + value);
      ...
      printWriter.println ("<END>");

will be written to the file, /tmp/Survey01Results.txt.
 
Output that is written to out such as
 
      out.println ("Thank-You for participating");
        ...
      out.println ("A problem occured while recording
            your answers. Please try again.");
will appear in the client's browser after the form has been processed and control returns from JdcSurvey01::service.
 
The main thing you need to know to understand how a servlet processes form arguments, is that input for the form processing is read from the request argument to the service method, and output is written in the response argument to the service method.
 
    public void service (HttpServletRequest request, 
                HttpServletResponse response) throws 
                ServletException, IOException
    {
        ...
    }

More specifically, the request method contains a list of parameters that can be retrieved with the HttpServletRequest::getParameterNames method.
 
       Enumeration values = request.getParameterNames();
With the values enumeration object returned by this call, you can now set up a loop to process each of the parameters passed by the HTML form to the servlet service routine:
 
       while ( values.hasMoreElements() )
            {
                ...
            }
The name of the parameter is retrieved on each iteration by Enumeration::nextElement, while the associated value is retrieved by HttpServletRequest::getParameter, which accepts the parameter name as an argument.
 
                String name, value;
                name = (String)values.nextElement();
                value = request.getParameter (name);
The only value you don't want to print in the results file is the value of the "submit" parameter, which is passed because submit was specified as a button in the HTML file. The servlet service routines weeds out this parameter with a simple string comparison:
 
      if ( name.compareTo ("submit") != 0 )
        {
          printWriter.println (name + ": " + value);
        }
You should now know enough to write simple servlets to extend your JavaServer to process forms that you would otherwise have to process with complex CGI scripts. The only other detail worth mentioning is the exception-handling capabilities provided by servlets. Be sure to specify that your service and init methods in your HttpServlet subclass can each throw a ServletException:
 
    public void init (
      ServletConfig config) throws ServletException
    ...
    public void service (HttpServletRequest request, 
                  HttpServletResponse response) throws 
                    ServletException, IOException
    ...

Inside the JdcSurvey01 servlet the service method uses two try/catch blocks to help provide either the user or the programmer with adequate feedback when something goes wrong. In the first try block, the user is warned if a problem occurs while attempting to write the survey results to the file. The second try block, tries to assure that the results file is properly closed before exiting the service routine. If not, a stack trace is dumped to the standard error device.
 

Administering Servlets
The real beauty of a JavaServer is that it is extensible. But before you can use a servlet to add extended functionality to your JavaServer, you have to use the JavaServer Administration applet provided with the JavaServer to install the servlet and specify default parameters and arguments. Bring up the server administration tool by setting your browser to the following URL:
    http://webserver:9090/applet.html
where webserver is replaced with the host name of your machine. In my case, my host machine's name is cool1 so the URL I invoke to install servlets is:
    http://cool1:9090/applet.html
After your web browser contacts these URLs the applet code for the Servlet administrator will be downloaded and executed. First you'll see the login screen shown in Figure 03.
 


Figure 03. Full Size


Type admin for both the login id and the password. Now you should see the main application frame for the Servlet Administration Applet as pictured in Figure 04.
 


Figure 04. Full Size


With the service titled Web Page Service highlighted, press the Manage button at the bottom of the window. You should now see an applet window similar to that pictured in Figure 05, but you will have to press the Servlets in the row of buttons at the top of the window before you will see the available servlets listed in Figure 05.
 


Figure 05. Full Size


Now select the Add function in the list box at the left. The two text fields you see at the right of Figure 05 should appear.
 
Fill these fields in as follows:
    ServletName:   "JdcSurvey01"
    Servlet Class: "JdcSurvey01"
You do have the option of giving the servlet a different name from the class name. The class name is the name given to the subclass of HttpServlet, which implements your servlet, in this case JdcSurvey01.
    public class JdcSurvey01 extends HttpServlet
    {
        ...
    }
Finally, once you have added the JdcSurvey01 to the JavaServer, you'll see it appear in the list box underneath the Configure heading inside the JavaServer Administration Applet. When you select JdcSurvey01 in the list box, you'll be able to set arguments (passed as properties) for the servlet through the dialog panel shown in Figure 06.
 


Figure 06. Full Size


In this case, you should set the default base directory to which the result file will be written when the form is processed by the service method of JdcSurvey01. As indicated in the code walkthrough presented earlier, the name for this property association is baseDir and the value is /tmp. This association can be specified as an argument by editing the dialog field labeled Arguments:
    Arguments: baseDir=/tmp
The default value for this property can also be specified in the configuration file servlets.properties. The full pathname for this file, relative to the root location where you installed your JavaServer is:
    admin/properties/process/javawebserver
                  /webpageservice/servlets.properties
One of the lines in the file should read:
    servlet.SurveyServlet.initArgs=baseDir=/tmp
or be set to another directory location, if you prefer an alternate default location.
 
Once you have installed the servlet though the Administration applet, you can invoke it from within an HTML file, such as TestJdcSurvey01.html as follows:
    <form action=http://cool1:8080/servlet/JdcSurvey01 
                                       method=POST>
The first part of the HTTP reference locates the JavaServer itself, assuming the default port number of 8080 has not been altered by special configuration or invocation parameters.
    http://cool1:8080
The latter part of the HTTP reference should begin with /servlet/ followed by the name which you gave to your servlet when installing it in the JavaServer Administration Applet. This name can be different than the actual class name given to the servlet if you wish.
 
You'll notice that the full URL corresponding to http://cool1:8080/servlet/JdcSurvey01 appears in the browser's URL filed in Figure 02. This is the web page that is automatically generated by the JavaServer after all output has been written to the response passed to the service in the JdcSurvey01 class.
 
(See Figure 02.)
 
Java Server Resources
Forms and forms-processing servlets like those presented here are used inside the Java Developer Connection web site. The JavaServer has made life a lot easier for us as we've upgraded the site over the past several months. In a subsequent article I'll follow up with some more complex examples of JavaServer servlets that show some of the tricks we've learned while working under the hood of this exciting new Java technology. I'll also show you how some of the servlets would appear as more traditional CGI Perl scripts so that those of you familiar with CGI can make a more personal comparison. Keep in mind that the JavaServer can process CGI scripts just like Apache or any other popular web server that you're accustomed to. So even if you've already got existing CGI scripts to dish out your web pages, Java Server will give you improved performance because it can spawn lightweight threads (instead of invoking an expensive new shell process) each time a form-processing request is required.
 
Now there's no excuse not to use Java to extend both sides of the client-server architecture.
 
Read Part II of the JavaServer technologies series.

Oracle is reviewing the Sun product roadmap and will provide guidance to customers in accordance with Oracle's standard product communication policies. Any resulting features and timing of release of such features as determined by Oracle's review of roadmaps, are at the sole discretion of Oracle. All product roadmap information, whether communicated by Sun Microsystems or by Oracle, does not represent a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. It is intended for information purposes only, and may not be incorporated into any contract.