简单的问题我想,但我似乎无法找到答案。
我正在使用Cookie类在Java Servlet中编写一个cookie,该类在响应头中发送到浏览器,如下所示:
Set-Cookie: test=somevalue; Domain=.mydomain.org; Expires=Thu, 06-Jan-2011 18:45:20 GMT; Path=/
我是通过Servlet 2.5 API中的Cookie类来完成的。我需要在此String的末尾添加“HTTPOnly”,Servlet 2.5 API不支持。没问题,我只是手动创建String并将“HTTPOnly”追加到最后......
然而,在这样做的过程中,遇到的挑战是首先在那里设置“Expires”标题,我使用了.setMaxAge(3600),它创建了该String的“Expires”部分。但是,由于我无法使用Cookie类,因此我需要创建“Expires”部分的值。
基本上,如何将“3600”格式化为“星期四,2011年1月6日18:45:20 GMT”?
注意:我可能用DateFormat找出正确的模式,但我希望有更好的方法来做到这一点。另一个想法:像以前一样使用Cookie类,然后只是以编程方式将Cookie转换为相应的标题字符串,然后只需将“HTTPOnly”附加到结尾。但我不知道采取Cookie对象并将其转换为相应的String值的任何方法。
所以可选地,我如何获取Cookie对象并以编程方式将其转换为相应的String值?
谢谢!
答案 0 :(得分:20)
这样的事情:
Date expdate = new Date ();
expdate.setTime (expdate.getTime() + (3600 * 1000));
String cookieExpire = "expires=" + expdate.toGMTString();
...
..因为不推荐使用toGMTString()
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 :(得分:9)
Java 8现在提供了一个合适的日期格式化程序DateTimeFormatter.RFC_1123_DATE_TIME:
OffsetDateTime oneHourFromNow
= OffsetDateTime.now(ZoneOffset.UTC)
.plus(Duration.ofHours(1));
String cookieExpires
= DateTimeFormatter.RFC_1123_DATE_TIME
.format(oneHourFromNow);
// E.g. "Tue, 8 Nov 2016 20:15:46 GMT"
此格式对expires
属性有效,请参阅RFC 6265 § 4.1.1,其中将格式定义为RFC 1123日期:
expires-av = "Expires=" sane-cookie-date sane-cookie-date = <rfc1123-date, defined in [RFC2616], Section 3.3.1>
答案 2 :(得分:6)
好吧,我在这个问题上没有看到太多活动,所以我将尝试回答这个问题,以便为将来寻找答案的人提供帮助。但是,如果他们选择的话,我会让其他人有机会参与其中。
所以我考虑了几个选项......
<强> 1)强>
Apache Commons HTTPClient项目有一个“DateUtil”类,我希望它可以工作。 http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/util/DateUtil.html。这提供了方便的方法,将日期格式化为几种标准格式,以便在http标头中传递日期...但是,它们似乎都没有与servlet容器返回的内容完全匹配。
<强> 2)强>
Apache Commons在该项目中也有一个Cookie类,它有一个返回String的“toExternalForm”方法。使用它,我想我可能只是按照惯例创建cookie,调用“toExternalForm”,然后追加“HTTPOnly”。 http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/Cookie.html。这可能有用,但我没有费心去尝试。
第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");
答案 3 :(得分:2)
JasonStoltz给出的第一个答案是正确答案:
1)Apache Commons HTTPClient项目有一个我希望可以工作的“DateUtil”类。 http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/util/DateUtil.html。这提供了方便的方法,将日期格式化为几种标准格式,以便在http标头中传递日期...但是,它们似乎都没有与servlet容器返回的内容完全匹配。
使用DateTime库在将来(或任何时间)获取一个小时的日期对象,然后使用Apache DateUtil类。 该类根据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) + ";");