JavaWeb 之 Cookie 和 Session
Cookie
由于 Http 是一种无状态的协议,服务器单从网络连接上无从知道客户身份。
会话跟踪是 Web 程序中常用的技术,用来跟踪用户的整个会话。常用会话跟踪技术是 Cookie 与 Session。
Cookie 是什么
Cookie 实际上是存储在客户端上的文本信息,并保留了各种跟踪的信息。
Cookie 工作步骤:
- 客户端请求服务器,如果服务器需要记录该用户的状态,就是用 response 向客户端浏览器颁发一个 Cookie。
- 客户端浏览器会把 Cookie 保存下来。
- 当浏览器再请求该网站时,浏览器把该请求的网址连同 Cookie 一同提交给服务器。服务器检查该 Cookie,以此来辨认用户状态。
注:Cookie 功能需要浏览器的支持,如果浏览器不支持 Cookie 或者 Cookie 禁用了,Cookie 功能就会失效。
Java 中把 Cookie 封装成了javax.servlet.http.Cookie类。
Cookie 类中的方法
| 方法 | 功能 |
|---|---|
| public void setDomain(String pattern) | 该方法设置 cookie 适用的域。 |
| public String getDomain() | 该方法获取 cookie 适用的域。 |
| public void setMaxAge(int expiry) | 该方法设置 cookie 过期的时间(以秒为单位)。如果不这样设置,cookie 只会在当前 session 会话中持续有效。 |
| public int getMaxAge() | 该方法返回 cookie 的最大生存周期(以秒为单位),默认情况下,-1 表示 cookie 将持续下去,直到浏览器关闭。 |
| public String getName() | 该方法返回 cookie 的名称。名称在创建后不能改变。 |
| public void setValue(String newValue) | 该方法设置与 cookie 关联的值。 |
| public String getValue() | 该方法获取与 cookie 关联的值。 |
| public void setPath(String uri) | 该方法设置 cookie 适用的路径。如果您不指定路径,与当前页面相同目录下的(包括子目录下的)所有 URL 都会返回 cookie。 |
| public String getPath() | 该方法获取 cookie 适用的路径。 |
| public void setSecure(boolean flag) | 该方法设置布尔值,向浏览器指示,只会在 HTTPS 和 SSL 等安全协议中传输此类 Cookie。 |
| public void setComment(String purpose) | 该方法规定了描述 cookie 目的的注释。该注释在浏览器向用户呈现 cookie 时非常有用。 |
| public String getComment() | 该方法返回了描述 cookie 目的的注释,如果 cookie 没有注释则返回 null。 |
Cookie 的有效期
Cookie的maxAge决定着 Cookie 的有效期,单位为秒。
如果 maxAge 为 0,则表示删除该 Cookie;
如果为负数,表示该 Cookie 仅在本浏览器中以及本窗口打开的子窗口内有效,关闭窗口后该 Cookie 即失效。
Cookie 中提供getMaxAge()和setMaxAge(int expiry)方法来读写maxAge属性。
Session
Session 是什么
不同于 Cookie 保存在客户端浏览器中,Session 保存在服务器上。
如果说 Cookie 机制是通过检查客户身上的“通行证”来确定客户身份的话,那么 Session 机制就是通过检查服务器上的“客户明细表”来确认客户身份。
Session 对应的类为 javax.servlet.http.HttpSession 类。Session 对象是在客户第一次请求服务器时创建的。
Session 类中的方法
javax.servlet.http.HttpSession 类中的方法:
| 方法 | 功能 |
|---|---|
| public Object getAttribute(String name) | 该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null。 |
| public Enumeration getAttributeNames() | 该方法返回 String 对象的枚举,String 对象包含所有绑定到该 session 会话的对象的名称。 |
| public long getCreationTime() | 该方法返回该 session 会话被创建的时间,自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。 |
| public String getId() | 该方法返回一个包含分配给该 session 会话的唯一标识符的字符串。 |
| public long getLastAccessedTime() | 该方法返回客户端最后一次发送与该 session 会话相关的请求的时间自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。 |
| public int getMaxInactiveInterval() | 该方法返回 Servlet 容器在客户端访问时保持 session 会话打开的最大时间间隔,以秒为单位。 |
| public void invalidate() | 该方法指示该 session 会话无效,并解除绑定到它上面的任何对象。 |
| public boolean isNew() | 如果客户端还不知道该 session 会话,或者如果客户选择不参入该 session 会话,则该方法返回 true。 |
| public void removeAttribute(String name) | 该方法将从该 session 会话移除指定名称的对象。 |
| public void setAttribute(String name, Object value) | 该方法使用指定的名称绑定一个对象到该 session 会话。 |
| public void setMaxInactiveInterval(int interval) | 该方法在 Servlet 容器指示该 session 会话无效之前,指定客户端请求之间的时间,以秒为单位。 |
Session 的有效期
由于会有越来越多的用户访问服务器,因此 Session 也会越来越多。为防止内存溢出,服务器会把长时间没有活跃的 Session 从内存中删除。
Session 的超时时间为maxInactiveInterval属性,可以通过getMaxInactiveInterval()、setMaxInactiveInterval(longinterval)来读写这个属性。
Tomcat 中 Session 的默认超时时间为 20 分钟。可以修改 web.xml 改变 Session 的默认超时时间。
例:
1 | <session-config> |
Cookie vs Session
存取方式
Cookie 只能保存ASCII字符串,如果需要存取 Unicode 字符或二进制数据,需要进行UTF-8、GBK或BASE64等方式的编码。
Session 可以存取任何类型的数据,甚至是任何 Java 类。可以将 Session 看成是一个 Java 容器类。
隐私安全
Cookie 存于客户端浏览器,一些客户端的程序可能会窥探、复制或修改 Cookie 内容。
Session 存于服务器,对客户端是透明的,不存在敏感信息泄露的危险。
有效期
使用 Cookie 可以保证长时间登录有效,只要设置 Cookie 的maxAge属性为一个很大的数字。
而 Session 虽然理论上也可以通过设置很大的数值来保持长时间登录有效,但是,由于 Session 依赖于名为JESSIONID的 Cookie,而 Cookie JESSIONID的maxAge默认为-1,只要关闭了浏览器该 Session 就会失效,因此,Session 不能实现信息永久有效的效果。使用 URL 地址重写也不能实现。
服务器的开销
由于 Session 是保存在服务器的,每个用户都会产生一个 Session,如果并发访问的用户非常多,会产生很多的 Session,消耗大量的内存。
而 Cookie 由于保存在客户端浏览器上,所以不占用服务器资源。
浏览器的支持
Cookie 需要浏览器支持才能使用。
如果浏览器不支持 Cookie,需要使用 Session 以及 URL 地址重写。
需要注意的事所有的用到 Session 程序的 URL 都要使用response.encodeURL(StringURL) 或response.encodeRediretURL(String URL)进行 URL 地址重写,否则导致 Session 会话跟踪失效。
跨域名
- Cookie 支持跨域名。
- Session 不支持跨域名。







