Spring Semester 2003


Lecture Notes Twenty: Introduction to Server-Side Java

This is your introduction to server-side Java this semester and the best preparation for Homework Assignments Five and Six (the last two for this semester, they will be posted tonight).

This review has four sections:

  1. Basic Java
  2. Java Applets
  3. Java Servlets
  4. Java Server Pages
ONE: Basic Java

Java is an object oriented language. In Java classes define the structure of objects, which are collections of variables and methods (procedures) bundled together. Variables and methods that are part of the blueprint of the objects defined by a class are called instance members.

The program below defines a class of objects called Point. Such an object contains two instance variables (x and y) is able to describe itself as a String, and knows how to calculate the Euclidean distance from it to another point.

The keyword this is how a Point object can refer to itself.

class One {
    public static void main(String[] args) {
	Point a, b; 
	a = new Point(-1, 3); 
	b = new Point(2, -1); 
        double distance = a.distanceTo(b); 
	System.out.println 
	    (
	     
	     "The distance from " + 
	     a + " to " + b + " is " + distance + 
	     
	     "\nThe distance from " + b + " to " + a + 
	     " should be the same, i.e. " + b.distanceTo(a)
	     
	     ); 

    }
}

class Point {
    double x, y; 
    Point (int x, int y) {
	this.x = x; this.y = y; 
    }
    public String toString() {
	return "(" + x + ", " + y + ")"; 
    }
    public double distanceTo (Point other) {
	return Math.sqrt(
			 (this.x - other.x) * (this.x - other.x) + 
			 (this.y - other.y) * (this.y - other.y)
                        ); 
    }
}
EXERCISE ONE

