[Java] Servlet工作原理之二:Session与Cookie

时间:2021-12-10 11:45:03

(未完成)

一、Cookie与Session的使用简介

1 Cookie

Cookie 用于记录用户在一段时间内的行为,它有两个版本:Version 0 和 Version 1,分别对应两种响应头 Set-Cookie 和 Set-Cookie2,但是 Servlet 规范中不支持 Set-Cookie2 响应头,在实际中 Set-Cookie2 的属性可以设置在 Set-Cookie 中。

Version 0 的属性如下

[Java] Servlet工作原理之二:Session与Cookie

Version 1 的属性如下

[Java] Servlet工作原理之二:Session与Cookie

当访问某个 URL 时,浏览器会根据 URL 将符合条件的 Cookie 放入请求头中,在服务器中通过 HttpServletResquest 的 getCookies() 方法可以获取到客户端发送来的 Cookie 对象的数组,Cookie 的方法如下:

  • public void setValue(String newValue) // 设置 Cookie 的值
  • public void setComment(String purpose) // 用来描述cookie的用途
  • public void setDomain(String pattern) // 指定cookie的域
  • public void setPath(String uri) // 指定的目录中的所有页面以及该目录的子目录中的所有页面都可以看到该cookie
  • public void setMaxAge(int expiry) // 设置最大过期时间,负值则储存在内存中,浏览器关闭时就过期
  • public void setVersion(int v) // 设置 Cookies 版本,0或1
  • public void setSecure(boolean flag) // cookie 是否仅使用安全协议发送,如HTTPS或SSL
  • public String getName()
  • public String getValue()
  • public String getComment()
  • public String getDomain()
  • public String getPath()
  • public int getMaxAge()
  • public int getVersion()
  • public boolean getSecure()
  • public Object clone()

如果需要创建一个 Cookie 对象,只需要 Cookie cookie = new Cookie("username", "tengyunhao") 即可创建,但是自己创建的 Cookie 的 name 不能和它自带属性值的名称一样,否则会抛出异常。当 Cookie 的属性中出现 Version 1 的属性时,则响应头会将 Version 值设为1,属性中出现 TOKEN 字符时(如“\”、“,”等)也会设 Version 值为 1。

2 Session

Cookie 可以用来记录客户端的访问信息,但它储存在客户端中,每次请求时客户端都需要传输这些 Cookie,如果 Cookie 很多就增加了传输的负担,而使用 Session 可以解决这个问题。Session 储存在服务器中,每次客户端只需要传输一个 Session 的 ID,通过这个 ID 来找到客户端对应的 Session,这个 ID 通常以 JSESIONID 为名储存在 Cookie 中,这个 Cookie 储存在内存中,浏览器关闭则过期。

当收到请求时,如果从 Cookie(或请求参数)中能获取 JSESIONID 值,则根据这个值查找 session 对象,如果获取不到 JSESIONID 值或 session 对象已经过期,则创建一个新的 session 对象,并 JSESIONID 值设置到响应头中。HttpSession 是一个接口,它的方法如下:

  • public String getId();
  • public long getCreationTime(); // 返回 session 创建时间
  • public long getLastAccessedTime(); // 客户端最后请求时间
  • public void setMaxInactiveInterval(int interval); // 设置超时时间,单位为秒
  • public int getMaxInactiveInterval();
  • public ServletContext getServletContext();
  • public Enumeration getAttributeNames();
  • public Object getAttribute(String name);
  • public void setAttribute(String name, Object value);
  • public void removeAttribute(String name);
  • public void invalidate(); // 销毁当前 session
  • public boolean isNew();

二、分布式的 Session 框架

从上面可以知道 Session 和 Cookie 各自优点和缺点,在大型的互联网系统中,单独使用两者都不可行。