近日使用Tomcat调试的时候,使用response写入一个Cookie,发现Cookie的值带上了双引号,百思不得其解,查找源码发现Tomcat在写入Cookie值有"/" 的时候,为避免错误,Tomcat做了以下处理:
org.apache.tomcat.util.http.ServerCookie
- <span> private static void maybeQuote (StringBuffer buf, String value) {
- if (value==null || value.length()==0) {
- buf.append("\"\"");
- } else if (CookieSupport.alreadyQuoted(value)) {
- buf.append('"');
- buf.append(escapeDoubleQuotes(value,1,value.length()-1));
- buf.append('"');
- } <span style="color: #ff0000;">else if (CookieSupport.isHttpToken(value) &&
- !CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 ||
- CookieSupport.isV0Token(value) &&
- CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0)</span> {
- buf.append('"');
- buf.append(escapeDoubleQuotes(value,0,value.length()));
- buf.append('"');
- } else {
- buf.append(value);
- }
- }
- </span>
查询Tomcat文档,解释如下:
org.apache.catalina. STRICT_SERVLET_COMPLIANCE
If this is true
the following actions will occur:
- any wrapped request or response object passed to an application dispatcher will be checked to ensure that it has wrapped the original request or response. (SRV.8.2 / SRV.14.2.5.1)
- a call to
Response.getWriter()
if no character encoding has been specified will result in subsequent calls toResponse.getCharacterEncoding()
returningISO-8859-1
and theContent-Type
response header will include acharset=ISO-8859-1
component. (SRV.15.2.22.1) - every request that is associated with a session will cause the session's last accessed time to be updated regardless of whether or not the request explicitly accesses the session. (SRV.7.6)
- cookies will be parsed strictly, by default v0 cookies will not work with any invalid characters.
If set tofalse
, any v0 cookie with invalid character will be switched to a v1 cookie and the value will be quoted. - the path in
ServletContext.getResource
/getResourceAsStream
calls must start with a "/".
If set tofalse
, code likegetResource("myfolder/myresource.txt")
will work.
If this is true
the default value will be changed for:
org.apache.catalina.connector.Request. ALLOW_EMPTY_QUERY_STRING
property- The
webXmlValidation
attribute of any Context element. - The
webXmlNamespaceAware
attribute of any Context element. - The
tldValidation
attribute of any Context element.
If not specified, the default value of false
will be used.
解决办法:
在catalina.properties里边增加一行:
org.apache.catalina.STRICT_SERVLET_COMPLIANCE=true
或者自行修改源码
影响版本:暂时确认有Tomcat 6、7