![]() |
![]() Spring Semester 2003 |
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:
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) ); } }
Describe a class of Fraction
objects. Model only as much as you need to. A
Fraction
is also a pair of two numbers (two int
s). 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 Fraction
s, taken in
absolute value).
TWO: Java Applets
Java allows descriptions to be built in stages.
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; } 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%
To summarize, it's the type of the object not that of the variable that counts.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%
How does this relate to applets?
Well, it's quite simple:
Applet
s are Horse
s (as defined in java.applet.Applet
)
Unicorn
s (and you define their talk()
)
Horse
s can talk()
, Applet
s 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
stupendous
in your Tomcat (server.xml
).
java.awt.Graphics
for more specific information:
Finally explain what happens here and why and how this is related to applets:http://java.sun.com/products/jdk/1.2/docs/api/java/awt/Graphics.html
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 Applet
s, we have two options here:
GenericServlet
, or
GenericServlet
called
HttpServlet
tomcat-docs/servletapi/javax/servlet/GenericServlet.html
tomcat-docs/servletapi/javax/servlet/http/HttpServlet.html
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.
HttpServlet
s are Horse
s 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.
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.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>" ); } }
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 String
s as keys and Object
s as values. For
complete information please check
on your Tomcat. Because values are stored astomcat-docs/servletapi/javax/servlet/http/HttpSession.html
Object
s casting is needed during retrieval. Take a look at the next example:
You have now also seen how one can access form data from a servlet.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>" ); } }
FOUR: Java Server Pages
One can write a servlet in a slightly different (PHP-like) manner. Here are the rules:
<% %>
) what you do in doGet
.
<%= %>
) for simple printing jobs in plain HTML.
<%! %>
) for any instance variables you want to declare.
request
, response
and session
are already declared for you.
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:
You will notice that the scriptlet is actually much smaller than anticipated. Why?<%! 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>
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>
Turn the servlets developed at Exercise Three and Four into .jsp
pages.
These on-line notes may be modified slightly during the week.