Java/Servlets/Cookie

Материал из Java эксперт
Перейти к: навигация, поиск

A utility class for parsing HTTP dates as used in cookies and other headers

   <source lang="java">
 

/*

* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/util/DateParser.java,v 1.11 2004/11/06 19:15:42 mbecke Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* 
*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
* 
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/

import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.Locale; import java.util.TimeZone; /**

* A utility class for parsing HTTP dates as used in cookies and other headers.  
* This class handles dates as defined by RFC 2616 section 3.3.1 as well as 
* some other common non-standard formats.
* 
* @author Christopher Brown
* @author Michael Becke
* 
*/

public class DateParser {

   /**
    * Date format pattern used to parse HTTP date headers in RFC 1123 format.
    */
   public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz";
   /**
    * Date format pattern used to parse HTTP date headers in RFC 1036 format.
    */
   public static final String PATTERN_RFC1036 = "EEEE, dd-MMM-yy HH:mm:ss zzz";
   /**
    * Date format pattern used to parse HTTP date headers in ANSI C 
    * asctime() format.
    */
   public static final String PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy";
   private static final Collection DEFAULT_PATTERNS = Arrays.asList(
           new String[] { PATTERN_ASCTIME, PATTERN_RFC1036, PATTERN_RFC1123 } );
   /**
    * Parses a date value.  The formats used for parsing the date value are retrieved from
    * the default http params.
    *
    * @param dateValue the date value to parse
    * 
    * @return the parsed date
    *
    * @throws DateParseException if the value could not be parsed using any of the 
    * supported date formats
    */
   public static Date parseDate(String dateValue){
       return parseDate(dateValue, null);
   }
   
   /**
    * Parses the date value using the given date formats.
    * 
    * @param dateValue the date value to parse
    * @param dateFormats the date formats to use
    * 
    * @return the parsed date
    * 
    * @throws DateParseException if none of the dataFormats could parse the dateValue
    */
   public static Date parseDate(
       String dateValue, 
       Collection dateFormats
   ) {
       
       if (dateValue == null) {
           throw new IllegalArgumentException("dateValue is null");
       }
       if (dateFormats == null) {
           dateFormats = DEFAULT_PATTERNS;
       }
       // trim single quotes around date if present
       // see issue #5279
       if (dateValue.length() > 1 
           && dateValue.startsWith(""") 
           && dateValue.endsWith(""")
       ) {
           dateValue = dateValue.substring (1, dateValue.length() - 1);
       }
       
       SimpleDateFormat dateParser = null;        
       Iterator formatIter = dateFormats.iterator();
       
       while (formatIter.hasNext()) {
           String format = (String) formatIter.next();            
           if (dateParser == null) {
               dateParser = new SimpleDateFormat(format, Locale.US);
               dateParser.setTimeZone(TimeZone.getTimeZone("GMT"));
           } else {
               dateParser.applyPattern(format);                    
           }
           try {
               return dateParser.parse(dateValue);
           } catch (ParseException pe) {
               // ignore this exception, we will try the next format
           }                
       }
       
       // we were unable to parse the date
       throw new RuntimeException("Unable to parse the date " + dateValue);        
   }
   /** This class should not be instantiated. */    
   private DateParser() { }
   

}


 </source>
   
  
 
  



Cookie Demo

   <source lang="java">
 

