home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)Counter.java 1.42 97/05/22
- *
- * Copyright (c) 1996-1997 Sun Microsystems, Inc. All Rights Reserved.
- *
- * This software is the confidential and proprietary information of Sun
- * Microsystems, Inc. ("Confidential Information"). You shall not
- * disclose such Confidential Information and shall use it only in
- * accordance with the terms of the license agreement you entered into
- * with Sun.
- *
- * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
- * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
- * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
- * THIS SOFTWARE OR ITS DERIVATIVES.
- *
- * CopyrightVersion 1.0
- */
- import java.io.*;
- import java.util.*;
-
- import javax.servlet.*;
- import javax.servlet.http.*;
-
- import sun.servlet.http.Cookie;
-
-
- /**
- * Simple servlet to demonstrate the "Cookie" API. It uses a cookie to
- * serve as a counter that increments each time this web page is visited
- * during a user session. That counter, along with some other data, is
- * shown on an HTML page dynamically generated by this servlet.
- *
- * <P> Of course, other kinds of data can be stored using cookies. You
- * should look at the privacy and security guidelines in RFC 2109 before
- * you start to use cookies, and be clear to your customers what value
- * your cookies are providing to them.
- *
- * @version 1.42
- * @author David Brownell
- * @author Pavani Diwanji
- */
- public
- class Counter extends HttpServlet {
-
- //
- // Name of the main cookie saved by this servlet.
- //
- private static final String counterName = "counter";
-
- //
- // Default initial value of session cookies maintained by counter
- // servlets. May be overriden by an instance's init parameter.
- //
- static final int defaultInitialValue = 10;
-
- //
- // Actual initial value used by this servlet instance. There could
- // be several such instances, for different parts of the web site's
- // URL namespace, with different initial values.
- //
- // User agents maintain "live" counter values in cookies which are
- // presented with requests, and the servlet increments such values
- // in its responses.
- //
- private int initialValue;
-
-
-
- /**
- * Initializes the servlet. Session counters normally start at ten,
- * but that may be overridden by providing an initialization parameter
- * named "initial" with a value which is a decimal number. This lets
- * different "counter" servlets have different initial values, as well
- * as letting different user sessions have different actual values.
- */
- public void init(ServletConfig conf) throws ServletException {
- String s;
-
- super.init(conf);
-
- if ((s = getInitParameter ("initial")) == null)
- initialValue = defaultInitialValue;
- else {
- try {
- initialValue = Integer.parseInt (s);
- } catch (NumberFormatException e) {
- initialValue = defaultInitialValue;
- log ("** Non-numeric format for 'initial' parameter: " + s);
- }
- }
- }
-
-
- /**
- * Handles a request. It does this by updating a per-request "counter"
- * cookie from the request, and storing it via the response. Output of
- * the servlet is a simple web page showing the original value of the
- * session's counter, and some other data.
- */
- protected void doGet (HttpServletRequest req, HttpServletResponse res)
- throws ServletException, IOException
- {
- int counter = initialValue;
- Cookie cookies [], c = null;
- boolean hadCookies = false, hadCounter = false;
-
- //
- // We do all the cookie work before we start writing output,
- // since once we start writing data the headers (with or
- // without cookies) can get flushed at any time.
- //
- if ((cookies = Cookie.getCookies (req)) != null) {
- hadCookies = true;
-
- for (int i = 0; i < cookies.length; i++) {
- if (cookies [i].getName ().equals (counterName)) {
- try {
-
- // clone this cookie to keep using the browser's
- // version of the cookie protocol
-
- c = (Cookie) cookies [i].clone ();
- counter = Integer.parseInt (c.getValue ());
- c.setValue (Integer.toString (counter + 1));
- hadCounter = true;
-
- } catch (NumberFormatException e) {
- // should never happen ...
- c = null;
- }
- break;
- }
- }
- }
-
- //
- // Always save a "counter" cookie, taking care to set the
- // attributes that weren't settable by cloning the original.
- //
- if (c == null)
- c = new Cookie (counterName, Integer.toString (counter));
- c.setComment ("Supports Cookie Counter Demo Servlet");
- // c.setMaxAge (2 * 24 * 60 * 60); // 2 days
- // c.setPath ("/");
- c.saveCookie (res);
-
- if (false) {
- // add a new cookie, discarded on browser exit, to see
- // how multiple cookies are dealt with
- c = new Cookie (
- "gensym-" + (System.currentTimeMillis () & 0x0ff),
- new Date().toString ());
- c.setComment ("Show multi-cookie support");
- c.saveCookie (res);
- }
-
-
-
- //
- // TRY THIS:
- //
- // (A) Design a simple form for letting people create new cookies.
- // Generate that form in the HTML below. Use the POST action, and
- // create the new cookie before generating output below.
- //
- // (B) Do something similar for letting users delete one or more
- // of the cookies reported by the user agent ... including the
- // counter itself, as one way to reinitialize a session!
- //
- // (C) Offer form controls over cookies' paths and maximum ages.
- //
- // (D) Experiment to see how different web browsers handle version
- // zero cookies. Which features are handled inconsistently?
- //
- // (E) See how this page reacts to HTTP's "HEAD" methods.
- //
- // (F) Normally, pages used to set cookies will not be cached.
- // This will probably be true of most dynamically generated web
- // content. Are there other pages in your website which should
- // not be widely cached by proxies and browsers? Why?
- //
-
-
-
- //
- // Generate the response message ... an HTML page that shows all
- // cookies, their values, and any attributes, plus some random
- // data about the session that may be interesting. We buffer the
- // whole response so that HTTP keepalive can be used.
- //
- ByteArrayOutputStream bytes;
- PrintStream out;
-
- bytes = new ByteArrayOutputStream (4096);
- out = new PrintStream (bytes);
-
- out.println ("<HTML><HEAD>");
- out.println ("<TITLE>Cookie Counter</TITLE>");
- out.println ("</HEAD><BODY BGCOLOR=#eeeeff>");
- out.println ("<CENTER><H1>Cookie Counter</H1></CENTER>");
-
- if (hadCounter) {
- out.println ("<CENTER>");
- out.println ("<P> <em><b>Your session's counter was ");
- out.println (counter);
- out.println (" before you visited this page.</b></em>");
- out.println ("<P> The counter has been incremented.");
- out.println ("</CENTER>");
- } else {
- out.println ("<P> You presented no session cookie. A new");
- out.println ("cookie was created, with an initial counter");
- out.println ("holding the value " + counter + ".");
- }
-
-
- if (hadCookies) {
- out.println ("<P> You presented these cookies: <OL>");
- for (int i = 0; i < cookies.length; i++) {
- String temp;
-
- out.println ("<LI> Name = ");
- out.println (cookies [i].getName ());
- out.println (", Value = ");
- out.println (cookies [i].getValue ());
-
- //
- // IETF standard cookies expose these attributes, but
- // the original (and still most common) style cookies
- // hide this data on the client side.
- //
- if ((temp = cookies [i].getDomain ()) != null) {
- out.println (", Domain = ");
- out.println (cookies [i].getDomain ());
- }
- if ((temp = cookies [i].getPath ()) != null) {
- out.println (", Path = ");
- out.println (cookies [i].getPath ());
- }
- }
- out.println ("</OL>");
- }
-
-
- out.println ("<P> Watch the value of the counter change as you");
- out.println ("reload this page! The counter is updated by the");
- out.println ("servlet which dynamically generates this web page.");
-
- out.println ("<P> Try comparing how different browsers work with");
- out.println ("cookies set using these two URLs on this server: ");
- out.println ("<a href=/counter.html>/counter.html</a>, and");
- out.println ("<a href=/servlet/Counter>/servlet/Counter</a>.");
- out.println ("These URLs refer to different 'counter' servlets,");
- out.println ("which initialize their counts to different values.");
-
-
- String temp = req.getHeader ("User-Agent");
- out.println ("<P> Your browser is <em>"
- + ((temp != null) ? temp : "not known!") + "</em>.");
-
- // XXX
- // This time printing crashes IIS!!!!!
-
- /*
- out.println ("<P>The cookie server's time is now <em>"
- + new Date () + ".</em>");
- */
-
- out.println ("</BODY></HTML>");
- out.flush ();
-
-
- //
- // Now that we've buffered up the entire message: write all our
- // header fields, then the body. We buffered it up so we can set
- // content length ... ensuring we can use connection keep-alive,
- // for the best networking performance.
- //
- // With HTTP/1.1 clients guaranteed, we could set the headers
- // and just write to the output stream (using chunked encoding)
- // with no worries about preventing keep-alive.
- //
-
- res.setContentType("text/html"); // ;charset=us-ascii
- res.setContentLength (bytes.size ());
- // ... Last-Modified: right now!
-
- bytes.writeTo (res.getOutputStream ());
- }
-
- /**
- * Describes what this servlet does.
- */
- public String getServletInfo() {
- return "Demonstrates the 'Cookie' API for user sessions";
- }
- }
-