Java 终止cookie标头中的字符串

Java 终止cookie标头中的字符串,java,cookies,servlets,Java,Cookies,Servlets,我想这是个简单的问题,但我似乎找不到答案 我正在使用cookie类在Java Servlet中编写cookie,该cookie类在响应头中发送到浏览器,如下所示: Set-Cookie: test=somevalue; Domain=.mydomain.org; Expires=Thu, 06-Jan-2011 18:45:20 GMT; Path=/ 我是通过Servlet2.5API中的Cookie类来实现这一点的。我需要在这个字符串的末尾添加“HTTPOnly”,Servlet2.5AP

我想这是个简单的问题,但我似乎找不到答案

我正在使用cookie类在Java Servlet中编写cookie,该cookie类在响应头中发送到浏览器,如下所示:

Set-Cookie: test=somevalue; Domain=.mydomain.org; Expires=Thu, 06-Jan-2011 18:45:20 GMT; Path=/
我是通过Servlet2.5API中的Cookie类来实现这一点的。我需要在这个字符串的末尾添加“HTTPOnly”,Servlet2.5API不支持它。没问题,我只需要手动创建字符串并在末尾附加“HTTPOnly”

然而,在这样做时,我遇到的挑战是,要首先在那里设置“Expires”头,我使用了.setMaxAge(3600),它创建了该字符串的“Expires”部分。但是,因为我不能使用Cookie类,所以我需要创建“Expires”部分的值

那么基本上,如何将“3600”格式化为“Thu,06-Jan-2011 18:45:20 GMT”?

注意:我可能可以用DateFormat找出正确的模式,但我希望有更好的方法。另一个想法是:像以前一样使用Cookie类,然后通过编程将Cookie转换为相应的头字符串,然后在末尾追加“HTTPOnly”。但我不知道有什么方法可以获取Cookie对象并将其转换为相应的字符串值

因此,我可以选择如何获取Cookie对象并通过编程将其转换为相应的字符串值?

谢谢

类似这样:

Date expdate = new Date ();
expdate.setTime (expdate.getTime() + (3600 * 1000));
String cookieExpire = "expires=" + expdate.toGMTString();
...
。。由于togmString()已被弃用

Date expdate= new Date();
expdate.setTime (expdate.getTime() + (3600 * 1000));
DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", java.util.Locale.US);
df.setTimeZone(TimeZone.getTimeZone("GMT"));
String cookieExpire = "expires=" + df.format(expdate);

我在这个问题上没有看到太多的活动,所以我将尝试回答这个问题,以便为将来寻找答案的人提供帮助。然而,如果其他人愿意的话,我会给他们一个参与的机会

所以我考虑了几个选择

1)

Apache Commons HTTPClient项目有一个“DateUtil”类,我希望它可以工作。这提供了方便的方法将日期格式化为几种标准格式,以便在http头中传递日期。。。但是,它们似乎都与servlet容器返回的内容不完全匹配

2)

apachecommons在该项目中还有一个Cookie类,它有一个返回字符串的“toExternalForm”方法。使用它,我想我可能已经能够按照常规创建cookie,调用“toExternalForm”,然后附加“HTTPOnly”。那可能有用,但我没有费心去尝试

3)

我最终决定只使用与Servlet容器返回的内容相匹配的模式,而不管它是否是标准格式。如果它是Servlet容器返回的,那么它应该工作,对吗?为什么不

SimpleDateFormat COOKIE_EXPIRES_HEADER_FORMAT = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss zzz");
COOKIE_EXPIRES_HEADER_FORMAT.setTimeZone(new SimpleTimeZone(0, "GMT"));
Date d = new Date();
d.setTime(d.getTime() + 3600 * 1000); //1 hour
String cookieLifeTime = COOKIE_EXPIRES_HEADER_FORMAT.format(d);
response.setHeader("Set-Cookie", "test=somevalue; Domain=.mydomain.org; Expires=" + cookieLifeTime + "; Path=/; HTTPOnly");

JasonStoltz给出的第一个答案是正确的:

1) Apache Commons HTTPClient项目有一个“DateUtil”类,我希望它可以工作。这提供了方便的方法将日期格式化为几种标准格式,以便在http头中传递日期。。。但是,它们似乎都与servlet容器返回的内容不完全匹配

使用DateTime库获取未来一小时(或任何时间)的日期对象,然后使用ApacheDateUtil类该类根据RFC输出,因此您不必担心它与servlet“通常生成”的内容不匹配-浏览器将尊重RFC

您的代码将如下所示:

// for one hour later (should probably use date libraries in general, this is somewhat awkward)
Date expiresDate = new Date(new Date().getTime() + 3600*1000); 
response.setHeader("Set-Cookie", "Expires=" + DateUtil.formatDate(expiresDate) + ";");

Java 8现在提供了一个适当的日期格式化程序:

OffsetDateTime一小时后
=OffsetDateTime.now(ZoneOffset.UTC)
.加上(持续时间为1小时);
字符串Cookie过期
=DateTimeFormatter.RFC\u 1123\u日期\u时间
.格式(从现在起一小时);
//例如,“2016年11月8日星期二20:15:46 GMT”
此格式对
expires
属性有效,请参阅,该属性将格式定义为RFC 1123日期:

expires av=“expires=”正常cookie日期 正常cookie日期=
谢谢,我很确定“toGMTString”方法已经被弃用了。我最终使用了稍微不同的模式(见我的答案)来匹配Servlet容器生成的内容,我希望找到一种完全避免使用DateFormat的方法。但是,这应该是可行的,没有其他答案,所以我将其标记为答案。在格式化日期标题时,使用java.util.Locale参数调用SimpleDataFormat构造函数非常重要,例如,
new SimpleDataFormat(“dd-MMM-yyyy-kk:mm:ss z”,Locale.US)
FYI,IE10似乎拒绝使用此格式字符串。使用
新的SimpleDataFormat(“EEE,dd-MMM-yyy-HH:mm:ss-zzz”,Locale.ROOT)
修复了它。Cookie的确切规范是出人意料的松散。但是,格式
“EEE,dd-MMM-yyy-HH:mm:ss-zzz”
(空格而不是连字符)是兼容的,并且也是HTTP头()中使用的HTTP日期格式。您的代码段设置了“Expires”头,而不是“Set Cookie”。回答得好,正确。但是我建议使用
OffsetDateTime
而不是
zoneDateTime
来更清楚地了解您的意图。我们这里只涉及UTC,而不是真正的时区,因此
OffsetDateTime
是合适的。真正的时区是UTC的偏移量加上一组处理异常情况的规则,如夏令时(DST)。@BasilBourque,你说得对,
OffsetDateTime
在语义上比
ZonedDateTime
更准确,我已经进行了相应的编辑。我们也可以使用plusDays(x),其中x是整数