Http协议是无状态协议,Web服务器没有短期记忆。在有些应用场景(例如:购物车)下,需要跨越多个请求识别同一个客户——客户跟踪,在Web应用中使用Cookie和Session可以做到这一点。
使用HttpSession对象保存跨多个HTTP请求的会话状态。容器使用会话识别客户的原理为:(1)针对客户端的第一个请求,容器会生成一个唯一的会话ID,并通过响应把它返回给客户端;(2)客户端在这个会话以后的请求中都带上这个会话ID;(3)容器看到这个ID后,就会把这个会话与请求相关联。
容器和客户端之间用什么方法交换会话ID信息?
httpsession-api.png
Cookie对象,response.setCookie()方法的入参是对象而不是kv对。Cookie中定义了如下几个关键属性:
private String comment; // ;Comment=VALUE ... describes cookie's use
private String domain; // ;Domain=VALUE ... domain that sees cookie
private int maxAge = -1; // ;Max-Age=VALUE ... cookies auto-expire
private String path; // ;Path=VALUE ... URLs that see the cookie
private boolean secure; // ;Secure ... e.g. use SSL
private boolean httpOnly; // Not in cookie specs, but supported by browsers
cookie最开始的设计目标是支持会话状态,不过也可以定制cookie来完成其他的工作,因为,cookie实际上是在客户端和服务器之间交换的一小段数据(key/value对)。
从cookie中取数据,不能像map一样取,要遍历cookies数组,根据key值相同与否来挑选。这里有一段常用的cookie相关的常用代码:
public String getCookieValueFromReq(String key, Cookie[] cookies) {
String value = "";
try {
if (null != cookies) {
for (Cookie cookie : cookies) {
if (cookie.getName().equalsIgnoreCase(key)) {
value = URLDecoder.decode(cookie.getValue(), "UTF-8");
}
}
}
return value;
} catch (Exception e) {
logger.error("获取cookie异常", e);
}
return "";
}
在单体应用中,会话管理比较简单;在分布式应用中,会话管理比较复杂,常用的方案有以下几种: