什么是Session
- 使用Cookie和附加URL参数都可以将上一次请求的状态信息传递到下一次请求中,但是如果传递的状态信息较多,将极大降低网络传输效率和增大服务器端程序处理的难度。
- Session技术是一种将会话状态保存在服务器端的技术 ,它可以比喻成是医院发放给病人的病历卡和医院为每个病人保留的病历档案的结合方式 。
- 客户端需要接收、记忆和回送 Session的会话标识号,Session可以且通常是借助Cookie来传递会话标识号。
Session跟踪机制
- Servlet API规范中定义了一个HttpSession接口,HttpSession接口定义了各种管理和操作会话状态的方法。
- HttpSession对象是保持会话状态信息的存储结构,一个客户端在WEB服务器端对应一个各自的HttpSession对象。
- WEB服务器并不会在客户端开始访问它时就创建HttpSession对象,只有客户端访问某个能与客户端开启会话的Servlet程序时,WEB应用程序才会创建一个与该客户端对应的HttpSession对象。
- WEB服务器为HttpSession对象分配一个独一无二的会话标识号,然后在响应消息中将这个会话标识号传递给客户端。客户端需要记住会话标识号,并在后续的每次访问请求中都把这个会话标识号传送给WEB服务器,WEB服务器端程序依据回传的会话标识号就知道这次请求是哪个客户端发出的,从而选择与之对应的HttpSession对象。
- WEB应用程序创建了与某个客户端对应的HttpSession对象后,只要没有超出一个限定的空闲时间段,HttpSession对象就驻留在WEB服务器内存之中,该客户端此后访问任意的Servlet程序时,它们都使用与客户端对应的那个已存在的HttpSession对象。
- HttpSession接口中专门定义了一个setAttribute方法来将对象存储到HttpSession对象中,还定义了一个getAttribute方法来检索存储在HttpSession对象中的对象,存储进HttpSession对象中的对象可以被属于同一个会话的各个请求的处理程序共享。
- Session是实现网上商城的购物车的最佳方案,存储在某个客户Session中的一个集合对象就可充当该客户的一个购物车。
Session超时管理
- WEB服务器无法判断当前的客户端浏览器是否还会继续访问,也无法检测客户端浏览器是否关闭,所以,即使客户已经离开或关闭了浏览器,WEB服务器还要保留与之对应的HttpSession对象。
- 随着时间的推移而不断增加新的访问客户端,WEB服务器内存中将会因此积累起大量的不再被使用的HttpSession对象,并将最终导致服务器内存耗尽。
- WEB服务器采用“超时限制”的办法来判断客户端是否还在继续访问,如果某个客户端在一定的时间之内没有发出后续请求,WEB服务器则认为客户端已经停止了活动,结束与该客户端的会话并将与之对应的HttpSession对象变成垃圾。
- 如果客户端浏览器超时后再次发出访问请求,WEB服务器则认为这是一个新的会话的开始,将为之创建新的HttpSession对象和分配新的会话标识号。
- 会话的超时间隔可以在web.xml文件中设置,其默认值由Servlet容器定义。
<session-timeout>30</session-timeout>
</session-config>
在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象)
注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。
Session和Cookie的主要区别在于:
- Cookie是把用户的数据写给用户的浏览器。
- Session技术把用户的数据写到用户独占的session中。
关掉IE后,在开IE,还能看到物品
IE禁用Cookie后的session处理
实验演示禁用Cookie后servlet共享数据导致的问题。
解决方案:URL重写
- response. encodeRedirectURL(java.lang.String url) 用于对sendRedirect方法后的url地址进行重写。
- response. encodeURL(java.lang.String url)用于对表单action和超链接的url地址进行重写
情况一:没有禁用cookie
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <title>SessionDemo.html</title>
- <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
- <meta http-equiv="description" content="this is my page">
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
- </head>
- <body>
- <a href="./SessionDemo1">购买</a><br>
- <a href="./SessionDemo2">结账</a><br>
- </body>
- </html>
servlet服务:
- package com.hbsi.session;
- import java.io.IOException;
- import java.io.PrintWriter;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- public class SessionDemo1 extends HttpServlet {
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = response.getWriter();
- HttpSession session = request.getSession();
- session.setAttribute("name","iphone");
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- }
- }
- package com.hbsi.session;
- import java.io.IOException;
- import java.io.PrintWriter;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- public class SessionDemo2 extends HttpServlet {
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = response.getWriter();
- HttpSession session = request.getSession();
- String value = (String) session.getAttribute("name");
- out.print("您购买的商品是:"+value);
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- }
- }
情况二:
不小心关闭了浏览器
- package com.hbsi.session;
- import java.io.IOException;
- import java.io.PrintWriter;
- import javax.servlet.ServletException;
- import javax.servlet.http.Cookie;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- public class SessionDemo1 extends HttpServlet {
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = response.getWriter();
- HttpSession session = request.getSession();
- //不小心关闭了浏览器
- String id = session.getId();
- Cookie cookie = new Cookie("JSESSIONID",id);
- cookie.setMaxAge(30*60);
- response.addCookie(cookie);
- session.setAttribute("name","手机");
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- }
- }
情况三:cookie被禁用的情况下
在C:\Users\DELL\AppData\Roaming\Microsoft\Windows\Cookies下,删除所有cookies
- package com.hbsi.session;
- import java.io.IOException;
- import java.io.PrintWriter;
- import javax.servlet.ServletException;
- import javax.servlet.http.Cookie;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- public class SessionDemo1 extends HttpServlet {
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = response.getWriter();
- HttpSession session = request.getSession();
- /*//不小心关闭了浏览器
- String id = session.getId();
- Cookie cookie = new Cookie("JSESSIONID",id);
- cookie.setMaxAge(30*60);
- response.addCookie(cookie);*/
- session.setAttribute("name","手机");
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- }
- }
- package com.hbsi.session;
- import java.io.IOException;
- import java.io.PrintWriter;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class StopCookieSession extends HttpServlet {
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = response.getWriter();
- request.getSession();
- String url1 = response.encodeRedirectURL("SessionDemo1");
- String url2 = response.encodeRedirectURL("SessionDemo2");
- out.print("<a href='"+url1+"'>购买</a>");
- out.print("<a href='"+url2+"'>结账</a>");
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- }
- }
第二次运行:
硬盘也没有存储cookie
情况4:禁用cookie,不小心关闭了
无法实现