关于cookie特殊字符
背景:需要从请求中获取某个cookie的内容,在jetty下是正常的,但是tomcat下获取到的该cookie的内容不正确,试了好多次,发现该 cookie的内容从”@“符号之后的部分被截断了。问了好多同事,最后大概了解到”@“不是cookie的合法字符,因此解析出来的cookie的”@ “开始的部分被丢弃了。
--------------------------------------------------------------------------------------
在网上查了下,cookie有以下版本:
版本0:由Netscape公司制定的,也被几乎所有的浏览器支持。Java中为了保持兼容性,目前只支持到版本0,Cookie的内容中不能包含空格,方括号,圆括号,等于号(=),逗号,双引号,斜杠,问号,@符号,冒号,分号。
版本1:根据RFC 2109(http://www.ietf.org/rfc/rfc2109.txt)文档制定的. 放宽了很多限制. 上面所限制的字符都可以使用. 但为了保持兼容性, 应该尽量避免使用这些特殊字符。
--------------------------------------------------------------------------------------
自己写cookie时,应尽量避免使用上述特殊字符。
读别人写的cookie时,如果遇到含特殊字符的cookie内容,tomcat会只保留特殊字符之前的内容,导致cookie的内容不完整。解决方法有两种:
1、修改tomcat配置
在catalina.properties中加入下面这行配置:
org.apache.tomcat.util.http.ServerCookie.ALLOW_HTTP_SEPARATORS_IN_V0=true
tomcat里有很多配置参数,其中org.apache.tomcat.util.http.ServerCookie.ALLOW_HTTP_SEPARATORS_IN_V0
如果设为true,tomcat将会允许cookie的name和value使用http分隔符(tomcat源码中的http分隔符:'\t', ' ', '\"',
'(', ')', ',', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '{',
'}',如果设置了org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR这个参数,'/'也会被作为http分隔符
),如果没有配置这个参数,默认值为false。参数的详细定义见http://tomcat.apache.org/tomcat-7.0-doc/config/systemprops.html。
tomcat是用自己的servlet-api,在tomcat的源码里可以看到。它会读取所有的配置参数,并根据参数判断是否允许cookie使用某些特殊字符。
2、在程序中自己解析cookie
可以从request中获取cookie这个header,得到所有cookie的内容字符串,然后再解析出所需要的cookie的内容,示例代码如下:
public static String getCookieValue(String name, HttpServletRequest
request){
try {
if(name == null)
return "";
String allCookieStr =
request.getHeader("Cookie");
if (allCookieStr != null)
{
name = name+"=";
int begin =
allCookieStr.indexOf(name);
if (begin >= 0)
{
int end = allCookieStr.indexOf(";",
begin);
if (end >= 0) {
return allCookieStr.substring(begin + name.length(),
end);
}else{
return
allCookieStr.substring(fromIndex + name.length());
}
}
}
} catch (Exception e)
{
e.printStackTrace();
}
return "";
}