import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CookieServlet extends HttpServlet {

 public void doGet(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, java.io.IOException {
   Cookie cookie = null;
   Cookie[] cookies = request.getCookies();
   boolean newCookie = false;
   if (cookies != null) {
     for (int i = 0; i < cookies.length; i++) {
       if (cookies[i].getName().equals("mycookie")) {
         cookie = cookies[i];
       }
     }
   }
   if (cookie == null) {
     newCookie = true;
     int maxAge;
     try {
       maxAge = new Integer(getServletContext().getInitParameter(
           "cookie-age")).intValue();
     } catch (Exception e) {
       maxAge = -1;
     }
     cookie = new Cookie("mycookie", "" + getNextCookieValue());
     cookie.setPath(request.getContextPath());
     cookie.setMaxAge(maxAge);
     response.addCookie(cookie);
   }
   response.setContentType("text/html");
   java.io.PrintWriter out = response.getWriter();
   out.println("<html>");
   out.println("<head>");
   out.println("<title>Cookie info</title>");
   out.println("</head>");
   out.println("<body>");
   out
.println("

Information about the cookie named \"mycookie\"

");
   out.println("Cookie value: " + cookie.getValue() + "
"); if (newCookie) { out.println("Cookie Max-Age: " + cookie.getMaxAge() + "
"); out.println("Cookie Path: " + cookie.getPath() + "
"); } out.println("</body>"); out.println("</html>"); out.close(); } private long getNextCookieValue() { return new java.util.Date().getTime(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { doGet(request, response); }

}


 </source>
   
  
 
  



Cookie reader

   <source lang="java">
 

import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CookieReader extends HttpServlet {

 public void doGet(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, java.io.IOException {
   Cookie cookie = null;
   //Get an array of Cookies associated with this domain
   Cookie[] cookies = request.getCookies();
   boolean hasCookies = false;
   if (cookies != null)
     hasCookies = true;
   // display the name/value of each cookie
   response.setContentType("text/html");
   java.io.PrintWriter out = response.getWriter();
   out.println("<html>");
   out.println("<head>");
   out.println("<title>Cookie information</title>");
   out.println("</head>");
   out.println("<body>");
   if (hasCookies) {
out.println("

The name and value of each found cookie

");
     for (int i = 0; i < cookies.length; i++) {
       cookie = cookies[i];
       out.println("Name of cookie #" + (i + 1) + ": "
           + cookie.getName() + "
"); out.println("Value of cookie #" + (i + 1) + ": " + cookie.getValue() + "

"); } } else {
out.println("

This request did not include any cookies

");
   }
   out.println("</body>");
   out.println("</html>");
   out.close();
 }
 public void doPost(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, java.io.IOException {
   doGet(request, response);
 }

}


 </source>
   
  
 
  



Cookie Utilities

   <source lang="java">

/**********************************************************************************

*
* Copyright (c) 2003, 2004 The Regents of the University of Michigan, Trustees of Indiana University,
*                  Board of Trustees of the Leland Stanford, Jr., University, and The MIT Corporation
*
* Licensed under the Educational Community License Version 1.0 (the "License");
* By obtaining, using and/or copying this Original Work, you agree that you have read,
* understand, and will comply with the terms and conditions of the Educational Community License.
* You may obtain a copy of the License at:
*
*      http://cvs.sakaiproject.org/licenses/license_1_0.html
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**********************************************************************************/

import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class CookieUtils {

 private CookieUtils() {
 }
 /**
  * Get a new (empty) CookieData list return An empty ArrayList
  */
 public static List newCookieList() {
   return new ArrayList();
 }
 /**
  * Parse an HTTP cookie
  * 
  * @param value
  *          Cookie value
  * @return A CookieData object representing this cookie
  */
 public static CookieData parseCookie(URL url, String value) {
   String[] cookieFields;
   CookieData cookie;
   cookieFields = value.split(";\\s*");
   cookie = makeCookieData(url, cookieFields[0]);
   for (int j = 1; j < cookieFields.length; j++) {
     if ("secure".equalsIgnoreCase(cookieFields[j])) {
       cookie.setSecure(true);
       continue;
     }
     if (cookieFields[j].indexOf("=") > 0) {
       String[] field = cookieFields[j].split("=");
       if ("expires".equalsIgnoreCase(field[0])) {
         cookie.setExpires(field[1]);
       } else if ("domain".equalsIgnoreCase(field[0])) {
         cookie.setDomain(field[1]);
       } else if ("path".equalsIgnoreCase(field[0])) {
         cookie.setPath(field[1]);
       } else if ("version".equalsIgnoreCase(field[0])) {
         cookie.setVersion(field[1]);
       } else if ("max-age".equalsIgnoreCase(field[0])) {
         cookie.setMaxAge(field[1]);
       }
     }
   }
   return cookie;
 }
 /**
  * Build a CookieData object from cookieName=cookieValue text
  * 
  * @param url
  *          URL this cookie belongs to
  * @param cookieText
  *          cookieName[=cookieValue] text
  * @return A new CookieData object
  */
 private static CookieData makeCookieData(URL url, String cookieText) {
   for (int i = 0; i < cookieText.length(); i++) {
     if (cookieText.charAt(i) == "=") {
       String name = cookieText.substring(0, i);
       String value = "";
       if (i + 1 <= cookieText.length()) {
         value = cookieText.substring(i + 1);
       }
       return new CookieData(url, name, value);
     }
   }
   return new CookieData(url, cookieText, "");
 }
 /**
  * Maintain a list of CookieData objects (add, replace, or delete a cookie)
  * 
  * @param cookieList
  *          CookieData list
  * @param cookie
  *          A CookieData object
  */
 public static void storeCookie(List cookieList, CookieData cookie) {
   int size = cookieList.size();
   for (int i = 0; i < size; i++) {
     CookieData cd = (CookieData) cookieList.get(i);
     if (cookie.equals(cd)) {
       if (cookie.getMaxAge() == 0) {
         cookieList.remove(i);
         return;
       }
       cookieList.set(i, cookie);
       return;
     }
   }
   if (cookie.getMaxAge() != 0) {
     cookieList.add(cookie);
   }
 }
 /**
  * Does the cookie domain match the URL?
  * 
  * @param urlString
  *          URL String to match
  * @param cookie
  *          CookieData object (the cookie)
  * @return true if the cookie domain matches the URL
  */
 public static boolean inDomain(String urlString, CookieData cookie) {
   URL url;
   try {
     url = new URL(urlString);
   } catch (MalformedURLException exception) {
     return false;
   }
   return inDomain(url, cookie);
 }
 /**
  * Does the cookie domain match the URL?
  * 
  * @param url
  *          URL to match
  * @param cookie
  *          CookieData object (the cookie)
  * @return true if the cookie domain matches the URL
  */
 public static boolean inDomain(URL url, CookieData cookie) {
   String domain = cookie.getDomain();
   return url.getHost().toLowerCase().endsWith(domain.toLowerCase());
 }
 /**
  * Does the cookie path match the URL "file"?
  * 
  * @param urlString
  *          String URL to match
  * @param cookie
  *          CookieData object (the cookie)
  * @return true if the cookie domain matches the URL
  */
 public static boolean inPath(String urlString, CookieData cookie) {
   URL url;
   try {
     url = new URL(urlString);
   } catch (MalformedURLException exception) {
     return false;
   }
   return inPath(url, cookie);
 }
 /**
  * Does the cookie path match the URL "file"?
  * 
  * @param url
  *          URL to match
  * @param cookie
  *          CookieData object (the cookie)
  * @return true if the cookie domain matches the URL
  */
 public static boolean inPath(URL url, CookieData cookie) {
   return url.getFile().startsWith(cookie.getPath());
 }
 /**
  * Find all stored cookies which associated with this server
  * 
  * @param cookieList
  *          List of stored cookies (CookieData objects)
  * @param url
  *          URL representing the request to lookup (server)
  * @return A List of associated cookies
  */
 public static List findCookiesForServer(List cookieList, URL url) {
   Iterator iterator = cookieList.iterator();
   ArrayList list = new ArrayList();
   while (iterator.hasNext()) {
     CookieData cookie = (CookieData) iterator.next();
     if ((inDomain(url, cookie)) && (inPath(url, cookie))) {
       list.add(cookie);
     }
   }
   return list;
 }
 /**
  * Find cookies associated with this server (by name)
  * 
  * @param cookieList
  *          List of stored cookies (CookieData objects)
  * @param url
  *          URL representing the request to lookup (server)
  * @param name
  *          Cookie name
  * @param exact
  *          true for exact name match, false to match on name prefix
  * @return A List of associated cookies
  */
 public static List getCookies(List cookieList, URL url, String name, boolean exact) {
   List serverCookies = findCookiesForServer(cookieList, url);
   Iterator iterator = serverCookies.iterator();
   ArrayList list = new ArrayList();
   while (iterator.hasNext()) {
     CookieData cookie = (CookieData) iterator.next();
     if (exact) {
       if (cookie.getName().equals(name)) {
         list.add(cookie);
       }
       continue;
     }
     if (cookie.getName().startsWith(name)) {
       list.add(cookie);
     }
   }
   return list;
 }
 /**
  * Find cookies associated with this server (exact name match)
  * 
  * @param cookieList
  *          List of stored cookies (CookieData objects)
  * @param url
  *          URL representing the request to lookup (server)
  * @param name
  *          Cookie name
  * @return A List of associated cookies
  */
 public static List getCookiesByName(List cookieList, URL url, String name) {
   return getCookies(cookieList, url, name, true);
 }
 /**
  * Find cookies associated with this server (match on name "prefix")
  * 
  * @param cookieList
  *          List of stored cookies (CookieData objects)
  * @param url
  *          URL representing the request to lookup (server)
  * @param name
  *          Cookie name
  * @return A List of associated cookies
  */
 public static List getCookiesByPrefix(List cookieList, URL url, String name) {
   return getCookies(cookieList, url, name, false);
 }

} /*******************************************************************************

* 
* Copyright (c) 2003, 2004 The Regents of the University of Michigan, Trustees
* of Indiana University, Board of Trustees of the Leland Stanford, Jr.,
* University, and The MIT Corporation
* 
* Licensed under the Educational Community License Version 1.0 (the "License");
* By obtaining, using and/or copying this Original Work, you agree that you
* have read, understand, and will comply with the terms and conditions of the
* Educational Community License. You may obtain a copy of the License at:
* 
* http://cvs.sakaiproject.org/licenses/license_1_0.html
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 
******************************************************************************/

/**

* Represent a single cookie
*/

class CookieData {

 /**
  * Null (unset) cookie age
  */
 public static final int NULL_AGE = -1;
 /**
  * Expired cookie
  */
 public static final int EXPIRED_AGE = 0;
 private String key;
 private String value;
 private String path;
 private String domain;
 private String version;
 private String expires;
 private int maxAge;
 private boolean secure;
 private CookieData() {
 }
 /**
  * Constructor
  * 
  * @param url
  *          URL associated with this cookie
  * @param key
  *          Cookie name
  * @param value
  *          Cookie value
  */
 public CookieData(URL url, String key, String value) {
   int slash = url.getFile().lastIndexOf("/");
   /*
    * Save cookie name and content
    */
   this.key = key;
   this.value = value;
   /*
    * Domain defaults to hostname, path to the "directory" portion of the
    * request, minus all text from the rightmost "/" character to the end of
    * the string...
    */
   this.path = slash < 1 ? "" : url.getFile().substring(0, slash);
   this.domain = url.getHost();
   this.version = null;
   this.expires = null;
   this.maxAge = NULL_AGE;
   this.secure = false;
 }
 /**
  * Get cookie name
  * 
  * @return The cooke name
  */
 public String getName() {
   return this.key;
 }
 /**
  * Get cookie value (the cookie "text")
  * 
  * @return The value
  */
 public String getValue() {
   return this.value;
 }
 /**
  * Save the path
  */
 public void setPath(String path) {
   this.path = path;
 }
 /**
  * Get the path
  * 
  * @return The cooke path attribute value (null if none)
  */
 public String getPath() {
   return this.path;
 }
 /**
  * Save the expiration date
  */
 public void setExpires(String expires) {
   this.expires = expires;
 }
 /**
  * Get the expiration date
  * 
  * @return The expires attribute value (null if none)
  */
 public String getExpires() {
   return this.expires;
 }
 /**
  * Save the domain
  */
 public void setDomain(String domain) {
   this.domain = domain;
 }
 /**
  * Get the domain
  * 
  * @return The domain attribute value (null if none)
  */
 public String getDomain() {
   return this.domain;
 }
 /**
  * Save the version
  */
 public void setVersion(String version) {
   this.version = version;
 }
 /**
  * Get the cookie version
  * 
  * @return The version (null if none)
  */
 public String getVersion() {
   return this.version;
 }
 /**
  * Set the maximum age for this cookie
  */
 public void setMaxAge(String maxAge) {
   try {
     this.maxAge = Integer.parseInt(maxAge);
   } catch (NumberFormatException ignore) {
   }
 }
 /**
  * Get the maximum age for this cookie
  */
 public int getMaxAge() {
   return this.maxAge;
 }
 /**
  * Save security setting (true if cookie to be sent only via HTTPS)
  */
 public void setSecure(boolean secure) {
   this.secure = secure;
 }
 public boolean getSecure() {
   return this.secure;
 }
 /**
  * Equal strings?
  * 
  * @param a
  *          String one
  * @param b
  *          Stringtwo
  * @return true if both are null, or String "equals" is true
  */
 private boolean stringEquals(String a, String b) {
   if ((a == null) && (b == null)) {
     return true;
   }
   if ((a == null) || (b == null)) {
     return false;
   }
   return a.equals(b);
 }
 /**
  * Equal cookies?
  * 
  * @param cookie
  *          for comparison
  * @return true if cookie name, path, and domain are all equal
  */
 public boolean equals(CookieData cookie) {
   if (!key.equals(cookie.getName())) {
     return false;
   }
   return stringEquals(path, cookie.getPath()) && stringEquals(domain, cookie.getDomain());
 }

}

 </source>
   
  
 
  



Parse a Cookie: header into individual tokens according to RFC 2109.

   <source lang="java">

/*

* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
* 
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
* 
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
* 
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
* 
* Contributor(s):
* 
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don"t indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

/*

* Copyright 2004-2005 Sun Microsystems, Inc.  All rights reserved.
* Use is subject to license terms.
*/

import java.lang.System; import java.lang.String; import java.lang.IndexOutOfBoundsException; import java.lang.ArrayIndexOutOfBoundsException; /**

* Parse a Cookie: header into individual tokens according to RFC 2109.
*/

public class CookieTokenizer {

   /**
    * Upper bound on the number of cookie tokens to accept.  The limit is
    * based on the 4 different attributes (4.3.4) and the 20 cookie minimum
    * (6.3) given in RFC 2109 multiplied by 2 to accomodate the 2 tokens in
    * each name=value pair ("JSESSIONID=1234" is 2 tokens).
    */
   private static final int MAX_COOKIE_TOKENS = 4 * 20 * 2;
   /**
    * Array of cookie tokens.  Even indices contain name tokens while odd
    * indices contain value tokens (or null).
    */
   private String tokens[] = new String[MAX_COOKIE_TOKENS];
   /**
    * Number of cookie tokens currently in the tokens[] array.
    */
   private int numTokens = 0;
   /**
    * Parse a name=value pair from the Cookie: header.
    *
    * @param cookies The Cookie: header to parse
    * @param beginIndex The index in cookies to begin parsing from, inclusive
    */
   private int parseNameValue(String cookies, int beginIndex) {
       int length = cookies.length();
       int index = beginIndex;
       while (index < length) {
           switch (cookies.charAt(index)) {
           case ";":
           case ",":
               // Found end of name token without value
               tokens[numTokens] = cookies.substring(beginIndex, index).trim();
               if (tokens[numTokens].length() > 0) {
                   numTokens++;
                   tokens[numTokens] = null;
                   numTokens++;
               }
               return index + 1;
           case "=":
               // Found end of name token with value
               tokens[numTokens] = cookies.substring(beginIndex, index).trim();
               numTokens++;
               return parseValue(cookies, index + 1);
           case """:
               // Skip past quoted span
               do index++; while (cookies.charAt(index) != """);
               break;
           }
           index++;
       }
       if (index > beginIndex) {
           // Found end of name token without value
           tokens[numTokens] = cookies.substring(beginIndex, index).trim();
           if (tokens[numTokens].length() > 0) {
               numTokens++;
               tokens[numTokens] = null;
               numTokens++;
           }
       }
       return index;
   }
   /**
    * Parse the name=value tokens from a Cookie: header.
    *
    * @param cookies The Cookie: header to parse
    */
   public int tokenize(String cookies) {
       numTokens = 0;
       if (cookies != null) {
           try {
               // Advance through cookies, parsing name=value pairs
               int length = cookies.length();
               int index = 0;
               while (index < length)
                   index = parseNameValue(cookies, index);
           }
           catch (ArrayIndexOutOfBoundsException e) {
               // Filled up the tokens[] array
           }
           catch (IndexOutOfBoundsException e) {
               // Walked off the end of the cookies header
           }
       }
       return numTokens;
   }
   /**
    * Return the number of cookie tokens parsed from the Cookie: header.
    */
   public int getNumTokens() {
       return numTokens;
   }
   /**
    * Returns a given cookie token from the Cookie: header.
    *
    * @param index The index of the cookie token to return
    */
   public String tokenAt(int index) {
       return tokens[index];
   }
   /**
    * Parse the value token from a name=value pair.
    *
    * @param cookies The Cookie: header to parse
    * @param beginIndex The index in cookies to begin parsing from, inclusive
    */
   private int parseValue(String cookies, int beginIndex) {
       int length = cookies.length();
       int index = beginIndex;
       while (index < length) {
           switch (cookies.charAt(index)) {
           case ";":
           case ",":
               // Found end of value token
               tokens[numTokens] = cookies.substring(beginIndex, index).trim();
               numTokens++;
               return index + 1;
           case """:
               // Skip past quoted span
               do index++; while (cookies.charAt(index) != """);
               break;
           }
           index++;
       }
       // Found end of value token
       tokens[numTokens] = cookies.substring(beginIndex, index).trim();
       numTokens++;
       return index;
   }

}

 </source>
   
  
 
  



Parsing and formatting HTTP dates as used in cookies and other headers.

   <source lang="java">

import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.Locale; import java.util.TimeZone; /**

* A utility class for parsing and formatting HTTP dates as used in cookies and
* other headers.  This class handles dates as defined by RFC 2616 section
* 3.3.1 as well as some other common non-standard formats.
*
* @author Christopher Brown
* @author Michael Becke
*/

public final class DateUtil {

   /**
    * Date format pattern used to parse HTTP date headers in RFC 1123 format.
    */
   public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz";
   /**
    * Date format pattern used to parse HTTP date headers in RFC 1036 format.
    */
   public static final String PATTERN_RFC1036 = "EEEE, dd-MMM-yy HH:mm:ss zzz";
   /**
    * Date format pattern used to parse HTTP date headers in ANSI C
    * asctime() format.
    */
   public static final String PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy";
   private static final Collection<String> DEFAULT_PATTERNS = Arrays.asList(
       new String[] {PATTERN_ASCTIME, PATTERN_RFC1036, PATTERN_RFC1123});
   private static final Date DEFAULT_TWO_DIGIT_YEAR_START;
   static {
       Calendar calendar = Calendar.getInstance();
       calendar.set(2000, Calendar.JANUARY, 1, 0, 0);
       DEFAULT_TWO_DIGIT_YEAR_START = calendar.getTime();
   }
   private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
   /**
    * This class should not be instantiated.
    */
   private DateUtil() {
   }
   /**
    * Parses a date value.  The formats used for parsing the date value are retrieved from
    * the default http params.
    *
    * @param dateValue the date value to parse
    * @return the parsed date
    * @throws DateParseException if the value could not be parsed using any of the
    *                            supported date formats
    */
   public static Date parseDate(String dateValue) {
       return parseDate(dateValue, null, null);
   }
   /**
    * Parses the date value using the given date formats.
    *
    * @param dateValue   the date value to parse
    * @param dateFormats the date formats to use
    * @return the parsed date
    * @throws DateParseException if none of the dataFormats could parse the dateValue
    */
   public static Date parseDate(String dateValue, Collection<String> dateFormats)
       {
       return parseDate(dateValue, dateFormats, null);
   }
   /**
    * Parses the date value using the given date formats.
    *
    * @param dateValue   the date value to parse
    * @param dateFormats the date formats to use
    * @param startDate   During parsing, two digit years will be placed in the range
    *                    startDate to startDate + 100 years. This value may
    *                    be null. When null is given as a parameter, year
    *                    2000 will be used.
    * @return the parsed date
    * @throws DateParseException if none of the dataFormats could parse the dateValue
    */
   public static Date parseDate(
       String dateValue,
       Collection<String> dateFormats,
       Date startDate
   )  {
       if (dateValue == null) {
           throw new IllegalArgumentException("dateValue is null");
       }
       if (dateFormats == null) {
           dateFormats = DEFAULT_PATTERNS;
       }
       if (startDate == null) {
           startDate = DEFAULT_TWO_DIGIT_YEAR_START;
       }
       // trim single quotes around date if present
       // see issue #5279
       if (dateValue.length() > 1
           && dateValue.startsWith(""")
           && dateValue.endsWith(""")
           ) {
           dateValue = dateValue.substring(1, dateValue.length() - 1);
       }
       SimpleDateFormat dateParser = null;
       for (String format : dateFormats) {
           if (dateParser == null) {
               dateParser = new SimpleDateFormat(format, Locale.US);
               dateParser.setTimeZone(TimeZone.getTimeZone("GMT"));
               dateParser.set2DigitYearStart(startDate);
           } else {
               dateParser.applyPattern(format);
           }
           try {
               return dateParser.parse(dateValue);
           } catch (ParseException pe) {
               // ignore this exception, we will try the next format
           }
       }
       // we were unable to parse the date
       throw new RuntimeException("Unable to parse the date " + dateValue);
   }
   /**
    * Formats the given date according to the RFC 1123 pattern.
    *
    * @param date The date to format.
    * @return An RFC 1123 formatted date string.
    * @see #PATTERN_RFC1123
    */
   public static String formatDate(Date date) {
       return formatDate(date, PATTERN_RFC1123);
   }
   /**
    * Formats the given date according to the specified pattern.  The pattern
    * must conform to that used by the {@link SimpleDateFormat simple date
    * format} class.
    *
    * @param date    The date to format.
    * @param pattern The pattern to use for formatting the date.
    * @return A formatted date string.
    * @throws IllegalArgumentException If the given date pattern is invalid.
    * @see SimpleDateFormat
    */
   public static String formatDate(Date date, String pattern) {
       if (date == null) {
           throw new IllegalArgumentException("date is null");
       }
       if (pattern == null) {
           throw new IllegalArgumentException("pattern is null");
       }
       SimpleDateFormat formatter = new SimpleDateFormat(pattern, Locale.US);
       formatter.setTimeZone(GMT);
       return formatter.format(date);
   }

}

 </source>
   
  
 
  



Setting and Reading Cookies

   <source lang="java">
 

import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class SettingandReadingCookies extends HttpServlet {

   public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws IOException, ServletException
   {
       response.setContentType("text/html");
       PrintWriter out = response.getWriter();
       
       out.println("<HTML>");
       out.println("<HEAD>");
       out.println("<TITLE>");
       out.println("A Web Page");
       out.println("</TITLE>");
       out.println("</HEAD>");
       out.println("<BODY");
       Cookie[] cookies = request.getCookies();
       boolean foundCookie = false;
       for(int loopIndex = 0; loopIndex < cookies.length; loopIndex++) { 
           Cookie cookie1 = cookies[loopIndex];
           if (cookie1.getName().equals("color")) {
               out.println("bgcolor = " + cookie1.getValue());
               foundCookie = true;
           }
       }  
       if (!foundCookie) {
           Cookie cookie1 = new Cookie("color", "cyan");
           cookie1.setMaxAge(24*60*60);
           response.addCookie(cookie1); 
       }
       out.println(">");
out.println("

Setting and Reading Cookies

");
       out.println("This page will set its background color using a cookie when reloaded.");
       out.println("</BODY>");
       out.println("</HTML>");

} }


 </source>
   
  
 
  



Utilities for finding and manipulating cookies

   <source lang="java">

/*

* Copyright (c) 2003-2006, Simon Brown
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*   - Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*
*   - Redistributions in binary form must reproduce the above copyright
*     notice, this list of conditions and the following disclaimer in
*     the documentation and/or other materials provided with the
*     distribution.
*
*   - Neither the name of Pebble nor the names of its contributors may
*     be used to endorse or promote products derived from this software
*     without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; /**

* Utilities for finding and manipulating cookies.
*
* @author    Simon Brown
*/

public class CookieUtils {

 /** represents 4 weeks in seconds */
 public static final int ONE_MONTH = 60 * 60 * 24 * 28;
 /**
  * Gets a reference to a named cookie from an array of cookies.
  *
  * @param cookies   an array of cookies
  * @param name      the name of the cookie to find
  * @return    a reference to a Cookie, or null if the cookie couldn"t be found
  */
 public static Cookie getCookie(Cookie cookies[], String name) {
   if (cookies != null) {
     for (Cookie cookie : cookies) {
       if (cookie.getName().equals(name)) {
         return cookie;
       }
     }
   }
   // we"ve got this far so the specified cookie wasn"t found
   return null;
 }
 /**
  * Adds a cookie with the specified name, value and expiry.
  *
  * @param response    the HttpServletResponse to add the cookie to
  * @param name        the name of the cookie
  * @param value       the value of the cookie
  * @param maxAge      the maxAge of the cookie (in seconds)
  */
 public static void addCookie(HttpServletResponse response, String name, String value, int maxAge) {
   Cookie cookie = new Cookie(name, value);
   cookie.setMaxAge(maxAge);
   response.addCookie(cookie);
 }
 /**
  * Removes a cookie with the specified name.
  *
  * @param response    the HttpServletResponse to remove the cookie from
  * @param name        the name of the cookie
  */
 public static void removeCookie(HttpServletResponse response, String name) {
   addCookie(response, name, "", 0);
 }

}

 </source>