Java/Servlets/Cookie

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

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

  
/*
 * $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 
     * <code>asctime()</code> 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() { }
    
}





Cookie Demo

  
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("<h2> Information about the cookie named \"mycookie\"</h2>");
    out.println("Cookie value: " + cookie.getValue() + "<br>");
    if (newCookie) {
      out.println("Cookie Max-Age: " + cookie.getMaxAge() + "<br>");
      out.println("Cookie Path: " + cookie.getPath() + "<br>");
    }
    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);
  }
}





Cookie reader

  
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("<h2> The name and value of each found cookie</h2>");
      for (int i = 0; i < cookies.length; i++) {
        cookie = cookies[i];
        out.println("Name of cookie #" + (i + 1) + ": "
            + cookie.getName() + "<br>");
        out.println("Value of cookie #" + (i + 1) + ": "
            + cookie.getValue() + "<br><br>");
      }
    } else {
      out.println("<h2> This request did not include any cookies</h2>");
    }
    out.println("</body>");
    out.println("</html>");
    out.close();
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, java.io.IOException {
    doGet(request, response);
  }
}





Cookie Utilities

 
/**********************************************************************************
 *
 * 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());
  }
}





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

 
/*
 * 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;
    }
}





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

 

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
     * <code>asctime()</code> 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
     *                    <code>startDate</code> to <code>startDate + 100 years</code>. This value may
     *                    be <code>null</code>. When <code>null</code> is given as a parameter, year
     *                    <code>2000</code> 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);
    }
}





Setting and Reading Cookies

  
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("<H1>Setting and Reading Cookies</H1>");
        out.println("This page will set its background color using a cookie when reloaded.");
        out.println("</BODY>");
        out.println("</HTML>");
}
}





Utilities for finding and manipulating cookies

 
/*
 * 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);
  }
}