Java Web Server

Using Java Classes


Contents / New Features / Administrator Docs / Developer Docs / Index / Page Comp Intro

The Java examples provided in Using Page Compilation demonstrate a variety of ways you can use Java programming statements to produce HTML output. The real power of Java, however, is the wide array of classes available for use with any Java program.

Java itself comes bundled with a rich set of useful classes such as Hashtables, Vectors, and networking classes. And every day, new classes are being written and added to the worldwide repertoire of Java functionality.

This document provides information about using Java classes in your HTML/Java pages:

Importing Java Classes

You can use any Java class in your page. Here's an example that uses the java.util.Date class:
<java type=import>
java.util.Date
</java>

<html>
<head><title>Today</title></head>
<body>
<h1>Today</h1>

<java>
// Maps day number to a name
String days [] = { "Sunday", "Monday", "Tuesday", "Wednesday",
                   "Thursday", "Friday", "Saturday" };

// Get today's date
Date today = new Date ();
int weekday = today.getDay ();
out.println ("<p>Today is " + days [weekday] + "!");
</java>

</body>
</html>

You can import all the classes in a package by using the * character. For example, the following code will import every class in java.net:

<java type=import>
import java.net.*;
</java>

After you import the classes you intend to work with, you can use those classes in the same way as any other Java class. Use new to create new objects, and call methods on those objects. The above example creates a new Date object and calls getDay () on that object to print out the day of the week.

You may have noticed the use of comments inside the java section. This is a good habit to get into, especially when you start writing large Web applications. But remember that you can only use Java-style comments in java sections, not HTML-style comments.

You are not limited to using the classes that come with Java. You can use classes that you create, or classes that you downloaded from your favorite Java Web site. All you have to remember is to import the classes before you use them, and to configure your CLASSPATH variable to specify the directory containing your Java classes.

Extending the Page Class

As your Web applications grow more complex, you may find yourself writing similar pieces of code over and over again in different files. This is especially true if your applications have multiple pages which perform similar functions. It would make sense to write this common code once, put it into a method, and have different pages access that method. The question is, where should that method go?

Before we answer this question, you'll need to know a little more about what happens when PageCompileServlet turns your file into Java code. As explained earlier, PageCompileServlet preprocesses your file into pure Java code. Anything between <java> tags is used verbatim, everything else is printed to the output stream.

But before this code can be used, Java requires that it reside within a method of some class. To accomplish this, PageCompileServlet creates a new class for each of your page files. The code that came from your file is put into the method called service of the new class called HttpServlet.

Let's look at an example, using our first simple PageCompileServlet Page.

<html><head><title>My First Page</title></head>
<body><h1>My First Page</h1>
<ul>
<java>
  for (int i = 0; i < 5; i++) out.println ("<li>" + i);
</java>
</ul>
</body></html>

Here is the Java file that PageCompileServlet produces for this page:

package pagecompile;

import com.sun.server.webserver.pagecompile.filecache.*;
import com.sun.server.webserver.pagecompile.ParamsHttpServletRequest;
import com.sun.server.webserver.pagecompile.*;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*


public class _FirstPage
extends HttpServlet{

//-------------------------------
  static {
  }
  
  //-------------- The service method
  public void service (HttpServletRequest request,
                         HttpServletResponse response)
      throws ServletException, IOException
  {
    ServletOutputStream out = response.getOutputStream ();
    ByteFileData __fileData = null;
    try {
      __fileData = (ByteFileData) ServletUtil.getFileCache(this).getFile("C:\\Java Web Server1.0\\public_html\\FirstPage.jhtml", null, 865872648000L);
      if (__fileData == null) throw new ServletException("FileChanged");

      /*** lines: 1-3 */
      __fileData.writeBytes (0, 93, out);
  
     for (int i = 0; i < 5; i++) out.println ("<li>" + i);
           /*** lines: 5-8 */
      __fileData.writeBytes (175, 40, out);
    }
    finally {
      if (__fileData != null) __fileData.close();
    }
  }
}

This file is the source code for a Java class called First_page. This is a class name that PageCompileServlet has assigned to this page. Looking a little further down, we find a single method called service. Within this method, we find the contents of our original file, translated into Java code.

If we look again at First_page, we can see that it is a subclass of another class called HttpServlet. HttpServlet contains all the data about a particular page, such as the arguments passed to the page and the ServletOutputStream that connects back to the browser. Anything that is in the HttpServlet class can be accessed by the Java code in your pages.

PageCompileServlet lets you specify that a page descends from a class other than HttpServlet. This new superclass is where you put the methods that you want to be accessible by several pages. Because those pages descend from this new superclass, the pages can use the methods in this superclass.

Let's see if any of this becomes clearer with an example. Say we have a function that prints an HTML table with a row for each entry in the dictionary provided. Each row has two columns corresponding to the name and value of the entry.

Now that we have this function, we would like to use it in several pages. But we would rather not copy this function into every one of those pages. Instead, we'll make a new class containing this function:

package COM.mysite;

import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.*;

public abstract
class BetterHttpServlet extends HttpServlet {
  //---------------------------------
  /**
   * Outputs an HTML table with a row for each entry in the dictionary
   * provided.  Each row has two columns corresponding to the name and
   * value of the entry
   */
  public void outputDictionaryTable(HttpServletResponse response, 
  				    Dictionary dict) throws IOException {
    ServletOutputStream out = response.getOutputStream();

    // Print a table
    out.println ("<table border");
    out.println ("<tr>");
    out.println ("<thKey</th>");
    out.println ("<thValue</th>");
    out.println ("</tr>");
  
    for (Enumeration keys = dict.keys (); keys.hasMoreElements (); ) {
      // Print each element
      Object key = keys.nextElement ();
      Object val = dict.get (key);
      out.println ("<tr>");
      out.println ("<td>" + key + "</td>");
      out.println ("<td>" + val + "</td>");
      out.println ("</tr>");
    }

    out.println ("</table>");
  }
}  

