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.