Java Cookie getDomain,getMaxAge,getPath返回null

AddCookieServlet

  1. Cookie cookie =  new  Cookie( "mycookie""juanjuan" );
  2. cookie.setMaxAge(10);  //10 means 10 seconds
  3. cookie.setDomain( ".cityu.edu.hk" );
  4. response.addCookie(cookie);


GetCookieServlet

  1. Cookie[] cookies = request.getCookies();
  2. if  (cookies !=  null ) {
  3.      for  (Cookie cookie : cookies) {
  4.          out .println(cookie.getName() +  ": "  + cookie.getValue()
  5.                 +  "<br>" );
  6.          out .println( "domain: "  + cookie.getDomain() +  "<br>" );
  7.          out .println( "max age: "  + cookie.getMaxAge() +  "<br>" );
  8.     }
  9. }


When you get cookie from request, you can only get cookie name and value, and always:
getDomain() return null
getPath() return null
getMaxAge() return -1

Check the real cookie data in Firefox menu ""Tools -> Options -> Privacy -> Show Cookies", you can see the cookie "mycookie" domain is cityu.edu.hk and max age is 10.


Why???
Answer
(from http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=50&t=004445):

This happens because Kookie API's implementation Kookie.java doesn't return us the Domain, Path, Max Age any extra information except Kookie name,value

NOTE: I have replaced "c" from cookie to "k" everwhere to avoid the posting error I was getting...

Here is a piece of code from Kookie.java,

code:

public Kookie(String name, String value)
{
maxAge = -1;
version = 0;
if(!isToken(name) || name.equalsIgnoreCase("Comment") || name.equalsIgnoreCase("Discard") || name.equalsIgnoreCase("Domain") || name.equalsIgnoreCase("Expires") || name.equalsIgnoreCase("Max-Age") || name.equalsIgnoreCase("Path") || name.equalsIgnoreCase("Secure") || name.equalsIgnoreCase("Version"))
{
String errMsg = lStrings.getString("err.kookie_name_is_token");
Object errArgs[] = new Object[1];
errArgs[0] = name;
errMsg = MessageFormat.format(errMsg, errArgs);
throw new IllegalArgumentException(errMsg);
} else
{
this.name = name;
this.value = value;
return;
}
}

Here what happens is- browser returns the kookie as defined per RFC 2109

Now, the webserver's code parses the kookie header separated by ";" and so gets following in the list,

name1=value1
domain=domain1
path=path1
(and other parameters like Secure, Comment etc...)
name2=value2
domain=domain2
path=path2
(and other parameters like Secure, Comment etc...)

and then tries to create Kookie object for each of such Name,Value pair after further separting by '=' sign. So, it does,
Kookie tempKookie = new Kookie(name,value);

now the Kookie.java ignores the kookie creation if the name is Path, Domain etc (as per the above Kookie.java) and so it only gets kookie's name and value...

Here is the Tomcat405's code that parses the Kookie. If we combine the knowledge of the RFC 2109, this code and Kookie.java then we would realize what happens here...

code:

/**
* Parse a kookie header into an array of kookies according to RFC 2109.
*
* @param header Value of an HTTP "Kookie" header
*/
public static Kookie[] parseKookieHeader(String header) {

if ((header == null) || (header.length() < 1))
return (new Kookie[0]);

ArrayList kookies = new ArrayList();
while (header.length() > 0) {
int semicolon = header.indexOf(';');
if (semicolon < 0)
semicolon = header.length();
if (semicolon == 0)
break;
String token = header.substring(0, semicolon);
if (semicolon < header.length())
header = header.substring(semicolon + 1);
else
header = "";
try {
int equals = token.indexOf('=');
if (equals > 0) {
String name = token.substring(0, equals).trim();
String value = token.substring(equals+1).trim();
kookies.add(new Kookie(name, value));
}
} catch (Throwable e) {
;
}
}

return ((Kookie[]) kookies.toArray(new Kookie[kookies.size()]));

}


hope this is helpful...

and the reason that Kookie.java ignores Domain, Path etc could be just that it wanted to avoid providing any more information to the server as a prevention of possible hack by some other servers. e.g.

- I have a server1, server2.

- server1 sets a kookie called "server1login" w/ domain/path etc..

- server2 hacks the user system's browser and write a code to read kookies that allows it to read "all" kookies set in the browser

- now, if the reading of the kookie returned every bit of information about the kookie then server2's code would know domain/path of server1 and can then overwrite the kookie BUT if it didn't get the domain/path then it won't be able to overwrite the kookie and the user's application runnin in the browser is less liable to mis-behave due to the hack.

- Here server2 CAN override Kookie API defined by Kookie.java and return all the information to the user but that would violate Kookie API but to do that we have to modify server2's servlets.jar where the Kookie.class is there and all those things which can't be just done with a blink of eye....

- if server1's code wanted to modify the kookie (in case of logout if we want to remove the kookie) then the code has to know the domain/path etc information with which the kookie was set and that way it can do things. AND most probably the code on server1 knows those values...

Its difficult to explain but I'm sure you won't have problem in getting what I am trying to say

Regards
Maulin

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值