A few things to note here. First, the class BetterHTTPServlet is part of packageCOM.mysite. You must make sure that your CLASSPATH can see this package. Second, this class should import all of javax.servlet.http, so it can use all of the Java classes. Third, this class is a subclass of HttpServlet so you can use all the variables and methods available to an HttpServlet. Finally, notice that our function throws the IOException. Any function that prints to out must declare this exception. Now that we have our class, our pages can use it by specifying an extends declaration at the beginning of the page, before all the import statements. Like so:

<html>
<java type=extends>COM.mysite.BetterHttpServlet</java>
<head><title>An extended page</title></head>
<body>
<java>
  Hashtable myDict = new Hashtable();
  myDict.put("a row", "a value"); 
  myDict.put("another row", "another value"); 

  // Call a method defined in our superclass BetterHttpServlet
  outputDictionaryTable(response, myDict);
</java>
</body>
</html>

The class created for this page will be a subclass of BetterHTTPServlet, rather than HttpServlet. This means that the page can access any of the methods and variables in BetterHTTPServlet, such as outputDictionaryTable(response, myDict);. Of course, the page can also access all the variables it would normally use, such as out.

Now that you have this superclass for your pages, you can have several, or all, of the pages in your Web application extend this page. This is an excellent way to design all the main functionality of your application into a single class. Then, all your pages simply extend from this class and call methods on it.

Another way to declare methods is to do it directly in the page using the type=class form of the java tag. This kind of declaration will create a method usable from that page, but not accessible by other pages. For example:

<html>
<java type=import>
  java.util.*
  java.io.*
</java>
<java type=class>
  //---------------------------------
  /**
   * Outputs an HTML table with a row for each entry in the dictionary
   * provided.  Each row has two columns corresponding to the name and
   * value of the entry
   */
  public void outputDictionaryTable(HttpServletResponse response, 
  				    Dictionary dict) throws IOException {
    ServletOutputStream out = response.getOutputStream();

     // Print a table
    out.println ("<table border");
    out.println ("<tr>");
    out.println ("<thKey</th>");
    out.println ("<thValue</th>");
    out.println ("</tr>");
  
    for (Enumeration keys = dict.keys (); keys.hasMoreElements (); ) {
      // Print each element
      Object key = keys.nextElement ();
      Object val = dict.get (key);
      out.println ("<tr>");
      out.println ("<td>" + key + "</td>");
      out.println ("<td>" + val + "</td>");
      out.println ("</tr>");
    }

      out.println ("</table>");
  }
</java>
<head><title>A page with embedded class code</title></head>
</body>
<java>
  Hashtable myDict = new Hashtable();
  myDict.put("a row", "a value"); 
  myDict.put("another row", "another value"); 

  // Call a method defined in our superclass BetterHttpServlet
  outputDictionaryTable(response, myDict);
</java>
</body>
</html>

Additional Class Declarations

At times, you may also want to include additional class declaration in your code. In some cases, extending your page servlet from another servlet requires too much effort. In these cases, you want to be able to add member variables and define methods of the page class directly.

This is supported with the <java type=class> tag. The type class defines code that is included as part of the page class itself.

Note: This code section cannot contain a conflicting implementation of the service method which will be generated by the PageCompileServlet.

Here is an example of adding class declarations to your file, using the <java type=class> tag:

<html><head><title>Example HTML/Java</title></head>
<body><h1>Example HTML/Java</h1>
<ul>
<java type=class>
  int mNumPageRequests = 0;
</java>
</ul>
This page has been requested 
<java> 
  synchronized (this) { 
    out.println(++mNumPageRequests); 
  }
</java>
times. 
</body></html>

The resulting Java code looks like this:

package pagecompile;

import com.sun.server.webserver.pagecompile.filecache.*;
import com.sun.server.webserver.pagecompile.ParamsHttpServletRequest;
import com.sun.server.webserver.pagecompile.*;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class _page__class
extends HttpServlet{

       int mNumPageRequests = 0;
     
//-------------------------------
  static {
  }
  
  //-------------- The service method
  public void service (HttpServletRequest request,
                         HttpServletResponse response)
      throws ServletException, IOException
  {
    ServletOutputStream out = response.getOutputStream ();
    ByteFileData __fileData = null;
    try {
      __fileData = (ByteFileData) ServletUtil.getFileCache(this).getFile("C:\\Java Web Server1.0\\public_html\\page_class.jhtml", null, 865875830000L);
      if (__fileData == null) throw new ServletException("FileChanged");

      /*** lines: 1-4 */
      __fileData.writeBytes (0, 108, out);
      /*** lines: 6-9 */
      __fileData.writeBytes (173, 55, out);
 
       synchronized (this) { 
         out.println(++mNumPageRequests); 
       }
           /*** lines: 13-15 */
      __fileData.writeBytes (334, 35, out);
    }
    finally {
      if (__fileData != null) __fileData.close();
    }
  }
>}
	


Top
java-server-feedback@java.sun.com
Copyright © 1997 Sun Microsystems, Inc.
All Rights Reserved.