|
Spring Semester 2003 |
javax.servlet vs. CGI.pm
this and this() and the special rules that apply to the second
If you know Java you also understand:
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: java.awt.Frame object
user too
paint when doing graphics
paint gives you access to a graphics context
protected is like private, but
allowing inheritance of the variable or method. Here's the output of compiling and running the program above:
Can you explain it?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%
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:
javax.servlet
javax.servlet.http
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:
javax.servlet.Servlet interface
javax.servlet.GenericServlet class, and
javax.servlet.http.HttpServlet class
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:
And we check it fromburrowww.cs.indiana.edu% javac One.java burrowww.cs.indiana.edu%
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,
service() method,
ServletRequest and ServletResponse objects to it.
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.