会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是 Cookie 和 Session。
一、Cookie
Cookie 通过在客户端记录信息确定用户的身份,Session通过在服务器端记录信息确定用户身份
1、Cookie简介:
-
- Cookie 意为“甜饼”,有 W3C组织提出。
- Cookie的出现:由于HTTP协议是一种无状态的协议,服务器单从网络连接上无从知道客户身份,为了解决此问题,于是出现了Cookie
- Cookie实际上是一小段的文本信息,客户端请求服务器,如果服务器需要记录该用户状态,就使用 response 向客户端浏览器颁发一个 Cookie,客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同Cookie一同提交给服务器,服务器会检查该Cookie,以此来辨认用户的状态。服务器还可以根据需要修改Cookie的内容
2、Cookie的有效期:
-
- Cookie的 maxAge 决定着 Cookie的有效期,单位为:秒/s(Second)
- Cookie中通过 getMaxAge() 方法和 setMaxAge(int maxAge) 方法来读写 maxAge属性
- 如果 maxAge 属性为正数,则表示该 Cookie会在 maxAge 秒之后自动失效。浏览器会将 maxAge 为正数的 Cookie持久化,即 写到对应的Cookie文件中。无论客户关闭了浏览器还是电脑,只要在 maxAge 秒之前,登录网站时该 Cookie仍然有效
- 如果 maxAge 为负数,则表示该 Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该 Cookie立即失效。 maxAge 为负数的 Cookie,为临时性 Cookie,不会被持久化,也不会被写到 Cookie文件中。 Cookie 信息保存在浏览器内存中,因此关闭浏览器该 Cookie就消失了。 Cookie 默认的 maxAge 值 为 -1
- 如果 maxAge 为 0,则表示删除该 Cookie。 Cookie机制没有提供删除 Cookie的方法,因此通过设置该 Cookie即时失效实现删除 Cookie的效果。 失效的Cookie会被浏览器从 Cookie文件或者 内存中删除
//新建 Cookie对象
Cookie cookie = new Cookie("userName","hello");
//设置生命周期为 0, 不能为 负数
cookie.setMaxAge(0);
//必须执行下面这一句代码
response.addCookie(cookie);
- response 对象提供的 Cookie 操作方法只有一个添加操作 addCookie(Cookie cookie) 。想要修改 Cookie 只能使用一个同名的 Cookie来覆盖原来的Cookie,达到修改的目的。删除时是需要把 maxAge 修改为 0 即可
- Cookie的 maxAge 决定着 Cookie的有效期,单位为:秒/s(Second)
3、Cookie 的修改、删除:
-
- Cookie 并不提供修改、删除操作,如果需要新建一个 同名的 Cookie,只需要新建一个同名的Cookie,并添加到 response 中覆盖原来的Cookie
- 如果想要删除某个Cookie,只需要新建一个同名的Cookie,并将maxAge设置为0,并添加到response中覆盖原来的Cookie。注意:是 0 而不是 负数。负数代表其他意义
- 注意:修改、删除Cookie时,新建的Cookie出value和maxAge之外的所有属性(name、path、domain等)都要与原Cookie完全一样,否则,浏览器会将其视为两个不同的Cookie,不会覆盖,导致修改或删除失败!
二、Session
1、Session简介:
-
- Session是另一种记录客户状态的机制,不同的是 Cookie保存在浏览器中,二Session保存在服务器上。
- 客户端浏览器访问服务器的时候,服务器吧客户端信息以某种形式记录在服务器上,这就是Session,客户端浏览器再次访问时只需要从该Session中查找客户的状态就可以了
- 如果说 Cookie 机制是通过检查客户身上的“通行证”来确定客户的身份的话,那么 Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。
- Session相当于程序在服务器上建立一份客户档案,客户来访时只需要查询客户档案表就可以了
- Session对应的类为 javax.servlet.http.HttpSession类,每一个来访者对应一个Session对象,所有该客户的状态信息都保存在这个Session对象里。Session对象是在客户端第一次请求服务器的时候创建的。
- Session是一种 key-value 的属性对。可以通过 getAttribute(String key) 和 setAttribute(String key, Object value) 方法来读写客户状态信息。在Servlet中使用request.getSession() 方法来获取该客户的Session。
//获取Session对象
HttpSession session = request.getSession();
//设置Session中的属性
session.setAttribute("loginTime", new Date());
//获取session属性
out.println("登录时间为:" + (Date)session.getAttribute("loginTime"));
- request 还可以使用 getSession(boolean create) 来获取session。
- 当 create 为 true 时,当客户端的Session不存在,则会先创建Session对象然后再将其返回
2、Session的生命周期:
-
- Session通过调用 invalidate() 方法来使Session对象失效
- HttpSession的常用方法:
- void setAttribute(String key, Object value):设置Session属性
- String getAttribute(String key):返回Session属性
- Enumeration getAttributeNames():返回Session中存在的属性名
- void removeAttribute(String key): 移除Session属性
- String getId():返回Session的 ID,该ID由服务器自动创建,不会重复
- long getCreationTime(): 返回Session的创建日期,返回类型为long,常被转换为Date类型。 eg: Date createTime = new Date(session.getCreationTime())
- long getLastAccessedTime(): 返回Session的最后活跃时间,返回类型为long
- int getMaxInactiveInterval():返回Session的超时时间,单位为:秒;超过该时间没有访问,服务器会认为该Session失效
- void setMaxInactiveInterval(int second): 设置Session的超时时间,单位为:秒
- boolean isNew():返回该Session是否是新创建的
- void invalidate():使该 Session 失效
- 小提示:Tomcat中Session的默认失效时间为 20 分钟,可通过 setMaxInactiveInterval(int seconds) 修改超时时间。可以修改 web.xml 改变Session的默认超时时间:
<session-config>
<!-- 此处的单位为:分钟 -->
<session-timeout>60</session-timeout>
</session-config>
3、URL地址重写
-
- 当客户端浏览器将 Cookie功能禁用或者不支持Cookie时,Java Web 提供了另一种解决方案: URL地址重写
- 原理:将该用户Session的id信息重写到URL地址中,服务器能够解析重写后的URL获取Session的id。这样即使客户端浏览器不支持 Cookie,也可以使用Session来记录用户的状态
- HttpServletResponse类提供了 encodeURL(String url):实现URL地址重写
4、Session中禁止使用 Cookie
-
- 方式一:找到项目中的 META-INF 目录(与WEB-INF同级,如果没有则自己新建一 个),新建一个 context.xml 文件(如果有就打开编辑):编辑内容为:
<?xml version='1.0' encoding='UTF-8' ?>
<Context path="/项目名称" cookies="false"> </Context>
- 方式二:修改Tomcat全局的 conf/context.xml 文件:
<Context cookies="false">
</Context>
- 注意:该配置只是禁止Session使用Cookie作为识别标志,并不能阻止其他的Cookie读写,也就是说服务器不会自动维护名为 JSESSIONID 的Cookie了,但程序中仍然可以读写其他的Cookie
- 方式一:找到项目中的 META-INF 目录(与WEB-INF同级,如果没有则自己新建一 个),新建一个 context.xml 文件(如果有就打开编辑):编辑内容为: