Example Servlet
Example Servlet
Note that the book has an interesting history on the first documented "Hello World!" program. import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<HTML>"); out.println("<HEAD><TITLE>Hello World</TITLE></HEAD>"); out.println("<BODY>"); out.println("<BIG>Hello World</BIG>"); out.println("</BODY></HTML>"); } } Example 2.3: A servlet that knows to whom it's saying hello, modified to return quickly in response to HEAD requests This servlet uses the request's getMethod() method to improve performance by detecting HEAD requests in the doGet() method so that it can return early. import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Hello extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); String name = req.getParameter("name"); out.println("<HTML>"); out.println("<HEAD><TITLE>Hello, " + name + "</TITLE></HEAD>");
out.println("<BODY>"); out.println("Hello, " + name); out.println("</BODY></HTML>"); } public String getServletInfo() { return "A servlet that knows the name of the person to whom it's" + "saying hello"; } }
Example 3.1: A simple counter This servlet counts and displays the number of times it has been accessed since the last server reboot.
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<HTML>"); out.println("<HEAD><TITLE>Hello World</TITLE></HEAD>"); out.println("<BODY>"); out.println("<BIG>Hello World</BIG>"); out.println("</BODY></HTML>"); } } Example 3.2: A more holistic counter This servlet counts the times it has been accessed, the number of instances created by the server, and the total times all of them have been accessed. import java.io.*;
import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class HolisticCounter extends HttpServlet { static int classCount = 0; // shared by all instances int count = 0; // separate for each servlet static Hashtable instances = new Hashtable(); // also shared public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/plain"); PrintWriter out = res.getWriter(); count++; out.println("Since loading, this servlet instance has been accessed " + count + " times."); // Keep track of the instance count by putting a reference to this // instance in a Hashtable. Duplicate entries are ignored. // The size() method returns the number of unique instances stored. instances.put(this, this); out.println("There are currently " + instances.size() + " instances."); classCount++; out.println("Across all instances, this servlet class has been " + "accessed " + classCount + " times."); } } Example 3.3: A counter that reads init parameters This servlet counts and displays the number of times it has been accessed, and reads an init parameter to know what at what number to begin counting. import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class InitCounter extends HttpServlet { int count;
public void init() throws ServletException { String initial = getInitParameter("initial"); try { count = Integer.parseInt(initial); } catch (NumberFormatException e) { count = 0; } } public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/plain"); PrintWriter out = res.getWriter(); count++; out.println("Since loading (and with a possible initialization"); out.println("parameter figured in), this servlet has been accessed"); out.println(count + " times."); } } Example 3.4: A fully persistent counter This servlet counts and displays the number of times it has been accessed, and saves the count to a file in its destroy() method to make the count persistent. import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class InitDestroyCounter extends HttpServlet { int count; public void init() throws ServletException { // Try to load the initial count from our saved persistent state FileReader fileReader = null; BufferedReader bufferedReader = null; try { fileReader = new FileReader("InitDestroyCounter.initial"); bufferedReader = new BufferedReader(fileReader); String initial = bufferedReader.readLine(); count = Integer.parseInt(initial); return; } catch (FileNotFoundException ignored) { } // no saved state
catch (IOException ignored) { } // problem during read catch (NumberFormatException ignored) { } // corrupt saved state finally { // Make sure to close the file try { if (bufferedReader != null) { bufferedReader.close(); } } catch (IOException ignored) { } } // No luck with the saved state, check for an init parameter String initial = getInitParameter("initial"); try { count = Integer.parseInt(initial); return; } catch (NumberFormatException ignored) { } // null or non-integer value // Default to an initial count of "0" count = 0; } public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/plain"); PrintWriter out = res.getWriter(); count++; out.println("Since the beginning, this servlet has been accessed " + count + " times."); } public void destroy() { super.destroy(); // entirely optional saveState(); } public void saveState() { // Try to save the accumulated count FileWriter fileWriter = null; PrintWriter printWriter = null; try { fileWriter = new FileWriter("InitDestroyCounter.initial"); printWriter = new PrintWriter(fileWriter); printWriter.println(count);
return; } catch (IOException e) { // problem during write // Log the exception. See Chapter 5. } finally { // Make sure to close the file if (printWriter != null) { printWriter.close(); } } } } Example 3.7: On the hunt for primes This servlet searches for prime numbers above one quadrillion. The algorithm it uses couldn't be simpler: it selects odd-numbered candidates and attempts to divide them by every odd integer between 3 and their square root. If none of the integers evenly divides the candidate, it is declared prime. It's disabled to let the server's CPU handle important tasks. import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class PrimeSearcher extends HttpServlet implements Runnable { long lastprime = 0; // last prime found Date lastprimeModified = new Date(); // when it was found Thread searcher; // background search thread public void init() throws ServletException { searcher = new Thread(this); searcher.setPriority(Thread.MIN_PRIORITY); // be a good citizen searcher.start(); } public void run() { // QTTTBBBMMMTTTOOO long candidate = 1000000000000001L; // one quadrillion and one // Begin loop searching for primes while (true) { // search forever if (isPrime(candidate)) { lastprime = candidate; // new prime
lastprimeModified = new Date(); // new "prime time" } candidate += 2; // evens aren't prime
// Between candidates take a 0.2 second break. // Another way to be a good citizen with system resources. try { searcher.sleep(200); } catch (InterruptedException ignored) { } } } private static boolean isPrime(long candidate) { // Try dividing the number by all odd numbers between 3 and its sqrt long sqrt = (long) Math.sqrt(candidate); for (long i = 3; i <= sqrt; i += 2) { if (candidate % i == 0) return false; // found a factor } // Wasn't evenly divisible, so it's prime return true; } public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/plain"); PrintWriter out = res.getWriter(); if (lastprime == 0) { out.println("Still searching for first prime..."); } else { out.println("The last prime discovered was " + lastprime); out.println(" at " + lastprimeModified); } } public void destroy() { searcher.stop(); } } Example 3.10: A Guestbook using CacheHttpServlet This servlet shows how to take advantage of com.oreilly.servlet.CacheHttpServlet . Its a guestbook servlet that displays user-submitted comments. The servlet stores the user comments
in memory as a Vector of GuestbookEntry objects. There's another version of this servlet running off a database in Chapter 9, Database Connectivity. For now, to simulate reading from a slow database, the display loop has a half-second delay per entry. As the entry list gets longer, the rendering of the page gets slower. However, because the servlet extends CacheHttpServlet , the rendering only has to occur during the first GET request after a new comment is added. All later GET requests send the cached response. import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import com.oreilly.servlet.CacheHttpServlet; public class Guestbook extends CacheHttpServlet { private Vector entries = new Vector(); // User entry list private long lastModified = 0; // Time last entry was added // Display the current entries, then ask for a new entry public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); printHeader(out); printForm(out); printMessages(out); printFooter(out); } // Add a new entry, then dispatch back to doGet() public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { handleForm(req, res); doGet(req, res); } private void printHeader(PrintWriter out) throws ServletException { out.println("<HTML><HEAD><TITLE>Guestbook</TITLE></HEAD>"); out.println("<BODY>"); } private void printForm(PrintWriter out) throws ServletException { out.println("<FORM METHOD=POST>"); // posts to itself
out.println("<B>Please submit your feedback:</B><BR>"); out.println("Your name: <INPUT TYPE=TEXT NAME=name><BR>"); out.println("Your email: <INPUT TYPE=TEXT NAME=email><BR>"); out.println("Comment: <INPUT TYPE=TEXT SIZE=50 NAME=comment><BR>"); out.println("<INPUT TYPE=SUBMIT VALUE=\"Send Feedback\"><BR>"); out.println("</FORM>"); out.println("<HR>"); } private void printMessages(PrintWriter out) throws ServletException { String name, email, comment; Enumeration e = entries.elements(); while (e.hasMoreElements()) { GuestbookEntry entry = (GuestbookEntry) e.nextElement(); name = entry.name; if (name == null) name = "Unknown user"; email = entry.email; if (name == null) email = "Unknown email"; comment = entry.comment; if (comment == null) comment = "No comment"; out.println("<DL>"); out.println("<DT><B>" + name + "</B> (" + email + ") says"); out.println("<DD><PRE>" + comment + "</PRE>"); out.println("</DL>"); // Sleep for half a second to simulate a slow data source try { Thread.sleep(500); } catch (InterruptedException ignored) { } } } private void printFooter(PrintWriter out) throws ServletException { out.println("</BODY>"); } private void handleForm(HttpServletRequest req, HttpServletResponse res) { GuestbookEntry entry = new GuestbookEntry(); entry.name = req.getParameter("name"); entry.email = req.getParameter("email"); entry.comment = req.getParameter("comment"); entries.addElement(entry); // Make note we have a new last modified time
lastModified = System.currentTimeMillis(); } public long getLastModified(HttpServletRequest req) { return lastModified; } } class GuestbookEntry { public String name; public String email; public String comment; }