Fall Semester 2002


Lecture Notes Twenty-One: Applets, servlets, and javax.servlet vs. CGI.pm
If you know Java you understand

The reviews posted last week were supposed to take care of that.

If you know Java you also understand:

So here's an example (exercise) to test your understanding.

Consider this:

class A {
  void fun() {
    System.out.println("This is fun as defined in class A."); 
  } 
}
 
class B extends A {
  void fun() {
    System.out.println("This is fun as defined in class B."); 
  } 
} 

public class One {
  public static void main(String[] args) {
    System.out.println("Welcome to Program One.");
 
    A m = new B(); 
    m.fun();  
 
    B n = new B(); 
    n.fun();
 
    ((A)n).fun(); 
 
  } 
} 
What do you get when you run the program?

Here's a similar, but a bit more involved example:

class Frame { // from java.awt

    protected String  myGC = "The Graphics Context from class Frame"; 
        
    protected int     width, height;
    protected boolean visible;
        
    protected void    resize(int w, int h) {
	setSize(w, h);
	refresh();
    }

    protected void    refresh() {
	paint(myGC);
    }

    protected void    setVisible(boolean tF) {
	visible = tF;
	paint(myGC);
    }

    protected void    setSize(int w, int h) {
	width = w;
	height = h;
    }
        
    public    void    paint(String gc) {
        System.out.println("Frame: I use\n  "
                         + gc 
                         + " \nto draw my images."); 
    } 
}
        
public class Painting extends Frame {

    public void paint(String graphicsContext) {
	System.out.println("Painting: I use\n  " 
                         + graphicsContext 
                         + " \nto draw my images.");
    }

    public static void main(String[] args) {

           Painting f = new Painting();  // you have 
           f.setSize(100, 200);          // seen this
           f.setVisible(true);           // many times... 

           user(f);                      // you never ever see this
                                         // but you know it happens
    }
     
    private static void user(Painting f) {
	f.resize(200, 400); 
       // minimal interaction by the user simulated here
    }

}
Notice: If you understand how the code above works then Also note: protected is like private, but allowing inheritance of the variable or method.

Here's the output of compiling and running the program above:

frilled.cs.indiana.edu%javac Painting.java
frilled.cs.indiana.edu%java Painting
Painting: I use
  The Graphics Context from class Frame 
to draw my images.
Painting: I use
  The Graphics Context from class Frame 
to draw my images.
frilled.cs.indiana.edu%
Can you explain it?

Do you see a similarity with this code?

import java.awt.*;
import java.awt.geom.*; 
        
public class Painting extends Frame {

    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D)g;

	Ellipse2D.Double e1 = new Ellipse2D.Double( 75, 40, 30, 70);
	Ellipse2D.Double e2 = new Ellipse2D.Double(115, 40, 30, 70);
	Ellipse2D.Double c1 = new Ellipse2D.Double( 85, 85, 15, 15);
	Ellipse2D.Double c2 = new Ellipse2D.Double(125, 85, 15, 15);
	Ellipse2D.Double n = new Ellipse2D.Double(55, 120, 110, 25);

	Arc2D.Double m = 
	    new Arc2D.Double(-40, -120, 300, 300, 230, 80, Arc2D.OPEN);

	g2.draw(e1);
	g2.draw(e2);
	g2.fill(c1);
	g2.fill(c2);

	g2.draw(n);

	g2.draw(m);
    }

    public static void main(String[] args) {

           Painting f = new Painting();  // you have 
           f.setSize(240, 230);          // seen this 
           f.setVisible(true);           // many times... 

           // user(f);                   // you never ever see this
                                         // but you know it happens
           // go ahead and be the user 

    }

}
Both applets and servlets are extensions of already existing defined classes.

For applets we extend class java.applet.Applet.

For servlets we have two options.

The Servlet API consists of two packages:

The javax part is there because servlets are a standard eXtension to Java, rather than a mandatory part of the API.

This means that while servlets are official Java, Java virtual machine developers are not required to include the classes for them in their Java development and execution environments.

The three core elements of the Servlet API are:

Normally, you create a servlet by subclassing one of the two classes, although if you are adding servlet capability to an existing object, you may find it easier to implement the interface.

The GenericServlet class is used for servlets that do not implement any particular communication protocol. Here's a basic servlet that demonstrates servlet structure by printing a short message.

burrowww.cs.indiana.edu% cd $myServlets
burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/jakarta-tomcat-3.2.1/webapps/examples/WEB-INF/classes
burrowww.cs.indiana.edu% emacs One.java
burrowww.cs.indiana.edu% cat One.java
import javax.servlet.*;
import java.io.*;
              
public class One extends GenericServlet {
    public void service(ServletRequest  req,
                        ServletResponse resp) throws  ServletException,
                        IOException {
        resp.setContentType("text/html");
        PrintWriter out = resp.getWriter();
        out.println("Hello, this is One.");
    }
}
burrowww.cs.indiana.edu% 
We compile it:
burrowww.cs.indiana.edu% javac One.java
burrowww.cs.indiana.edu% 
And we check it from
http://burrowww.cs.indiana.edu:21xxx/examples/servlet/One
BasicServlet extends the GenericServlet class and implements one method: service().

Whenever a server wants to use the servlet,

The servlet tells the server what type of response to expect, gets a printWriter from the response object, and transmits its output.

More Examples

1. The second servlet we develop is again a very generic and simple one.

burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/jakarta-tomcat-3.2.1/webapps/examples/WEB-INF/classes
burrowww.cs.indiana.edu% emacs Two.java 
burrowww.cs.indiana.edu% cat Two.java
import javax.servlet.*;
import java.io.*;
              
public class Two extends GenericServlet {
    public void service(ServletRequest req, ServletResponse resp)
        throws ServletException, IOException {
        resp.setContentType("text/plain");
        resp.getWriter().println("Hello... servlet Two here");
    }
}
burrowww.cs.indiana.edu% javac Two.java
burrowww.cs.indiana.edu%
2. The third servlet we develop is an HTTP Servlet, and that's a more specific one.
burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/jakarta-tomcat-3.2.1/webapps/examples/WEB-INF/classes
burrowww.cs.indiana.edu% emacs Three.java
burrowww.cs.indiana.edu% cat Three.java
import javax.servlet.*; 
import javax.servlet.http.*;
import java.io.*;
              
public class Three extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.getWriter().println(
            "<html><head><title>Three</title></head><body bgcolor=white>"
          + "HttpServlet replying to GET with: servlet Three here!</body></html>"
        );
    } 
}
burrowww.cs.indiana.edu% javac Three.java
burrowww.cs.indiana.edu%
3. The fourth servlet we develop is processing a form request.
burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/jakarta-tomcat-3.2.1/webapps/examples/WEB-INF/classes
burrowww.cs.indiana.edu% emacs Four.java
burrowww.cs.indiana.edu% cat Four.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
             
public class Four extends HttpServlet {

    public void doGet(HttpServletRequest req, HttpServletResponse resp)
                      throws ServletException, 
                             IOException {

        resp.setContentType("text/html");
        resp.getWriter().println(

              "<html><head><title>Four GET</title></head><body bgcolor=white>"
            + "<form method=POST action=/examples/servlet/Four>Type your name here: " 
            + "<input type=text name=fieldName size=10> <p> then push <input " 
            + " type=submit value=Proceed> (or hit Enter) </form></body></html>"

        );

    }

    public void doPost(HttpServletRequest req, HttpServletResponse resp)
                       throws ServletException, 
                              IOException {

        resp.setContentType("text/html");
        resp.getWriter().println(

              "<html><body bgcolor=white><h1>Hello, <font color=blue>" 
            + req.getParameter("fieldName")
            + "</font>!</h1></body></html>"

        );

    }
}
burrowww.cs.indiana.edu% javac Four.java
burrowww.cs.indiana.edu%
In class we will compare these with CGI.pm implementations.

Example One

#!/usr/bin/perl

use CGI;

$q = new CGI; 

print $q->header(-type=>'text/plain'),
      "Hello, this is One."; 
Example Two

#!/usr/bin/perl

use CGI;

$q = new CGI; 

print $q->header(-type=>'text/plain'),
      "Hello... servlet Two here.";
Example Three

#!/usr/bin/perl

use CGI;

$q = new CGI;

if ($q->request_method() eq 'GET') {
  print $q->header, $q->start_html(-bgcolor=>'white'), 
        "HttpServlet replying to GET with: servlet Three here!",
        $q->end_html;  
} 
Example Four

#!/usr/bin/perl

use CGI;

$q = new CGI;

if ($q->request_method() eq 'GET') {
  print $q->header, $q->start_html(-bgcolor=>'white'),
        $q->start_form(-method=>'POST',
                       -action=>$q->url), 
        "Type your name here: ", $q->textfield(-name=>'fieldName'), 
        "<p>then push: ", $q->submit(-value=>'Proceed'), " (or hit Enter)",  
        $q->end_html;  
} elsif ($q->request_method() eq 'POST') {
  print $q->header, $q->start_html(-bgcolor=>'white'), 
        "<h1>Hello, <font color=blue>", $q->param('fieldName'), "</font>!</h1>", 
        $q->end_html;
} else {

}
The CGI implementations seem more compact.

Do the servlet implementations offer any particular advantage?

Let's look at these two programs.

First the servlet:

burrowww.cs.indiana.edu% cd $myServlets
burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/jakarta-tomcat-3.2.1/webapps/examples/WEB-INF/classes
burrowww.cs.indiana.edu% cp One.java Counter.java
burrowww.cs.indiana.edu% emacs Counter.java
burrowww.cs.indiana.edu% cat Counter.java
import javax.servlet.*;
import java.io.*;
              
public class Counter extends GenericServlet {
    int n; 
    public void service(ServletRequest  req,
                        ServletResponse resp) throws  ServletException,
                        IOException {
        n = n + 1; 
        resp.setContentType("text/html");
        PrintWriter out = resp.getWriter();
        out.println("Counter is: " + n);
    }
}
burrowww.cs.indiana.edu% javac Counter.java
burrowww.cs.indiana.edu% 
Then the CGI.pm (or CGI) implementation:
#!/usr/bin/perl

use CGI;

$q = new CGI; 

$n = $n + 1; 

print $q->header(-type=>'text/plain'), 
      "Counter is: ", $n;

This is where the similarity ends.

We will see later that this "global memory" has a drawback.

To compensate for that we can use session tracking.

And then the difference between the two approaches becomes even more striking.

But more about this later.

The Chat Server

We'll introduce the problem in class and sketch a few solutions to it.

Then we will discuss one such solution in detail.


Last updated: Oct 18, 2002 by Adrian German for A348/A548