先说一个误区:
1.Cookie的格式有2个不同的版本,第一个版本,我们称为Cookie Version 0,是最初由Netscape公司制定的,也被几乎所有的浏览器支持。而较新的版本,Cookie Version 1,则是根据RFC 2109文档制定的。为了确保兼容性,JAVA规定,前面所提到的涉及Cookie的操作都是针对旧版本的Cookie进行的。而新版本的Cookie目 前还不被Javax.servlet.http.Cookie包所支持。
以上提到的仅仅针对javax.servlet.http.Cookie,反编译源码可以看到private int version = 0;但是java还有其他的cookie类,是可以支持到version1的。
”javax.servlet.http.Cookie“,通常我们会使用这个类来处理本地存储的cookie,但是如下firebug抓包可以看到,request中的cookie对象是一整个string,这里就涉及到解析cookie的问题。(tomcat源码中有处理request中cookie[]的方法),
另外java本身有一个类java.net.HttpCookie,~~~根据官方doc文档显示,java6里面其实已经支持各种规范的cookie格式,但在创建的时候,得注意设置version版本
public final class HttpCookie extends Object implements Cloneable HttpCookie 对象表示一个 http cookie,该 cookie 带有服务器和用户代理之间的状态信息。广泛采用 Cookie 来创建有状态 (stateful) 会话。 有 3 种 http cookie 规范: Netscape 草案 RFC 2109 - http://www.ietf.org/rfc/rfc2109.txt RFC 2965 - http://www.ietf.org/rfc/rfc2965.txt HttpCookie 类可以接受所有这 3 种语法形式。 从以下版本开始: 1.6
并且这个类的方法parse可以直接用来解析request的cookie对象得到cookie数组,即req.getHeader("cookie")
public static List<HttpCookie> parse(String header)
在这个类里面有一个guessCookieVersion方法,也大致说明了几个版本间的主要区别:这里可以看到其实expires属性仅仅是Netscape版本使用而已,并非所有cookie都有这个玩意:)
/* * try to guess the cookie version through set-cookie header string */ private static int guessCookieVersion(String header) { int version = 0; header = header.toLowerCase(); if (header.indexOf("expires=") != -1) { // only netscape cookie using 'expires' version = 0; } else if (header.indexOf("version=") != -1) { // version is mandatory for rfc 2965/2109 cookie version = 1; } else if (header.indexOf("max-age") != -1) { // rfc 2965/2109 use 'max-age' version = 1; } else if (startsWithIgnoreCase(header, SET_COOKIE2)) { // only rfc 2965 cookie starts with 'set-cookie2' version = 1; } return version; }