- Special Edition Using Java, 2nd Edition -

Chapter 42

Server-Side Scripting with Java


by Joe Weber

One of the advances the Netscape Corporation added to its second generation Web servers—Enterprise Server and FastTrack Server—was the ability to uniquely use the Java and JavaScript languages to perform server-side work. This integration is designed to help you more easily perform the tasks which were previously accomplished through CGI scripts. In addition, Sun has taken up the same quest with its Servlet technology currently available only in its HTTP server (code-named Jeeves).

Why Use Java for Server-Side Applications?

So why would you want to use Java to perform server-side interaction? First, for developers who are already working in the Java programming language (of which you obviously are now), and who want to take advantage of the rapid development cycles afforded by Java, server-side Java is a natural extension. Second, it is often advantageous to use the efforts that are put into a client-side Java applet and mitigate that onto the server.

One prime example of where using the code from a standard Applet on a server-side program can be extremely helpful is with programs that serve dual purposes. Java can be used not only on the Web, but also on desktops. This combination provides a unique independence. As a result, Java is being used to develop in many situations where the medium of delivery will be both CD-ROM and Internet. In other words, with Java, it is possible to deliver exactly the same application first on a Web site as an applet, and then as an application on a CD-ROM. When many of these applications are used on the Internet, though, they suffer badly because of bandwidth restrictions.

The problem is that a CD-ROM can contain a lot of information. After all, a CD-ROM can contain more than 600M. Transferring all that data across the low-bandwidth Internet is very problematic. As a result, it is often the case that it would be nice to limit the amount of data sent. By extracting the search portion the applet for the server (without any other code changes), this limitation is simple and very cost effective.

In addition to these benefits, you can capture great power from using the client/server abilities of Java. By interacting with a client side Java applet, a server-side applet can share the load between it and the client. By placing the various portions of your program on two computers you can produce the best solution for your environment. For instance, by limiting the amount of sheer calculations which are performed by the server, you can reduce your server load. At the same time, by forcing the server to do all the work that requires access to large amounts of data, and having it send only the limited portion of the data that the client needs, you end up limiting the amount of bandwidth required by the client. The client can perform most of the calculations, while the server performs all the data searching.

Server-side Java can be done in three ways:

Enabling Java on the Enterprise or FastTrack Server

Because the first option—using Java for standard CGI—isn”t very practical, ignore that option in this chapter. Let”s start by taking a look at how to use the Enterprise and FastTrack Servers with server-side applications.

In order for you to take advantage of the Java serving capabilities of the Enterprise or FastTrack servers, you must first enable these options on the server.

The controls for the VM are located in the server controls. Netscape”s integrated server management system includes controls for a great number of items about your server, and each of these things is placed under different headings. To get to the Java controls:

Select the PROGRAMS file in the main window as shown in figure 42.1.

Select the JAVA controls in the side frame.

To have the server use the JVM, choose Yes and select OK, as shown in figure 42.2.


FIG. 42.1

Select the Programs option in the main window.


FIG. 42.2

Activate the Java interpreter.

Once you choose OK, the server prompts you to confirm the changes and to restart the server. If all goes as planed, the server notifies you that it has been restarted, as shown in figure 42.3. If not, you may need to manually stop and restart your server in order for these changes to take effect.


FIG. 42.3

The server should confirm that it has restarted.

With the Netscape 2.0 servers, the directory /SERVER-JAVA has been set aside in much the same way that /CGI-BIN has been used on first-generation HTTP servers. Now that you have enabled Java on your Web server, you can confirm that it is working by using some of the Java applications that are included with the Enterprise and FastTrack servers.

In order for you to use the demonstration classes that are shipped with the Enterprise and FastTrack servers, you need to make sure you have entered the correct directory in the Java Applet Directory option during your server configuration. By default, this directory is
 
/USR/NS-HOME/PLUGINS/JAVA/APPLETS
 
However, you will want to change the /USR/NS-HOME to the directory that is appropriate for your instillation.

To test the Java implementation with your server, you can now open the URL http://your.webserver.com/server-java/BrowserDataApplet in your browser. This should cause the server to run the BrowserDataApplet and return information about your browser, as shown in figure 42.4.