Describe a class of Fraction objects. Model only as much as you need to. A Fraction is also a pair of two numbers (two ints). A Fraction object, however, will have a different representation as a String (i.e., instead of showing it as (3, 5) we'll be showing it as 3/5, as expected). A Fraction should be able to calculate its distance to another Fraction (which is simply the arithmetical difference between the two Fractions, taken in absolute value).

TWO: Java Applets

Java allows descriptions to be built in stages.

frilled.cs.indiana.edu%cat Ionesco.java
class Horse {
    int numberOfLegs = 4; 
    void talk() {
	System.out.println("Howdy!"); 
    }
} 

class Unicorn extends Horse { 
    Horn h;   
} 

class Ionesco {
    public static void main(String[] args) {
	Horse a; 
	Unicorn b; 
	a = new Horse(); 
	b = new Unicorn(); 
	Horse c = new Unicorn(); 	
        /* 
	  Unicorn d = new Horse(); // this is incorrect
	 */ 
	a.talk(); 
	b.talk(); 
	c.talk(); 

    } 
} 

class Horn { 
    // whatever... 
} 

frilled.cs.indiana.edu%javac Ionesco.java
frilled.cs.indiana.edu%java Ionesco
Howdy!
Howdy!
Howdy!
frilled.cs.indiana.edu%
This is called inheritance. (You have also seen polymorphism above). The class extension mechanism is basically similar to computing the set union of features (variables and methods the object is made of). One can redefine a method in the extended class, obtaining the following effect:
frilled.cs.indiana.edu%cat Ionesco.java
class Horse {
    int numberOfLegs = 4; 
    void talk() {
	System.out.println("Howdy!"); 
    }
} 

class Unicorn extends Horse { 
    Horn h;   
    void talk() {
	System.out.println("Bonjour!"); 
    }
} 

class Ionesco {
    public static void main(String[] args) {
	Horse a; 
	Unicorn b; 
	a = new Horse(); 
	b = new Unicorn(); 
	Horse c = new Unicorn(); 	
        /* 
	  Unicorn d = new Horse(); // this is incorrect
	 */ 
	a.talk(); 
	b.talk(); 
	c.talk(); 

    } 
} 

class Horn { 
    // whatever... 
} 

frilled.cs.indiana.edu%javac Ionesco.java
frilled.cs.indiana.edu%java Ionesco
Howdy!
Bonjour!
Bonjour!
frilled.cs.indiana.edu%
To summarize, it's the type of the object not that of the variable that counts.

How does this relate to applets?

Well, it's quite simple:

If Horses can talk(), Applets are more specific: they paint using a graphical context which they receive as a parameter. Here's an applet to which we have taught a little French (as in the case of the Unicorn, above). Notice how paint gets invoked, and when.

frilled.cs.indiana.edu%cat Two.java
import java.awt.*; 
import java.applet.*; 

public class Two extends Applet {
    int count = 0; 
    public void paint(Graphics g) {
	g.setColor(Color.red); 
	g.fillOval(30, 30, 100, 100); 
	g.setColor(Color.yellow);
	g.fillOval(50, 80, 60, 60); 
	System.out.println("paint() has just been called..."); 
        this.count += 1; 
	System.out.println("     it has been called " + 
			   count + " times thus far."); 
    }  

}
frilled.cs.indiana.edu%javac Two.java
frilled.cs.indiana.edu%cat Two.html
<html>
  <head>
    <title>An Applet</title>
  </head>
  <body bgcolor=white>
    <applet code="Two.class" width=300 height=300>

    </applet>    
  </body>
</html>frilled.cs.indiana.edu%appletviewer Two.html
paint() has just been called...
     it has been called 1 times thus far.
paint() has just been called...
     it has been called 2 times thus far.
paint() has just been called...
     it has been called 3 times thus far.
paint() has just been called...
     it has been called 4 times thus far.
frilled.cs.indiana.edu%

EXERCISE TWO

  1. Define a context stupendous in your Tomcat (server.xml).
  2. Install this applet in it (keep the same names for your files).
  3. Write another applet in which you draw a different picture.
Use this link to java.awt.Graphics for more specific information:

http://java.sun.com/products/jdk/1.2/docs/api/java/awt/Graphics.html
Finally explain what happens here and why and how this is related to applets:
frilled.cs.indiana.edu%cat Ionesco.java
class Horse {
    int numberOfLegs = 4; 
    void greet() { talk(); }
    void talk() {
	System.out.println("Howdy!"); 
    }
} 

class Unicorn extends Horse { 
    Horn h;   
    void talk() {
	System.out.println("Bonjour!"); 
    }
} 

class Ionesco {
    public static void main(String[] args) {
	Horse a = new Unicorn(); 	
	a.greet(); 

    } 
} 

class Horn { } 

frilled.cs.indiana.edu%javac Ionesco.java
frilled.cs.indiana.edu%java Ionesco
Bonjour!
frilled.cs.indiana.edu%

THREE: Java Servlets

The mechanism for defining servlets is similar to those for defining applets. Your servlets are basically extensions of the classes that the javax packages define. That allows your programs to have their methods called when needed. A Unicorn is told to greet the audience, and because it is a Horse it will understand what it needs to do. But it does it in its own way. Same for your servlets.

Unlike Applets, we have two options here:

  1. we could extend a very basic class, called GenericServlet, or
  2. we could extend an extension of GenericServlet called HttpServlet
These two classes are in different packages, but that doesn't matter. Check on your Tomcat for more information. Suffice it to say that the talk() for a GenericServlet is called service(), while an HttpServlet talks in two different ways: doGet(), or doPost(), depending on how it has been called. HttpServlets are Horses that know HTTP. (On the Internet nobody knows that you're a Horse).

Here's a template for an HttpServlet (place it in the context created earlier):

burrowww.cs.indiana.edu% cd $CATALINA_HOME
burrowww.cs.indiana.edu% cd webapps
burrowww.cs.indiana.edu% cd stupendous
burrowww.cs.indiana.edu% cd WE*
burrowww.cs.indiana.edu% cd classes
burrowww.cs.indiana.edu% pico Template.java 
burrowww.cs.indiana.edu% cat Template.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*; 

public class Template extends HttpServlet {

  public void doGet(HttpServletRequest request, 
                    HttpServletResponse response) 
              throws ServletException, IOException {

    // Use "request" to read incoming HTTP headers
    // (e.g., cookies) and read query data from HTML forms

    // Use "response" to specify the HTTP response status
    // code and headers (e.g., the content type, cookies)

    PrintWriter out = response.getWriter(); 
    // Use "out" to send content to browser 

  }

}
burrowww.cs.indiana.edu% javac Template.java
burrowww.cs.indiana.edu% 

Here's HelloFive from Lab Two as a servlet:

burrowww.cs.indiana.edu% pwd
/u/dgerman/tomcat/jakarta-tomcat-4.0.3/webapps/stupendous/WEB-INF/classes
burrowww.cs.indiana.edu% cat HelloFive.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*; 

public class HelloFive extends HttpServlet {
    
