|
1. Overview of CookiesCookies are small bits of textual information that a Web server sends to a browser and that the browser returns unchanged when visiting the same Web site or domain later. By having the server read information it sent the client previously, the site can provide visitors with a number of conveniences:
Or, a site that ought to have much higher security standards might let users skip user name and passwords via cookies. For example, some of the big on-line bookstores use cookies to remember users, and let you order without reentering much of your personal information. However, they don't actually display the full credit card number, and only let you send books to an address that was entered when you did enter the credit card in full or use the username and password. As a result, someone using the person's computer (or stealing their cookie file) could do no more harm than sending a big book order to the credit card owner's address, where it could be refused. However, smaller companies might not be so careful, and access to someone's computer or cookie file could result in loss of valuable personal information. Even worse, incompetent sites might embed credit card or other sensitive information directly in the cookies themselves, rather than using innocuous identifiers which are only linked to real users on the server. The point of all this is twofold. First, due to real and perceived privacy problems, some users turn off cookies. So, even when you use cookies to give added value to a site, your site shouldn't depend on them. Second, as the author of servlets that use cookies, you should be careful not to trust cookies for particularly sensitive information, since this would open the user up to risks if somebody accessed their computer or cookie files. 2. The Servlet Cookie APITo send cookies to the client, a servlet would create one or more cookies with the appropriate names and values vianew Cookie(name, value) (section 2.1), set any
desired optional attributes via cookie.setXxx (section 2.2), and
add the cookies to the response headers via
response.addCookie(cookie) (section 2.3). To read incoming cookies,
call request.getCookies() , which returns an array of
Cookie objects. In most cases, you loop down this array until you
find the one whose name (getName ) matches the name you have in
mind, then call getValue on that Cookie to see the
value associated with that name. This is discussed in section 2.4.
2.1 Creating CookiesA Cookie is created by calling theCookie constructor, which takes two
strings: the cookie name and the cookie value. Neither the name nor the value
should contain whitespace or any of: [ ] ( ) = , " / ? @ : ; 2.2 Reading and Specifying Cookie AttributesBefore adding the cookie to the outgoing headers, you can look up or set attributes of the cookie. Here's a summary:
2.3 Placing Cookies in the Response HeadersThe cookie is added to theSet-Cookie response header by means of the addCookie
method of HttpServletResponse . Here's an example: Cookie userCookie = new Cookie("user", "uid1234"); response.addCookie(userCookie); 2.4 Reading Cookies from the ClientTo send cookies to the client, you created aCookie then used addCookie to send a
Set-Cookie HTTP response header. This was discussed above in
section 2.1. To read the cookies that come back from the client, you call
getCookies on the HttpServletRequest . This returns an
array of Coo kie objects corresponding to the values that came in on
the Cookie HTTP request header. Once you have this array, you
typically loop down it, calling getName on each Cookie
until you find one matching the name you have in mind. You then call
getValue on the matching Cookie, doing some processing specific to
the resultant value. This is such a common process that the following section
presents a simple getCookieValue method that, given the array of
cookies, a name, and a default value, returns the value of the cookie matching
the name, or, if there is no such cookie, the designated default value.
3. Some Minor Cookie UtilitiesHere are some simple but useful utilities for dealing with cookies.3.1 Getting the Value of a Cookie with a Specified NameHere's a section of ServletUtilities.java that slightly simplifies the retrieval of a cookie value given a cookie name by looping through the array of availableCookie objects, returning
the value of any Cookie whose name matches the input. If there is
no match, the designated default value is returned. public static String getCookieValue(Cookie[] cookies, String cookieName, String defaultValue) { for(int i=0; i<cookies.length; i++) { Cookie cookie = cookies[i]; if (cookieName.equals(cookie.getName())) return(cookie.getValue()); } return(defaultValue); } 3.2 LongLivedCookie.java (Download source code)Here's a small class that you can use instead ofCookie if you want your cookie to automatically persist when the
client quits the browser. package hall; import javax.servlet.http.*; public class LongLivedCookie extends Cookie { public static final int SECONDS_PER_YEAR = 60*60*24*365; public LongLivedCookie(String name, String value) { super(name, value); setMaxAge(SECONDS_PER_YEAR); } } 4. Example: A Customized Search Engine InterfaceHere's a variation of the SearchEngines example shown in the section on the HTTP status line. In this version, the front end is dynamically generated instead of coming from a static HTML file. Then, the servlet that reads the parameters and forwards them to the appropriate search engine also returns cookies to the client that list these values. Next time the client visits the front end, the cookie values are used to preload the form fields with the most recently used entries.4.1 SearchEnginesFrontEnd.javaThis servlet builds the form-based front end to the search engine servlet. At first blush, the output looks just like the page given by the static HTML page presented in the section on HTTP status codes. Here, however, selected values are remembered in cookies (set by theCustomizedSearchEngines servlet that this page
sends data to), so if the user comes back to the same page at a later time (even
after quitting the browser and restarting), the page is initialized with the
values from the previous search.
Note that code uses ServletUtilities.java,
for the package hall; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.net.*; public class SearchEnginesFrontEnd extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie[] cookies = request.getCookies(); String searchString = ServletUtilities.getCookieValue(cookies, "searchString", "Java Programming"); String numResults = ServletUtilities.getCookieValue(cookies, "numResults", "10"); String searchEngine = ServletUtilities.getCookieValue(cookies, "searchEngine", "google"); response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Searching the Web"; out.println(ServletUtilities.headWithTitle(title) + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=\"CENTER\">Searching the Web</H1>\n" + "\n" + "<FORM ACTION=\"/servlet/hall.CustomizedSearchEngines\">\n" + "<CENTER>\n" + "Search String:\n" + "<INPUT TYPE=\"TEXT\" NAME=\"searchString\"\n" + " VALUE=\"" + searchString + "\"><BR>\n" + "Results to Show Per Page:\n" + "<INPUT TYPE=\"TEXT\" NAME=\"numResults\"\n" + " VALUE=" + numResults + " SIZE=3><BR>\n" + "<INPUT TYPE=\"RADIO\" NAME=\"searchEngine\"\n" + " VALUE=\"google\"" + checked("google", searchEngine) + ">\n" + "Google |\n" + "<INPUT TYPE=\"RADIO\" NAME=\"searchEngine\"\n" + " VALUE=\"infoseek\"" + checked("infoseek", searchEngine) + ">\n" + "Infoseek |\n" + "<INPUT TYPE=\"RADIO\" NAME=\"searchEngine\"\n" + " VALUE=\"lycos\"" + checked("lycos", searchEngine) + ">\n" + "Lycos |\n" + "<INPUT TYPE=\"RADIO\" NAME=\"searchEngine\"\n" + " VALUE=\"hotbot\"" + checked("hotbot", searchEngine) + ">\n" + "HotBot\n" + "<BR>\n" + "<INPUT TYPE=\"SUBMIT\" VALUE=\"Search\">\n" + "</CENTER>\n" + "</FORM>\n" + "\n" + "</BODY>\n" + "</HTML>\n"); } private String checked(String name1, String name2) { if (name1.equals(name2)) return(" CHECKED"); else return(""); } } 4.2 CustomizedSearchEngines.javaTheSearchEnginesFrontEnd
servlet shown above sends its data to the CustomizedSearchEngines
servlet. In many respects, it is just like the SearchEngines
servlet shown in the section
on HTTP status codes. However, in addition to constructing a URL for a
search engine and sending a redirection response to the client, the servlet also
sends cookies recording the user data. These cookies will, in turn, be used by
the servlet building the front end to initialize the entries in the HTML forms. package hall; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.net.*; /** A varition of the SearchEngine servlet that uses * cookies to remember users choices. These values * are then used by the SearchEngineFrontEnd servlet * to create the form-based front end with these * choices preset. * 4.3 SearchEnginesFrontEnd OutputHere's the front end as it looks after the user types in some values or if the user comes back to the page in the same or a later session, after having typed in the values in the previous visit.4.4 CustomizedSearchEngines Output
|