ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Web Server Java -- Servlets and JSP
Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11

Cookies

Problem:
You want the client (the browser) to remember some bit of information for you.



Solution:
Bake a cookie, and serve it to the client along with your response.

Discussion

Cookies were invented by Netscape as a debugging technique, but have since become ubiquitous: all modern browsers, including MSIE, and text browsers such as Lynx accept and store them. A cookie is, at heart, a small piece of text--a name and value pair--that the server side generates and sends to the client. The browser remembers them (nontransient cookies are stored to your hard disk; Netscape creates a file called cookies or cookies.txt, for example). The browser then sends them back to the server on any subsequent visit to a page from the same site. The Cookie class is part of the javax.servlet.http package, so any servlet implementation will include it. The constructor is passed a name and value, but there are other parameters you can set. Most important is the expiry time, which is in seconds from the time you first send it. The default is -1; if the value is negative, the cookie is not saved to disk; it becomes a "transient cookie" that exists only until the browser exits and is then forgotten. For cookies that are stored to disk, the expiry time is converted to a base of January 1, 1970, the beginning of Unix time and of the modern computing era.

When the browser visits a site that has sent it a cookie or cookies, it returns all of them as part of the HTTP headers. You retrieve them all (as an array) using the getCookies( ) method, and iterate through them looking for the one you want.

It has been said of Sun that when they copy something, they both improve upon it and give credit where credit's due in the name. Consider Microsoft ODBC and Java JDBC; Microsoft ASP and Java JSP. The same cannot be said of most large companies.

for (int i=0; i<mySiteCookies.length; i++) {
  Cookie c = mySiteCookies[i];
  if (c.getName( ).equals(name-you're-looking-for)) {
      someString = c.getValue( );
      break;
  }
}

Suppose you want the user to pick a favorite color for the servlet to use as the background color for pages from that point on. Let's use a name of prefs.bgcolor for the color-coding cookie. The main servlet is CookieServlet, which checks for the cookie. If it was not set previously, it jumps off to an HTML page, which will eventually return here via another servlet. On the other hand, if the color cookie was previously set, CookieServlet (shown in Example 18-5) displays the welcome page with the user's color set.


Example 18-5: CookieServlet.java

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
/** Simple Cookie-based Page Color Display servlet demo.
*/
public class CookieServlet extends HttpServlet {
  /** The preferences cookie name */
  protected final static String PREFS_BGCOLOR = "prefs.bgcolor";
  /** Where to go if we have not yet been customized. */
  protected final static String CUSTOMIZER = "/ColorCustomize.html";
  /** The user's chosen color, if any */
  protected String faveColor = null;
 
  public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
 
    // Go through all the cookies we have, looking for a faveColor.
    Cookie[] mySiteCookies = request.getCookies( );
    for (int i=0; i<mySiteCookies.length; i++) {
      Cookie c = mySiteCookies[i];
      if (c.getName( ).equals(PREFS_BGCOLOR)) {
        faveColor = c.getValue( );
        break;
      }
    }
 
    // if we did not find a faveColor in a cookie,
    // punt to customization servlet to bake one up for us.
    if (faveColor == null) {
      ServletContext sc = getServletContext( );
 
      // Requires Servlet API 2.1 or later!
      // RequestDispatcher rd =
      //  sc.getRequestDispatcher(CUSTOMIZER");
      //rd.forward(request, response);
 
      // Do it the old way
      response.sendRedirect(CUSTOMIZER);
    }
 
    // OK, we have a color, so we can do the page.
    PrintWriter out = response.getWriter( );
    response.setContentType("text/html");
 
    out.println("<html><title>A Custom-Colored Page</title>");
    out.print("<body bgcolor=\"");
    out.print(faveColor);
    out.println("\">");
    out.println("<P>Welcome! We hope you like your colored page!</P>");
    out.println("</body></html>");
    out.flush( );
  }
}


If the user has not yet set a color customization cookie, the CookieServlet passes control (by sending an HTTP redirect in the old API, or by use of a ServletDispatcher under the Servlet API 1.2 or later) to this HTML page.

<BODY BGCOLOR="pink">
<H1>Please choose a color</h2>
<FORM ACTION="/servlet/ColorCustServlet" METHOD=GET>
<SELECT NAME="color_name">
  <OPTION VALUE="green">Green</>
  <OPTION VALUE="white" SELECTED>White</>
  <OPTION VALUE="gray">Grey</>
</SELECT>
<INPUT TYPE="submit" VALUE="OK">
</FORM>

Finally, the HTML page will jump to the customization servlet (Example 18-6), which contains the code shown here to save the user's preference as a cookie, and then return to the CookieServlet by sending an HTTP "redirect," causing the browser to load the specified replacement page.


Example 18-6: ColorCustServlet.java

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
/** Color customization servlet */
public class ColorCustServlet extends HttpServlet {
 
  protected final static String DEFAULT_COLOR = "white";
  protected String faveColor = DEFAULT_COLOR;
 
  public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter( );
 
    String cand=request.getParameter("color_name");
    if (cand != null) {
      faveColor = cand;
      Cookie c = new Cookie(CookieServlet.PREFS_BGCOLOR, faveColor);
      c.setMaxAge(60*60*24*365);
      response.addCookie(c);
    }
    response.sendRedirect("/servlet/CookieServlet");
  }
}

Of course, there are issues to consider when using cookies. Some users disable cookies out of justifiable fear that web sites will use them for gathering more information than a person might want to have known. In this case, our servlet would keep coming back to the customization page. It should probably have a warning to the effect that "cookies must be enabled to view this site." Or you could use other techniques, such as session tracking (see Session Tracking).

And realistically, you probably want to keep more than one preference item for a user. If you let them set the screen background, you also need to set the text color, for example. It's probably better to keep the preferences in a database on the server side, and just set a token that identifies the user (possibly the database primary key). Even then, remember that cookies can be altered! See Program: CookieCutter for a program to allow modification of the cookies stored on your hard drive.

Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11

Next Pagearrow