    String[] images = { "lh08.gif", 
                        "lh07.gif", 
                        "lh09.gif", 
                        "lh01.gif"
                      }; 
    
    public void doGet(HttpServletRequest request, 
                      HttpServletResponse response) 
                throws ServletException, IOException {
        
        PrintWriter out = response.getWriter(); 
        
        int index = (int) (Math.random() * images.length); 
        
        response.setContentType("text/html"); 

        out.println(

"<html>" + 
"  <head><title>My First Servlet</title></head>" + 
"  <body bgcolor=white>" + 
"    The image below has index " + index + "<p>" + 
"    <img src=\"http://www.cs.indiana.edu/classes/a113-dger/left.gif\"> " + 
"Click <a href=\"http://burrowww.cs.indiana.edu:36400/stupendous/servle" + 
"t/HelloFive\">here</a> for a new random image <p> " + 
"    <img src=\"http://www.cs.indiana.edu/dept/img/" + 
     images[index] + 
"\"> " + 
"  </body>" + 
"</html>" 

        ); 
        
    }
    
}
burrowww.cs.indiana.edu% javac HelloFive.java
burrowww.cs.indiana.edu% 

You see then that we can use an instance variable for the array of images.

EXERCISE THREE

Write a servlet that counts and reports the number of times it has been accessed. It should keep the counter in an instance variable and increment it every time it's accessed. (Don't worry about it having to be synchronized). We'll use this below, in a slightly modified form.

Let's write a servlet that scrolls through the images, instead of giving us a random image every time.

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

public class Scroll extends HttpServlet {
    
    String[] images = { "lh08.gif", 
                        "lh07.gif", 
                        "lh09.gif", 
                        "lh01.gif"
                      }; 
    
    int index = 0; 

    public void doGet(HttpServletRequest request, 
                      HttpServletResponse response) 
                throws ServletException, IOException {
        
        PrintWriter out = response.getWriter(); 
        
        String me = request.getContextPath() + request.getServletPath(); 

        String queryString = request.getQueryString(); 

        if (queryString == null) { index = 0; } 
        else if (queryString.equalsIgnoreCase("up")) { 
            index = (index + 1) % images.length; 
        } else if (queryString.equalsIgnoreCase("down")) { 
            index = (index + 3) % images.length; 
        } else {

        }

        response.setContentType("text/html"); 

        out.println(

"<html>" + 
"  <head><title>My Second Servlet</title></head>" + 
"  <body bgcolor=white><table>" + 
"    <tr><td><a href=\"" + me + "?down\">Down</a> <td>Image" + index + 
"    <td><a href=\"" + me + "?up\">Up</a> <p>" + 
"    <tr><td colspan=3><img src=\"http://www.cs.indiana.edu/dept/img/" + 
     images[index] + 
"\"> " + 
"  </table></body>" + 
"</html>" 

        ); 
        
    }
    
}
This example also shows you how you can retrieve the query string, the context path, and the servlet path, the way we used to do in CGI. The circular buffer implementation is straightforward, I think.

EXERCISE FOUR

Write a servlet that counts and reports the number of times it has been accessed. It should keep the counter in a session variable, so that the counter is specific to the user. We will be implementing something similar below, so keep reading.

An HttpSession variable can be obtained from the request. Sessions are really hashtables, with Strings as keys and Objects as values. For complete information please check

tomcat-docs/servletapi/javax/servlet/http/HttpSession.html
on your Tomcat. Because values are stored as Objects casting is needed during retrieval.

Take a look at the next example:

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

public class Last extends HttpServlet {
    
    public void doGet(HttpServletRequest request, 
                      HttpServletResponse response) 
                throws ServletException, IOException {

        PrintWriter out = response.getWriter(); 

        String me = request.getContextPath() + request.getServletPath(); 

        String whichWay = request.getParameter("what"); 

        int index; 

        HttpSession session = request.getSession(); 

        String count = (String) session.getAttribute("count");             

        index = (count == null) ? 0 : Integer.parseInt(count); 

        if (whichWay == null) { 

        } else {
            // the empty string is different from null! 

            if (whichWay.equals("up")) {
                index += 1; 
            } else if (whichWay.equals("down")) {
                index -= 1; 
            } else {
                // something went wrong 
            }

            session.setAttribute("count", index + ""); 

        }

        response.setContentType("text/html"); 

        out.println(

"<html>" + 
"  <head><title>My Last Servlet</title></head>" + 
"  <body bgcolor=white><table>" + 

"    <form method=\"GET\" action=\"" + me + "\"> " + 

"      The counter is currently: " + index + " <p> " + 

"      Please choose an action: <select name=\"what\"> " + 
"        <option value=\"nothing\"> Click Me! " + 
"        <option value=\"up\"> Up " + 
"        <option value=\"down\"> Down " + 
"      </select> <p> " + 

"      Then press <input type=\"submit\" value=\"Proceed\"> " + 

"    </form>"  + 

"  </body> " + 
"</html>" 

        ); 

    }
    
} 
You have now also seen how one can access form data from a servlet.

