Cookie.java
上传用户:tanyanyong
上传日期:2013-06-23
资源大小:1355k
文件大小:17k
源码类别:

电子政务应用

开发平台:

MultiPlatform

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999 The Apache Software Foundation.  All rights 
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer. 
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution, if
  20.  *    any, must include the following acknowlegement:  
  21.  *       "This product includes software developed by the 
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowlegement may appear in the software itself,
  24.  *    if and wherever such third-party acknowlegements normally appear.
  25.  *
  26.  * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
  27.  *    Foundation" must not be used to endorse or promote products derived
  28.  *    from this software without prior written permission. For written 
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache"
  32.  *    nor may "Apache" appear in their names without prior written
  33.  *    permission of the Apache Group.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation.  For more
  51.  * information on the Apache Software Foundation, please see
  52.  * <http://www.apache.org/>.
  53.  *
  54.  * ====================================================================
  55.  *
  56.  * This source code implements specifications defined by the Java
  57.  * Community Process. In order to remain compliant with the specification
  58.  * DO NOT add / change / or delete method signatures!
  59.  */ 
  60. package javax.servlet.http;
  61. import java.io.IOException;
  62. import java.text.MessageFormat;
  63. import java.util.ResourceBundle;
  64. /**
  65.  *
  66.  * Creates a cookie, a small amount of information sent by a servlet to 
  67.  * a Web browser, saved by the browser, and later sent back to the server.
  68.  * A cookie's value can uniquely 
  69.  * identify a client, so cookies are commonly used for session management.
  70.  * 
  71.  * <p>A cookie has a name, a single value, and optional attributes
  72.  * such as a comment, path and domain qualifiers, a maximum age, and a
  73.  * version number. Some Web browsers have bugs in how they handle the 
  74.  * optional attributes, so use them sparingly to improve the interoperability 
  75.  * of your servlets.
  76.  *
  77.  * <p>The servlet sends cookies to the browser by using the
  78.  * {@link HttpServletResponse#addCookie} method, which adds
  79.  * fields to HTTP response headers to send cookies to the 
  80.  * browser, one at a time. The browser is expected to 
  81.  * support 20 cookies for each Web server, 300 cookies total, and
  82.  * may limit cookie size to 4 KB each.
  83.  * 
  84.  * <p>The browser returns cookies to the servlet by adding 
  85.  * fields to HTTP request headers. Cookies can be retrieved
  86.  * from a request by using the {@link HttpServletRequest#getCookies} method.
  87.  * Several cookies might have the same name but different path attributes.
  88.  * 
  89.  * <p>Cookies affect the caching of the Web pages that use them. 
  90.  * HTTP 1.0 does not cache pages that use cookies created with
  91.  * this class. This class does not support the cache control
  92.  * defined with HTTP 1.1.
  93.  *
  94.  * <p>This class supports both the Version 0 (by Netscape) and Version 1 
  95.  * (by RFC 2109) cookie specifications. By default, cookies are
  96.  * created using Version 0 to ensure the best interoperability.
  97.  *
  98.  *
  99.  * @author Various
  100.  * @version $Version$
  101.  *
  102.  */
  103. // XXX would implement java.io.Serializable too, but can't do that
  104. // so long as sun.servlet.* must run on older JDK 1.02 JVMs which
  105. // don't include that support.
  106. public class Cookie implements Cloneable {
  107.     private static final String LSTRING_FILE =
  108. "javax.servlet.http.LocalStrings";
  109.     private static ResourceBundle lStrings =
  110. ResourceBundle.getBundle(LSTRING_FILE);
  111.     
  112.     //
  113.     // The value of the cookie itself.
  114.     //
  115.     
  116.     private String name; // NAME= ... "$Name" style is reserved
  117.     private String value; // value of NAME
  118.     //
  119.     // Attributes encoded in the header's cookie fields.
  120.     //
  121.     
  122.     private String comment; // ;Comment=VALUE ... describes cookie's use
  123. // ;Discard ... implied by maxAge < 0
  124.     private String domain; // ;Domain=VALUE ... domain that sees cookie
  125.     private int maxAge = -1; // ;Max-Age=VALUE ... cookies auto-expire
  126.     private String path; // ;Path=VALUE ... URLs that see the cookie
  127.     private boolean secure; // ;Secure ... e.g. use SSL
  128.     private int version = 0; // ;Version=1 ... means RFC 2109++ style
  129.     
  130.     
  131.     /**
  132.      * Constructs a cookie with a specified name and value.
  133.      *
  134.      * <p>The name must conform to RFC 2109. That means it can contain 
  135.      * only ASCII alphanumeric characters and cannot contain commas, 
  136.      * semicolons, or white space or begin with a $ character. The cookie's
  137.      * name cannot be changed after creation.
  138.      *
  139.      * <p>The value can be anything the server chooses to send. Its
  140.      * value is probably of interest only to the server. The cookie's
  141.      * value can be changed after creation with the
  142.      * <code>setValue</code> method.
  143.      *
  144.      * <p>By default, cookies are created according to the Netscape
  145.      * cookie specification. The version can be changed with the 
  146.      * <code>setVersion</code> method.
  147.      *
  148.      *
  149.      * @param name  a <code>String</code> specifying the name of the cookie
  150.      *
  151.      * @param value a <code>String</code> specifying the value of the cookie
  152.      *
  153.      * @throws IllegalArgumentException if the cookie name contains illegal characters
  154.      * (for example, a comma, space, or semicolon)
  155.      * or it is one of the tokens reserved for use
  156.      * by the cookie protocol
  157.      * @see #setValue
  158.      * @see #setVersion
  159.      *
  160.      */
  161.     public Cookie(String name, String value) {
  162. if (!isToken(name)
  163. || name.equalsIgnoreCase("Comment") // rfc2019
  164. || name.equalsIgnoreCase("Discard") // 2019++
  165. || name.equalsIgnoreCase("Domain")
  166. || name.equalsIgnoreCase("Expires") // (old cookies)
  167. || name.equalsIgnoreCase("Max-Age") // rfc2019
  168. || name.equalsIgnoreCase("Path")
  169. || name.equalsIgnoreCase("Secure")
  170. || name.equalsIgnoreCase("Version")
  171.     ) {
  172.     String errMsg = lStrings.getString("err.cookie_name_is_token");
  173.     Object[] errArgs = new Object[1];
  174.     errArgs[0] = name;
  175.     errMsg = MessageFormat.format(errMsg, errArgs);
  176.     throw new IllegalArgumentException(errMsg);
  177. }
  178. this.name = name;
  179. this.value = value;
  180.     }
  181.     /**
  182.      *
  183.      * Specifies a comment that describes a cookie's purpose.
  184.      * The comment is useful if the browser presents the cookie 
  185.      * to the user. Comments
  186.      * are not supported by Netscape Version 0 cookies.
  187.      *
  188.      * @param purpose a <code>String</code> specifying the comment 
  189.      * to display to the user
  190.      *
  191.      * @see #getComment
  192.      *
  193.      */
  194.     public void setComment(String purpose) {
  195. comment = purpose;
  196.     }
  197.     
  198.     
  199.     
  200.     /**
  201.      * Returns the comment describing the purpose of this cookie, or
  202.      * <code>null</code> if the cookie has no comment.
  203.      *
  204.      * @return a <code>String</code> containing the comment,
  205.      * or <code>null</code> if none
  206.      *
  207.      * @see #setComment
  208.      *
  209.      */ 
  210.     public String getComment() {
  211. return comment;
  212.     }
  213.     
  214.     
  215.     
  216.     /**
  217.      *
  218.      * Specifies the domain within which this cookie should be presented.
  219.      *
  220.      * <p>The form of the domain name is specified by RFC 2109. A domain
  221.      * name begins with a dot (<code>.foo.com</code>) and means that
  222.      * the cookie is visible to servers in a specified Domain Name System
  223.      * (DNS) zone (for example, <code>www.foo.com</code>, but not 
  224.      * <code>a.b.foo.com</code>). By default, cookies are only returned
  225.      * to the server that sent them.
  226.      *
  227.      *
  228.      * @param pattern a <code>String</code> containing the domain name
  229.      * within which this cookie is visible;
  230.      * form is according to RFC 2109
  231.      *
  232.      * @see #getDomain
  233.      *
  234.      */
  235.     public void setDomain(String pattern) {
  236. domain = pattern.toLowerCase(); // IE allegedly needs this
  237.     }
  238.     
  239.     
  240.     
  241.     
  242.     /**
  243.      * Returns the domain name set for this cookie. The form of 
  244.      * the domain name is set by RFC 2109.
  245.      *
  246.      * @return a <code>String</code> containing the domain name
  247.      *
  248.      * @see #setDomain
  249.      *
  250.      */ 
  251.     public String getDomain() {
  252. return domain;
  253.     }
  254.     /**
  255.      * Sets the maximum age of the cookie in seconds.
  256.      *
  257.      * <p>A positive value indicates that the cookie will expire
  258.      * after that many seconds have passed. Note that the value is
  259.      * the <i>maximum</i> age when the cookie will expire, not the cookie's
  260.      * current age.
  261.      *
  262.      * <p>A negative value means
  263.      * that the cookie is not stored persistently and will be deleted
  264.      * when the Web browser exits. A zero value causes the cookie
  265.      * to be deleted.
  266.      *
  267.      * @param expiry an integer specifying the maximum age of the
  268.      *  cookie in seconds; if negative, means
  269.      * the cookie is not stored; if zero, deletes
  270.      * the cookie
  271.      *
  272.      *
  273.      * @see #getMaxAge
  274.      *
  275.      */
  276.     public void setMaxAge(int expiry) {
  277. maxAge = expiry;
  278.     }
  279.     /**
  280.      * Returns the maximum age of the cookie, specified in seconds,
  281.      * By default, <code>-1</code> indicating the cookie will persist
  282.      * until browser shutdown.
  283.      *
  284.      *
  285.      * @return an integer specifying the maximum age of the
  286.      * cookie in seconds; if negative, means
  287.      * the cookie persists until browser shutdown
  288.      *
  289.      *
  290.      * @see #setMaxAge
  291.      *
  292.      */
  293.     public int getMaxAge() {
  294. return maxAge;
  295.     }
  296.     
  297.     
  298.     
  299.     /**
  300.      * Specifies a path for the cookie
  301.      * to which the client should return the cookie.
  302.      *
  303.      * <p>The cookie is visible to all the pages in the directory
  304.      * you specify, and all the pages in that directory's subdirectories. 
  305.      * A cookie's path must include the servlet that set the cookie,
  306.      * for example, <i>/catalog</i>, which makes the cookie
  307.      * visible to all directories on the server under <i>/catalog</i>.
  308.      *
  309.      * <p>Consult RFC 2109 (available on the Internet) for more
  310.      * information on setting path names for cookies.
  311.      *
  312.      *
  313.      * @param uri a <code>String</code> specifying a path
  314.      *
  315.      *
  316.      * @see #getPath
  317.      *
  318.      */
  319.     public void setPath(String uri) {
  320. path = uri;
  321.     }
  322.     /**
  323.      * Returns the path on the server 
  324.      * to which the browser returns this cookie. The
  325.      * cookie is visible to all subpaths on the server.
  326.      *
  327.      *
  328.      * @return a <code>String</code> specifying a path that contains
  329.      * a servlet name, for example, <i>/catalog</i>
  330.      *
  331.      * @see #setPath
  332.      *
  333.      */ 
  334.     public String getPath() {
  335. return path;
  336.     }
  337.     /**
  338.      * Indicates to the browser whether the cookie should only be sent
  339.      * using a secure protocol, such as HTTPS or SSL.
  340.      *
  341.      * <p>The default value is <code>false</code>.
  342.      *
  343.      * @param flag if <code>true</code>, sends the cookie from the browser
  344.      * to the server using only when using a secure protocol;
  345.      * if <code>false</code>, sent on any protocol
  346.      *
  347.      * @see #getSecure
  348.      *
  349.      */
  350.  
  351.     public void setSecure(boolean flag) {
  352. secure = flag;
  353.     }
  354.     /**
  355.      * Returns <code>true</code> if the browser is sending cookies
  356.      * only over a secure protocol, or <code>false</code> if the
  357.      * browser can send cookies using any protocol.
  358.      *
  359.      * @return <code>true</code> if the browser can use
  360.      * any standard protocol; otherwise, <code>false</code>
  361.      *
  362.      * @see #setSecure
  363.      *
  364.      */
  365.     public boolean getSecure() {
  366. return secure;
  367.     }
  368.     /**
  369.      * Returns the name of the cookie. The name cannot be changed after
  370.      * creation.
  371.      *
  372.      * @return a <code>String</code> specifying the cookie's name
  373.      *
  374.      */
  375.     public String getName() {
  376. return name;
  377.     }
  378.     /**
  379.      *
  380.      * Assigns a new value to a cookie after the cookie is created.
  381.      * If you use a binary value, you may want to use BASE64 encoding.
  382.      *
  383.      * <p>With Version 0 cookies, values should not contain white 
  384.      * space, brackets, parentheses, equals signs, commas,
  385.      * double quotes, slashes, question marks, at signs, colons,
  386.      * and semicolons. Empty values may not behave the same way
  387.      * on all browsers.
  388.      *
  389.      * @param newValue a <code>String</code> specifying the new value 
  390.      *
  391.      *
  392.      * @see #getValue
  393.      * @see Cookie
  394.      *
  395.      */
  396.     public void setValue(String newValue) {
  397. value = newValue;
  398.     }
  399.     /**
  400.      * Returns the value of the cookie.
  401.      *
  402.      * @return a <code>String</code> containing the cookie's
  403.      * present value
  404.      *
  405.      * @see #setValue
  406.      * @see Cookie
  407.      *
  408.      */
  409.     public String getValue() {
  410. return value;
  411.     }
  412.     /**
  413.      * Returns the version of the protocol this cookie complies 
  414.      * with. Version 1 complies with RFC 2109, 
  415.      * and version 0 complies with the original
  416.      * cookie specification drafted by Netscape. Cookies provided
  417.      * by a browser use and identify the browser's cookie version.
  418.      * 
  419.      *
  420.      * @return 0 if the cookie complies with the
  421.      * original Netscape specification; 1
  422.      * if the cookie complies with RFC 2109
  423.      *
  424.      * @see #setVersion
  425.      *
  426.      */
  427.     public int getVersion() {
  428. return version;
  429.     }
  430.     /**
  431.      * Sets the version of the cookie protocol this cookie complies
  432.      * with. Version 0 complies with the original Netscape cookie
  433.      * specification. Version 1 complies with RFC 2109.
  434.      *
  435.      * <p>Since RFC 2109 is still somewhat new, consider
  436.      * version 1 as experimental; do not use it yet on production sites.
  437.      *
  438.      *
  439.      * @param v 0 if the cookie should comply with 
  440.      * the original Netscape specification;
  441.      * 1 if the cookie should comply with RFC 2109
  442.      *
  443.      * @see #getVersion
  444.      *
  445.      */
  446.     public void setVersion(int v) {
  447. version = v;
  448.     }
  449.     // Note -- disabled for now to allow full Netscape compatibility
  450.     // from RFC 2068, token special case characters
  451.     // 
  452.     // private static final String tspecials = "()<>@,;:\"/[]?={} t";
  453.     private static final String tspecials = ",;";
  454.     
  455.     
  456.     
  457.     /*
  458.      * Tests a string and returns true if the string counts as a 
  459.      * reserved token in the Java language.
  460.      * 
  461.      * @param value the <code>String</code> to be tested
  462.      *
  463.      * @return <code>true</code> if the <code>String</code> is
  464.      * a reserved token; <code>false</code>
  465.      * if it is not
  466.      */
  467.     private boolean isToken(String value) {
  468. int len = value.length();
  469. for (int i = 0; i < len; i++) {
  470.     char c = value.charAt(i);
  471.     if (c < 0x20 || c >= 0x7f || tspecials.indexOf(c) != -1)
  472. return false;
  473. }
  474. return true;
  475.     }
  476.     /**
  477.      *
  478.      * Overrides the standard <code>java.lang.Object.clone</code> 
  479.      * method to return a copy of this cookie.
  480.      *
  481.      *
  482.      */
  483.     public Object clone() {
  484. try {
  485.     return super.clone();
  486. } catch (CloneNotSupportedException e) {
  487.     throw new RuntimeException(e.getMessage());
  488. }
  489.     }
  490. }