当我添加如下cookie时:
FacesContext.getCurrentInstance().getExternalContext().addResponseCookie("Test", "Test", null);
然后它运行良好,但cookie成为会话cookie,其最大年龄为-1
。
当我尝试如下:
Map<String, Object> properties = new HashMap<>();
properties.put("domain", "test");
properties.put("maxAge", 31536000);
properties.put("secure", false);
properties.put("path","/");
FacesContext.getCurrentInstance().getExternalContext().addResponseCookie("Test", "Test", properties);
然后我在任何地方都看不到cookie。我不明白为什么。
我正在使用Tomcat 7。
答案 0 :(得分:26)
您的具体案例失败,因为域名设置错误。 Cookie是特定于域的。您无法在其他域上设置Cookie。如果您未指定域,则它将默认为当前请求URI的域。仅当您打算在常见或不同的子域上设置Cookie时,Cookie#setDomain()
才有用。例如。如果您有foo.example.com
和bar.example.com
,那么您可以通过该方法为其他域设置Cookie,或将域设置为.example.com
(带有前导期!)以在之间共享Cookie这两个子域名。
所以,这应该在你的特定情况下做到:
String name = "cookiename";
String value = "cookievalue";
Map<String, Object> properties = new HashMap<>();
properties.put("maxAge", 31536000);
properties.put("path", "/");
externalContext.addResponseCookie(name, URLEncoder.encode(value, "UTF-8"), properties);
请注意,显式设置路径非常重要,以防您打算在webapp-wide范围内使用cookie,否则默认为当前路径,当在第一次在子文件夹中设置时,该路径当然会失败。任何父文件夹都无法访问此类cookie。上面的另一个答案没有正确考虑到这一点,因为它不必要地错误地重用现有的cookie而不是全新的。另见a.o. In Java servlet, cookie.getMaxAge() always returns -1
关于在JSF中检索cookie,请使用ExternalContext#getRequestCookieMap()
:
Cookie cookie = (Cookie) externalContext.getRequestCookieMap().get(name);
String value = URLDecoder.decode(cookie.getValue(), "UTF-8");
// ...
请注意,我在设置/检索之前对cookie值进行了网址编码/解码,否则您会遇到以下相关问题中提到的问题:Why do cookie values with whitespace arrive at the client side with quotes?和java.lang.IllegalArgumentException: Control character in cookie value or attribute。
尽管如此,我确实同意JSF API在检索和设置cookie方面有些不透明。出于此目的,JSF实用程序库OmniFaces在several useful utility methods中有Faces
utility class,隐式将默认值设置为cookie属性并对值进行URL编码/解码。
// Getting a cookie value.
String value = Faces.getRequestCookie(name);
// Setting a session cookie in current path.
Faces.addResponseCookie(name, value, -1);
// Setting a session cookie in current domain.
Faces.addResponseCookie(name, value, "/", -1);
// Setting a (sub)domain-wide session cookie.
Faces.addResponseCookie(name, value, ".example.com", "/", -1);
// Setting a cookie with max age of 1 year in current domain.
Faces.addResponseCookie(name, value, "/", (int) TimeUnit.DAYS.toSeconds(365));
// Removing a cookie from current domain.
Faces.removeResponseCookie(name, "/");
答案 1 :(得分:22)
试试这个:
public class CookieHelper {
public void setCookie(String name, String value, int expiry) {
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
Cookie cookie = null;
Cookie[] userCookies = request.getCookies();
if (userCookies != null && userCookies.length > 0 ) {
for (int i = 0; i < userCookies.length; i++) {
if (userCookies[i].getName().equals(name)) {
cookie = userCookies[i];
break;
}
}
}
if (cookie != null) {
cookie.setValue(value);
} else {
cookie = new Cookie(name, value);
cookie.setPath(request.getContextPath());
}
cookie.setMaxAge(expiry);
HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
response.addCookie(cookie);
}
public Cookie getCookie(String name) {
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
Cookie cookie = null;
Cookie[] userCookies = request.getCookies();
if (userCookies != null && userCookies.length > 0 ) {
for (int i = 0; i < userCookies.length; i++) {
if (userCookies[i].getName().equals(name)) {
cookie = userCookies[i];
return cookie;
}
}
}
return null;
}
}