FIG. 42.4

The BrowserDataApplet reveals information about your browser.

The information that is shown about the browser is the information that the browser provides to the server. There is no magic bullet here; the server must rely on what and/or who the browser claims to be. As a result, if you use the information, you should be aware that a browser can provide information that may not seem to be correct. Some browsers, such as Microsoft Internet Explorer, show themselves as being Mozilla for compatibility with Netscape, as shown in figure 42.5.


FIG. 42.5

Microsoft Internet Explorer claims to be Mozilla.

So where does this information come from? First, take a look at the directory

Make sure you substitute /NETSCAPE-SERVER-DIRECTORY with the directory in which your Netscape 2.0 server resides. In that directory, you will find several files, one of which is called BrowserDataApplet.class.

When you accessed the directory /SERVER-JAVA, the Enterprise server went out and loaded the BrowserDataApplet class into its virtual machine; the results were sent to your browser, just like a CGI program.

HelloWorld Java Application for a Server Applet

Instead of diving into the complete source code for the BrowserDataApplet, let”s take a look at how to do something a bit simpler. In almost every language since Kernie and Richie invented C, the first program is traditionally one that says Hello World. Java is a unique language in that it has a number of different Hello World implementations, depending on how it is being used. You have already seen how to write HelloWorld as an application and as an Applet. Now let”s write it so that the server sends a document that simply says Hello World to the browser.

Listing 42.1 shows the source code for the sever-side applet HelloWorld program.

Listing 42.1 HelloWorld for server-side Java application.

/* Import the required classes from other packages */
import netscape.server.applet.HttpApplet;
import java.io.PrintStream;
/* The class which is created is called HelloWorld */
public class HelloWorld extends HttpApplet{
public void run() throws Exception {
PrintStream out = getOutputStream();
out.println ("HelloWorld");
}

}

Understanding the Source Code for the HelloWorld Application

In order to understand the source code for the HelloWorld application, let”s take it line by line. The first two lines of the code import two classes. The first class is provided by Netscape, and the second is included with the Java library provided with Sun”s Java Developer Kit.

/* Import the required classes from other packages */
import netscape.server.applet.HttpApplet;
import java.io.PrintStream;

netscape.server.applet.HttpApplet is probably the most important class included with the API from Netscape. The server expects all the programs that it loads to be HttpApplets, just as Appletviewer or Netscape expect classes to extend java.applet.Applet. As you see in the next line of code, you can make the HelloWorld class into an HttpApplet by extending, or inheriting, the characteristics of HttpApplet.

The next line of code is the class declaration. In order to be usable as a server-applet, all classes must be declared first to be public (so the server can read them) and second to extend HttpApplet.