FOUR: Java Server Pages

One can write a servlet in a slightly different (PHP-like) manner. Here are the rules:

  1. Turn into a scriptlet (<% %>) what you do in doGet.
  2. Use expressions (<%= %>) for simple printing jobs in plain HTML.
  3. Use declarations (<%! %>) for any instance variables you want to declare.
  4. Remember that request, response and session are already declared for you.
We will add a few more rules as we go through the examples below.

With these rules we obtain the following equivalents for the three servlets developed above.

(Notice that I place them all next to the applets and .html files.)

Here's what HelloFive becomes:

<%!    
    String[] images = { "lh08.gif", 
                        "lh07.gif", 
                        "lh09.gif", 
                        "lh01.gif"
                      }; 

 %>
    
 <%

    int index = (int) (Math.random() * images.length); 

  %> 

<html> 
  <head><title>My First JSP</title></head>
  <body bgcolor=white>
    The image below has index <%=index%> <p>
    <img src="http://www.cs.indiana.edu/classes/a113-dger/left.gif"> Click <a 
   href=
  "http://burrowww.cs.indiana.edu:36400/stupendous/servlet/HelloFive\">here</a>
   for a new random image <p>   
    <img src="http://www.cs.indiana.edu/dept/img/<%=images[index]%>"> 

  </body>
</html>
You will notice that the scriptlet is actually much smaller than anticipated. Why?

Here's the second servlet turned into a JSP page (Scroll.jsp)

<%!
    
    String[] images = { "lh08.gif", 
                        "lh07.gif", 
                        "lh09.gif", 
                        "lh01.gif"
                      }; 
    
    int index = 0; 

 %>

<%

        String me = request.getContextPath() + request.getServletPath(); 

        String queryString = request.getQueryString(); 

        if (queryString == null) { index = 0; } 
        else if (queryString.equalsIgnoreCase("up")) { 
            index = (index + 1) % images.length; 
        } else if (queryString.equalsIgnoreCase("down")) { 
            index = (index + 3) % images.length; 
        } else {

        }

 %>

<html> 
  <head><title>My Second JSP</title></head> 
  <body bgcolor=white><table> 
    <tr><td><a href="<%=me%>?down">Down</a> 
        <td>Image<%=index%>
        <td><a href="<%=me%>?up">Up</a> <p>  
    <tr><td colspan=3>
          <img src="http://www.cs.indiana.edu/dept/img/<%=images[index]%>"> 
  </table></body>
</html>

I hope that you realize this that the current picture is a global notion here.

Here's the last servlet easily transformed into a JSP (Last.jsp).

<%
	String me = request.getContextPath() + request.getServletPath(); 

        String whichWay = request.getParameter("what"); 

        int index; 
	
	String count = (String) session.getAttribute("count");             
	
	index = (count == null) ? 0 : Integer.parseInt(count); 
	
        if (whichWay == null) { 

	} else {
	    // the empty string is different from null!

	    if (whichWay.equals("up")) {
		index += 1; 
	    } else if (whichWay.equals("down")) {
		index -= 1; 
	    } else {
		// something went wrong 
	    }

            session.setAttribute("count", index + ""); 

	}
 %>

<html>
  <head><title>My Last JSP</title></head>
  <body bgcolor=white><table>

    <form method="GET" action="<%=me%>"> 

      The counter is currently: <%=index%> <p> 

      Please choose an action: <select name="what"> 
        <option value="nothing"> Click Me! 
        <option value="up"> Up 
        <option value="down"> Down 
      </select> <p> 

      Then press <input type="submit" value="Proceed"> 

    </form> 

  </body> 
</html>
EXERCISE FIVE

Turn the servlets developed at Exercise Three and Four into .jsp pages.

These on-line notes may be modified slightly during the week.


Last updated: Mar 31, 2003 by Adrian German for A348/A548