|
CSCI A348/548
|
The Java Servlet API provides a standard way to extend the
functionality of any kind of server that uses a protocol based
on requests and responses.
Servlets are used primarily with web servers, where
they provide Java-based replacement for CGI scripts.
In other words, on a web server that supports servlets (and there
are many), you can use a Java servlet to create dynamic web content
in much the same way you currently use a CGI script.
Servlets have many advantages over CGI scripts, however:
When a client makes a request involving a servlet, the server loads and executes the appropriate Java classes. Those classes generate content, and the server sends the content back to the client. In most cases, the client is a web browser, the server is a web server, and the servlet returns standard HTML. On the server side, however, there is one important difference: persistence.
Note
however that persistence is used here to mean
"enduring between invocations," and not "written
to permanent storage," as it is sometimes used.
Instead
of shutting down at the end of each request,the servlet can
remain loaded, ready to handle subsequent requests.
The request processing time for a servlet can vary, but it is typically quite fast when compared with a similar CGI program. The real advantage of a servlet, however, is that you incur most of the startup overhead only once.
When a servlet loads, its init() method is called.
You can use init() to create I/O intensive resources,
such as database connections, for use across multiple invocations.
If you have a high-traffic site, the performance benefits can be
quite dramatic. Instead of putting up and tearing down a hundred
thousand database connections, the server needs to create a
connection only once. The servlet's destroy()
method can clean up resources when the server shuts down.
Because servlets are persistent, you can actually remove a lot
of filesystem (and/or database) accesses altogether. For example
to implement a page counter, you can simply store a number in a
static variable rather than consulting a file (or
a database) for every request. Using this technique, you need to
read and write to the disk only occasionally to preserve state.
Since a servlet remains active, it can perform other tasks when it is not servicing client requests, such as running a background processing thread (where clients connect to the servlet to view the result) or even acting as an RMI host, enabling a single servlet to handle connections from multiple types of clients. For example, if you write an order processing servlet, it can accept transactions from both an HTML form and an applet using RMI.
Servlet Basics
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
burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman
burrowww.cs.indiana.edu% cd $myServlets
burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/jakarta-tomcat/webapps/examples/WEB-INF/classes
burrowww.cs.indiana.edu% cat L19BasicServlet.java
import javax.servlet.*;
import java.io.*;
public class L19BasicServlet extends GenericServlet {
public void service(ServletRequest req,
ServletResponse resp) throws ServletException,
IOException {
resp.setContentType("text/plain");
PrintWriter out = resp.getWriter();
out.println("Hello, this is L19.");
}
}
We compile it:
And we check it fromburrowww.cs.indiana.edu% javac L19BasicServlet.java burrowww.cs.indiana.edu% ls -l L19Basi* -rw-r--r-- 1 dgerman students 671 Oct 31 00:19 L19BasicServlet.class -rw-r--r-- 1 dgerman students 414 Oct 30 22:58 L19BasicServlet.java -rw-r--r-- 1 dgerman students 398 Oct 30 22:53 L19BasicServlet.java~ burrowww.cs.indiana.edu%
http://burrowww.cs.indiana.edu:12xxx/examples/servlet/L19BasicServlet
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 first servlet we develop is a very generic and simple one.
burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/jakarta-tomcat/webapps/examples/WEB-INF/classes
burrowww.cs.indiana.edu% cat L19_S1.java
import javax.servlet.*;
import java.io.*;
public class L19_S1 extends GenericServlet {
public void service(ServletRequest req, ServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/plain");
resp.getWriter().println("Hello... L19_S1 here!");
}
}
burrowww.cs.indiana.edu% javac L19_S1.java
burrowww.cs.indiana.edu%
2. The second
servlet we develop is an HTTP Servlet, a more specific one.
burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/jakarta-tomcat/webapps/examples/WEB-INF/classes
burrowww.cs.indiana.edu% ls -ld L19_S2.java
-rw-r--r-- 1 dgerman students 467 Oct 31 00:42 L19_S2.java
burrowww.cs.indiana.edu% cat L19_S2.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class L19_S2 extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
resp.getWriter().println(
"<html><head><title>L19_S2</title></head><body bgcolor=white>"
+ "HttpServlet replying to GET with: L19_S2 here!</body></html>"
);
}
}
burrowww.cs.indiana.edu% javac L19_S2.java
burrowww.cs.indiana.edu%
3. The third
servlet we develop is processing a form request.
burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/jakarta-tomcat/webapps/examples/WEB-INF/classes
burrowww.cs.indiana.edu% ls -ld L19_S3.java
-rw-r--r-- 1 dgerman students 964 Oct 31 00:48 L19_S3.java
burrowww.cs.indiana.edu% cat L19_S3.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class L19_S3 extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
resp.getWriter().println(
"<html><head><title>L19_S3 GET</title></head><body bgcolor=white>"
+ "<form method=POST action=/examples/servlet/L19_S3>Type your name here: "
+ "<input type=text name=namefield 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("namefield")
+ "</font>!</h1></body></html>"
);
}
}
burrowww.cs.indiana.edu% javac L19_S3.java
burrowww.cs.indiana.edu%
In class we will compare these with CGI implementations. The Chat Server
We'll introduce the problem in class and sketch a few solutions to it.
On Thursday we will discuss one such solution in detail.
A348/A548.