Session 与 Cookie 的使用是一个既简单又复杂的问题,简单是因为它们本身只是 HTTP 中的一个配置项,在 Servlet 规范中只是对应到一个类而已;复杂则是因为当系统达到需要用到很多的 Cookie 时,我们需要考虑 HTTP 对 Cookie 数量和大小的限制。 Session 也会有同样的问题,当一个应用系统有几百台服务器时,怎样能解决 Session 在多台服务器之间共享的问题呢?
Session 与 Cookie 都是为了保持用户与后端服务器的交互状态。它们各自有其优缺点,例如:使用 Cookie 来传递信息时,随着 Cookie 个数的增多和访问量的增加,它占用的网络带宽也会增大,所以有大访问量是希望用 Session ,但是 Session 的致命弱点是不容易在多台服务器之间共享,这限制了 Session 的使用。
-
理解Cookie
Cookie 的作用通俗的说当一个用户通过 HTTP 访问一个服务器时,这个服务器会将一些 Key/Value 键值对返回给客户端浏览器,并给这些数据加上一些限制条件,在条件符合时这个用户下次访问这个服务器时,数据又被完整地待会给服务器。由于 HTTP 是一种无状态协议,当用户的一次请求访问结束后,后端服务器无法主导下一次来访问的还是不是上一个用户。而当在一个很短的时间间隔内,如果一个用户相关的数据被频繁访问,则可以针对这个数据做缓存,这样可以大大提高数据的访问性能。Cookie 的作用正是如此,由于是同一个客户端发出的请求,每次发出的请求都会带有第一次访问时服务端设置的信息,这样服务器就可以根据 Cookie 值来划分访问的用户了。
Cookie 用一些常见的属性项:
NAME=VALUE 键值对,可以设置要保存的 Key/Value
Expires 过期时间,在设置的某个时间点后该 Cookie 就会失效
Domain 生成该 Cookie 的域名
Path 该 Cookie 是在当前哪个路径下生成的
Secure 如果设置了这个属性,那么只会在SSH连接时才会回传该 Cookie -
Cookie 如何工作
当我们用如下方式创建 Cookie 时:
String getCookie(Cookie[] cookies, String key) {
if(cookies != null) {
for(Cookie cookie : cookies) {
if(cookie.getName().equals(key)) {
return cookie.getValue();
}
}
}
return null;
}
@Override
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws IOException,ServletException {
Cookie[] cookies = request.getCookies();
String userName = getCookie(cookies,"userName");
String userAge = getCookie(cookies,"userAge");
if(userName == null) {
response.addCookie(new Cookie("userName","helloworld"));
}
if(userAge == null) {
response.addCookie(new Cookie("userAge","18"));
}
response.getHeader("Set-Cookie");
}
那么 Cookie 是如何加到 HTTP 的 Header 中的呢?下面来看一下 Tomcat是如何调用 addCookie() 方法的。
通过查找资料可以看出,真正构建 Cookie 是在 org.apache.catalina.Response 类中完成的,调用 generateCookieString() 方法将 Cookie 对象构造成一个键值对形式的字符串,然后将这个字符串命名为 Set-Cookie 添加到 MineHeader中。
以上讲述了在服务端如何创建 Cookie ,下面看一下如何从客户端获取 Cookie。
当我们请求某个 URL 路径时,浏览器会根据这个 URL 路径健符合条件的 Cookie 放在 Request 请求头中传回给服务器,服务器通过 request.getCookies() 来取得所有的 Cookie。
- 使用 Cookie 的限制
Cookie 是 HTTP 头中的一个字段,虽然 HTTP 本身对这个字段并没有多少限制,但是 Cookie 最终还是存储在浏览器中,不同的浏览器对 Cookie 的存储的大小和数量都有一些限制。