Jersey中如何在ContainerResponseContext中更新响应Cookie
问题原因
你原有方案失效的核心原因有两个:
- 手动调用
remove(HttpHeaders.SET_COOKIE)只会清除本次响应中已经添加的Set-Cookie头,和客户端存储的原有Cookie没有关联,也不会影响请求携带的Cookie值 - 没有保证新写入Cookie的
path、domain属性和原有Cookie完全一致,导致浏览器判定为两个不同的Cookie,不会覆盖更新
可行实现方案
不需要额外判断是否为首次请求,每次响应直接覆盖写入同名、同属性的Cookie即可自动刷新过期时间,完整实现如下:
代码实现
import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.core.Cookie; import javax.ws.rs.core.NewCookie; import java.io.IOException; public class SessionCookieRefreshFilter implements ContainerResponseFilter { // 需刷新的Cookie名称 private static final String SESSION_COOKIE_NAME = "user_session"; // Cookie有效期,单位秒,示例为7天 private static final int COOKIE_EXPIRE_SECONDS = 604800; @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { String cookieValue; // 读取请求携带的原有Cookie Cookie existingCookie = requestContext.getCookies().get(SESSION_COOKIE_NAME); if (existingCookie != null) { cookieValue = existingCookie.getValue(); } else { // 首次请求无Cookie时生成新值,替换为自身业务的生成逻辑 cookieValue = java.util.UUID.randomUUID().toString().replace("-", ""); } // 构建新Cookie,重置有效期,path、domain属性必须和原有Cookie完全一致 NewCookie refreshedCookie = new NewCookie( SESSION_COOKIE_NAME, cookieValue, "/", // 匹配原有Cookie的path null, // 匹配原有Cookie的domain,无则留空 1, "session cookie", COOKIE_EXPIRE_SECONDS, null, false, // secure属性按需开启,HTTPS环境建议设为true true // httpOnly属性建议开启,防止XSS窃取 ); // 直接写入响应即可,同名同属性Cookie会自动覆盖,无需手动删除旧的Set-Cookie头 responseContext.getHeaders().add("Set-Cookie", refreshedCookie.toString()); } }
注意事项
- 新Cookie的
name、path、domain三个属性必须和原有Cookie完全一致,否则浏览器会生成新Cookie而不是覆盖更新 - 如果服务需要保留其他Set-Cookie头,不要调用
remove(HttpHeaders.SET_COOKIE)方法,直接写入目标Cookie即可,浏览器会以最后收到的同属性Cookie配置为准
内容的提问来源于stack exchange,提问作者Praveen
相关产品推荐
相关产品推荐