/* The class which is created is called HelloWorld */
public class HelloWorld extends HttpApplet{

All server applets need to overload the method run(). The run method is the method which the server runs when a user attempts to access the URL where the HelloWorld applet is located. In a certain sense, you can think of the run() method as the cousin of the main() function in C or C++.

public void run() throws Exception {

The next two lines perform the actual work of the class. In this case, you want to write the text Hello World out to the browser. In order to do this, you need a place to write the text. This may seem obvious, but remember the class doesn”t know what it is that you want to do, and System.out will put it on the server”s console, not in the browser window. Fortunately, Netscape has included a method called getOutputStream() which provides you with a means to get to the stream of data going back to the client.

PrintStream out = getOutputStream();

Finally, now that you have access to the stream handler, you can place the text Hello World on the browser screen. To do this, use the println() method provided in the PrintStream class.

out.println ("HelloWorld");

The last two lines could also have been written as

getOutputStream().out.println(“Hello World”);

if you would prefer. Because you are used to the syntax of System.out.println() this may even make more sense to you.

Creating and Compiling the HelloWorld Application

To create this application, copy the contents of listing 42.1 into your favorite text editor. Then compile them using the javac program supplied with Sun”s JDK.

Including the Netscape Package in the CLASSPATH

The syntax for compiling the HelloWorld application is not quite as simple as for most Java code. The reason for this is that you need to import a class from the Netscape package. As a result, it is necessary to include the file that contains the package in the CLASSPATH.

Before you can include the file, though, you need to first determine where the file is located. What you need to look for is a file called SERV2_0.ZIP. By default, this file is located at

You need to substitute the /USR/NS-HOME directory with the correct directory for your Enterprise or FastTrack server. As with the rest of this chapter, the location that is used for my installation is /OPTL/ENT-HOME, so the actual path is

but your installation is likely to be different. to obtain the proper file name, substitute /OPTL/ENT-HOME for the directory where you installed the FastTrack or Enterprise server.

In addition to the SERV2_0.ZIP file, you may need to know the location of the CLASSES.ZIP file included with the JDK. This file is located in the /JAVA/LIB directory. For the purposes of this chapter, the file in my installation is located at
 
/OPTL/JAVA/LIB/CLASSES.ZIP
 
But as with the location of the SERV2_0.ZIP file, you need to substitute the actual directory where you have installed the JDK.
If you obtain an error such as
 
class java.io.PrintStream not found on import
 
the odds are that you need to also add the CLASSES.ZIP file to your CLASSPATH.
 

Once you have located the CLASSES.ZIP and SERV2_0.ZIP files, you have two ways to add them to the class path. The first and simplest is to do so on the command line. To compile the HelloWorld file, include the Netscape package in the CLASSPATH as shown in the following command line:

This should produce a file called HelloWorld.class in the directory where the HelloWorld.java file is located.

If you”re like most people, you don”t really want to have to type out 104 characters every time you want to compile the HelloWorld program. To eliminate the need to always specify the -CLASSPATH option, you can set an environment variable called CLASSPATH to point to the SERV2_0.ZIP file. Once the CLASSPATH has been set, you can compile a program in much the same way you would any other Java application.

To set the CLASSPATH variable using the corn shell (csh), you would type:

CLASSPATH=/optl/ent-home/plugins/java/classes/serv2_0.zip
export CLASSPATH

For Windows NT users, the examples given here and through out this chapter are for UNIX machines. When using an NT machine, the directories should use the backslash (\) instead of the forward slash (/). Also, to set an environment variable, you need to use the set command, as in:
 
set classpath=\ns-home\plugins\java\classes\serv2_0.zip
 

 

Once the you have set the CLASSPATH variable, you can now compile the HelloWorld application by typing:

Viewing the HelloWorld Application

To be able to run the HelloWorld application, the first step is to copy the HelloWorld.class file into the directory you have specified when configuring the Enterprise or FastTrack server (refer to fig. 42.2). If you placed the HelloWorld.java file in this directory and compiled it there, you don”t have to move anything; it is already in the correct location.

To test out the HelloWorld application, open the URL /server-java/HelloWorld in any browser. It does not need to be a Java-enabled browser such as Netscape Navigator. Figure 42.6 shows the page you should see.


FIG. 42.6

The HelloWorld application should generate a simple page in your browser.

As you can see from figure 42.6, the Java application produced something which, to your browser, looked exactly like it was coming from any standard HTML file. Of course, this was a lot of work to produce a simple line of text, but before you learn to surf the big waves, it is generally a good idea to learn to swim first.

A Bigger Greeting Example

Now take a look at a more advanced Java application similar to the BrowserDataApplet, which shows some information about the incoming browser. Listing 42.2 shows the source code for the new application.

Listing 42.2 Greetings Java source code—A server-side applet that displays browser information.

import netscape.server.applet.HttpApplet;
import java.io.PrintStream;
import java.net.Socket;
import java.net.InetAddress;
public class Greetings extends HttpApplet {
public void run() throws Exception {
//Check to find out if browser can accept normal text output
if (returnNormalResponse("text/plain")) {
//Get the output stream to send data to client
PrintStream out = getOutputStream();
//get the socket the browser is connected to
Socket client = getClientSocket();
//find the hostname of the socket
String clientAddress = client.getInetAddress().getHostName();
//Check to see if it's my IP address
if (clientAddress.compareTo ("206.31.43.250")==0)
out.println("Greetings great and wonderful master!");
else
out.println("Nice to meet other netizens");
//Find out what browser the client is using
String browser = getHeader ("user-agent");
if (browser != null){
if (browser.startsWith ("Mozilla"))
out.println ("Your using Netscape... Hey this is a Netscape Server too!");
else
out.println("You're using the" + browser+” browser”);
}
else
out.println("Hey, your browser didn't identify itself.");
}
}
} //end class Greetings

Notice that just like our HelloWorld example, the very first thing that you need to write is

import netscape.server.applet.HttpApplet;

This includes the class from the Netscape library into the Java environment. Netscape actually provides four classes to assist the construction of server side applications:

Each of these classes provides a means to access data about the server or the client in order to make writing server applications easier.

Each different class contains various methods to place or get information about the environment. In the HelloWorld example, the only method used was getOutputStream(). The Greetings shows the use of several more of methods in HttpApplet.

The first line in the Greetings class shows an example of one such method. Before you blindly write to the browser (like you did with the HelloWorld application), it is better to first make sure that the browser is willing to accept text output. If not, you may have to respond differently, so the first line of the Greetings application checks to see if the browser has a standard “text/plain” response:

if (returnNormalResponse("text/plain")) {

After you have verified the browser response, the application opens the output stream, just as it did in the HelloWorld application. Once the connection has been established to the browser, the program proceeds to send data, the same way that it did for HelloWorld.

Now, it”s often convenient to know who is accessing your server. Based on who it is, you might want to give a different response to the user, so let”s retrieve some information about the client accessing the Greetings application.

The next line of code defines a Socket variable that points to where the client has attached. If you are familiar with Java programming, this socket can be used just as it would in any other Java application.

Once you have a pointer to the client socket, you can use it to determine the address the client browser is coming from, using the getInetAddress() method. Once you have the client”s IP address, you can use it to determine if the client is a valid host or someone else. In this example, I choose to simply have the application greet my computer differently than other people on the Net:

//get the socket the browser is connected to
Socket client = getClientSocket();
//find the hostname of the socket
String clientAddress = client.getInetAddress().getHostName();
//Check to see if it's my IP address
if (clientAddress.compareTo ("206.31.43.250")==0)
out.println("Greetings great and wonderful master!");
else
out.println("Nice to meet other netizens");

For experienced Java programmers, it might be interesting to note that the getClientSocket() method is not one from HttpApplet, but rather from its parent ServerApplet.
 
The getInetAddress() and getHostName() methods are not part of the Netscape package at all, but rather part of members of the java.net package.
 

Another useful piece of information to use is what type of browsers are accessing your pages. If they are not Netscape compliant, you may actually want to give them a completely different Web page. The next several lines of the Greetings application deal with doing just that. First, the type of browser is obtained using the getHeader method. This method can be used to retrieve a variety of information about the standard HTTP header. The HTTP header contains a lot of information about the browser, but the one you”re interested is the agent (or browser) that the incoming request is coming from. This information is contained in the User-Agent portion of the header. To retrieve the various other pieces of information contained in the header, the string “user-agent” should be substituted with the appropriate title:

//Find out what browser the client is using
String browser = getHeader ("user-agent");

You may initially wonder about the next line of the code, which reads:

if (browser != null){

It”s important to make sure that you actually received a string from the getHeader request, because unfortunately, it is not always the case that information obtained using the various methods will actually return data. For instance, some browsers do not return information about who they are. If this is the case, the method will return null, and unless you check for this, you will run into problems using the string.

I decided that if the browser that was coming in was a Netscape Navigator browser (or any browser claiming to be Netscape), I would give the user a friendly hello. To do this, you need to compare the browser name with Mozilla. In fact, all you really care about is, does the browser”s name start with Mozilla? If not, you will simply give them another message.

The Methods of netscape.server.applet.HttpApplet

A complete list of the netscape.server.applet.HttpApplet may be helpful in developing server applications (see table 42.1).

Table 42.1 HttpApplet Methods

Methods Use
public String getMethod() Returns the method request header (such as GET, HEAD, or POST).
public URL getURI() Returns the relative portion of a URL (for example, if a URL is http://www.magnastar.com/applets, the URI would be /applets).
public String getProtocol() Returns the protocol that is being used for transportation (such as HTTP).
public String getQuery() Returns the query string from the HTTP request.
public String getPath() Returns the path of the HTTP request.
public void setContentType(String type) Sets the content type for the HTTP response.
public getURL() Returns the URL of the HTTP request.
public boolean returnNormalResponse Starts an HTTP (String contentType)response request. The content type is set based on the parameter, and headers that have been established by calling setResponseProperty are sent.
public void returnFile Opens an HTTP response and (String contentType, File file)sends the contents of the specified file using the indicated contentType.
public void returnFile(File file) Similar to the previous method, but the content type is derived from the extension of the file (for example, MYFILE.GIF).
public boolean returnErrorResponse Opens an HTTP error(String contentType, int status, String reason)response to the request using the given error status and reason.
public boolean returnMultipartResponse Initiates a multi-(String subtype, String boundary)part boundary, and explicitly sets the boundary marker.
public void endMultipartResponse() Ends a multi-part response. This method must be called to close a multi-part response. If multiple multi-part responses are nested, the most recent part is closed.
public void setStatus(int n, String Reason) Specifies the status of the response and the reason.
public int setFileInfo(File file) Sets the status based on a given file. If for instance the client only wants a changed file (instead of the cached value), this function returns ABORTED.
public String translateURI (String uri) Translates the given string into the full path for the given file system.
public static String uri2url Concatenates the prefix and(String prefix, String suffix)suffix to form the URL.
public Hashtable getFormData() Returns the values of a form. These values are placed in a Hashtable and separated by && characters. The names become the keys to the Hashtable.
public String getFormField (String fieldName) Returns the form field of the HTTP request for the given field name.

(d)The Methods of netscape.server.applet.ServerApplet

The netscape.server.applet.ServerApplet class is at the heart of most of the activities of Java-based CGI. The HttpApplet class extends this class, so these methods in table 42.2 are available to any class that extends HttpApplet as well.

Table 42.2 ServerApplet methods

Methods Use
public Socket getClientSocket() Returns the socket that is connected to the client.The socket can be used to obtain information about the incoming client, including its IP address.
public String getClientProperty Returns various(String name)information about the client. The name can be set to several variables, the most common of which are ip and dns.
public String getConfigProperty Returns parameters set by(String name)the site administrator for the invocation of server applets.
public String getHeader(String name) Returns the header value requested by the name value. The name-value pairs are set based on the RFC822 headers.
public InputStream getInputStream() Returns the InputStream which should be used to read from the client.
public PrintStream getOutputStream() Returns the PrintStream which should be used to write to the client.
public String getRequestProperty Returns properties about (String name)the client”s request. The request properties include method, uri, protocol, and query.
public String getResponseProperty Returns the properties (String name)which are to be sent to the client as a result of the client response.
public static Server getServer() Returns the Server which may be queried for information about the server. Helpful for use when trying to get information about the current server.
public String getServerProperty Returns properties that(String name)represent the working variables of the server.
public void inform (String error) Records informational message in the server”s error log.
public void reportMisconfiguration Records informational(String error)message in the server”s error log about missing or illegal parameters.
public void reportCatastrophe Records informational message(String error)in the server”s error log about a catastrophic error.
public void reportFailure(String error) Records informational message in the server”s error log about a general failure.
public void reportSecurity (String error) Records informational message in the server”s error log about a security violation, or someone attempting to access a resource they shouldn”t.
public void run() throws Exception The run method performs the work fulfilling the request that was made to the server. Each applet must override the run method for its own purposes. Any exceptions generated by the run method indicate some sort of failure and are recorded in the server 4"s error log.
public void setResponseProperty Sets properties that (String name, String value)should be returned as the result of client responses.
public void warn(String error) Records an informational message in the server”s error log about warnings.

Sun”s Servlet Technology

Currently code named Jeeves, Sun”s Java-based Internet server is actually a framework for developing Internet services, installing them, and making them secure.

The thing that makes Jeeves the most different is the use of what have been called servlets. Servlets work a lot like SHTML documents. When a request is made to an object that contains a servlet, the servlet is executed and the output is sent to the client. The major difference between standard SHTML documents and servlets, however, is that once a communications socket is opened between the servlet and the client, the servlet can continue to have a on-going dialog with the client. In this sense, it is very similar to Netscape”s technology.

Servlets can also be written to work with server-side includes. So servlets can go either way—SHTML or as an server response to a directory.

In addition, servlets don”t have to be loaded separately each time a servlet page is loaded. Once a servlet is placed into memory and can respond to all requests to that page. This can dramatically save on resources. In fact, Servlets have an init() method, similar to Applets. So, if there are some costly operations which it will perform for every request, the Servlet can place this in its init() method and maximize performance.

Currently in the servlet specification is the ability to allow digitally-signed servlets to be loaded over the Net. This technology could eventually mean that servlet authors could charge for their programs on a per-use basis. Individuals whose pages are not accessed frequently, but who would still like to normally expensive programs on their systems. They would only need to pay for what they use.

The Servlet HelloWorld Example

Take look at the HelloWorld example for a Servlet, just as you did for the Netscape example (see listing 42.3).

Listing 42.3 HelloWorld example for a Servlet.

/* Import the required classes from other packages */
import java.servlet.*;
import java.io.PrintStream;
/* The class which is created is called HelloWorld */
public class HelloWorld extends Servlet{
public void service(ServletRequest req, ServletResponse resp) throws IOException {
PrintStream out = new PrintStream (res.getOutputStream());
//Write out standard HTML response header
res.setContentType (“text/html”);
res.writeHeaders();
//Write out the response
out.println(“<HTML><BODY>“);
out.println ("HelloWorld");
out.println(“</BODY></HTML>“);
}

}

By comparing listing 42.3 and 42.1, you find that they are surprisingly (or perhaps not so surprisingly) similar. All servlets must extend the java.servlet.Servlet class. The most important method in Servlet is service(). The service() method is called each time the server receives a request for the Servlet page.

If you look at the service() method, you see that just like the run() method in the Netscape HelloWorld program, the first task is to create a PrintStream buffer to print data back to the browser.

The next few lines of code show one of the differences between Servlets and HttpApplets—namely that you need to actually write out the header information. Finally, the next lines are nearly identical to the final line of listing 42.1.

The Servlet Greeting Example

Once again, as you did with the HttpApplet, take a look at the Greeting example using the Servlet Technology. Listing 42.4 shows the code for doing this.

Listing 42.4 Greeting example using the Servlet Technology.

import java.servlet.*t;
import java.io.PrintStream;
import java.net.Socket;
import java.net.InetAddress;
public class Greetings extends HttpApplet {
public void service (ServletRequest req, ServletResponse res) throws IOException {
//Get the output stream to send data to client
PrintStream out = new PrintStream (res.getOutputStream();
//find the hostname of the socket
String clientAddress = req.getRemoteAddr();
//Check to see if it's my IP address
if (clientAddress.compareTo ("206.31.43.250")==0)
out.println("Greetings great and wonderful master!");
else
out.println("Nice to meet other netizens");
//Find out what browser the client is using
String browser = req.getHeader ("user-agent");
if (browser != null){
if (browser.startsWith ("Mozilla"))
out.println ("Your using Netscape... Hey this is a Netscape Server too!");
else
out.println("You're using the" + browser+” browser”);
}
else
out.println("Hey, your browser didn't identify itself.");
}
}
} //end class Greetings

As with the HelloWorld example, the Greetings example in listing 42.4 is nearly identical to its listing 42.2 counterpart for Netscape server.

As with the HelloWorld example, most of the work for the Servlet is actually being done in the service() method.

The major difference between listings 42.2 and 42.4 is the fact that java.servlet.ServletRequest includes methods to retrieve information about the request data directly. It”s not necessary to get the client socket and then find the address as you did in listing 42.2. With a servlet, you can simply call the getRemoteAddr() method to obtain this information.


Previous Page TOC Next Page

| Previous Chapter | Next Chapter |

|Table of Contents | Book Home Page |

| Que Home Page | Digital Bookshelf | Disclaimer |


To order books from QUE, call us at 800-716-0044 or 317-361-5400.

For comments or technical support for our books and software, select Talk to Us.

© 1996, QUE Corporation, an imprint of Macmillan Publishing USA, a Simon and Schuster Company