Session 会话机制

1、简介

     session: 域对象,就是在不同资源之间共享数据

     四大域对象:

          pageContext,request、session、application

          本页面、同一次请求、同一次会话(浏览器打开-关闭)、整个项目(只要服务器不关闭)

    

     session:在同一次会话共享数据。

     session.setAttribute(key,value);//设置数据,Object value

     Object value = session.getAttribute(key);//获取数据

     session.removeAttribute(key);//移除数据的

    

2、获取session

     1)、request.getSession();//获取到session对象

     2)、JSP页面有隐含的session对象。我们直接拿来使用

     服务器创建session对象。

     session每个会话都有自己的session

    

     session在获取的时候,如果是新的会话,服务器会给会话创建一个新的session对象

     如果是旧的会话,会只用之前获取到的session

 

3、session的创建

     服务器创建session。

     服务器会为每个会话创建他对应的session。在第一次获取session对象的时候才会创建session对象。

 

4、会话控制原理

     1)、HTTP协议是一个无状态的协议。

          无法识别多个请求是否有关联关系。

          服务器无法识别请求来自于哪个用户。

          服务器可能就不知道他创建的session对象应该属于谁的。

    

     第一次获取session对象。没有能标识用户身份的内容

          请求-》不能标识用户身份

          响应:多了一个字段

               服务器命令保存的cookie就是创建的session对象的id值

               Set-Cookie: JSESSIONID=D62C83CD3A285840D469C44636849EC0; Path=/13.Session

               命令浏览器去保存一个cookie。浏览器就会保存好cookie。

               浏览器下次访问会带上这个cookie。

               Cookie: JSESSIONID=D62C83CD3A285840D469C44636849EC0 

     第二次获取session对象。

          请求头中多了一个字段:

               //浏览器带的这个字段就是session对象的id值

               Cookie: JSESSIONID=D62C83CD3A285840D469C44636849EC0

    

     服务器获取session对象

               request.getSession();

          1、request中带了一个名为JSESSIONID=D62C83CD3A285840D469C44636849EC0的cookie

          2、服务器request.getSession();获取session对象会判断

          3、服务器取出JSESSIONID的值(表示的是session对象的id值)。

          4、服务器就会按照这个id值查找之前创建的所有的session对象,哪个session的id是对应的值,便将它返回。

          5、将之前创建的对象返回。

         

     会话控制原理:

          1)浏览器获取session对象以用来保存或者获取数据

          2)服务器会根据请求中携带的JSESSIONID这个Cookie,来查找对应的session对象

          3)找到返回这个session给你用

          4)没找到创建一个新的session对象,并且创建还创建了一个Cookie,名叫JESSIONID,值是session对象的id值

          5)以后再访问服务器获取session对象。重复步骤2开始

    

     session对象创建:

          服务器会为每个会话创建他对应的session。

          在第一次获取session对象的时候才会创建session对象。

          如果整个项目运行过程中不需要session对象,就不会创建。

         

5、session对象是创建好默认保存在内存中。

    

          session对象需要销毁。

          销毁:

               会话关闭(浏览器关闭)需要销毁session。

               浏览器关闭服务器并不会销毁session。

               session的销毁是服务器做的。

              

     session默认的生存时间。1800秒:代表session在1800秒不使用就会销毁。

     在服务器web.xml中

    

        30

   

 

    session.getMaxInactiveInterval();

   

    1)第一次发请求获取session,根据JSESSIONID判断。

    2)服务器返回一个新的session,命令浏览器保存JSESSIONID这个cookie

         Set-Cookie: JSESSIONID=D60840CD71FAC53EACD5B2506C27F1E6

         session只有3秒

    3)再来获取session。带上JSESSIONID。

         Cookie:JSESSIONID=D60840CD71FAC53EACD5B2506C27F1E6

    4)根据带来的JSESSIONID寻找session对象的时候没有找到(session3秒后销毁了)

         创建了一个新的session对象,响应:Set-Cookie:JSESSIONID=146246FF5A0DE3BBC3ACB6A02FA01CA8;

         我们通过下面方法指定session的最大不活动时间,也就是多少秒不使用后过期

         负数:session永不过期

         0和整数:session多少秒不使用后过期

          session.setMaxInactiveInterval(3);

          使session立即失效

         

   为什么每次打开浏览器是一次新会话?是session对象没了吗?

         session实际要维持30分钟。

         这个现象根本原因:不是session没有了,

         而是cookie没了。我们保存JSESSIONID这个cookie的时候。cookie默认的生存时间是一次会话,也就是浏览器关闭就没了,

        而下次我们要获取session,之前浏览器关闭了,cookie没了,所以获取session的时候。不会携带jSESSIONID这个cookie,

        所以服务器会创建新的session。

    

     默认现象创建新session不是因为session对象没了,而是cookie没了。

     默认会话期间的cookie其实是保存在浏览器进程中的。

     我们也可以持久化保存cookie。cookie才会被保存在硬盘中。

    

    

6、浏览器禁用cookie,通过URL重写技术

     JSESSIONID=44E065DA42AA2E3FCAD92A279EFF38D3

     user=admin

 

     JSESSIONID=1D1EA4DC6E300F695F9115CA7AA52099;新的         

     1)我们可以通过URL重写的手段来继续带上JSESSIONID    

      Session/target.jsp;jsessionid=44E065DA42AA2E3FCAD92A279EFF38D3    

     在url后面分号带上jsessionid=44E065DA42AA2E3FCAD92A279EFF38D3    

 

     2)

    url重写  路径应该带上项目名

    如果浏览器禁用了cookie

     encodeURL会在我们要访问的地址后面加上  ;jsessionid=xxx;

     如果浏览器没禁用cookie

     encodeURL不会去改造访问路径

     response.encodeURL(request.getContextPath()+"/target.jsp")

 

     3)标签库中有个标签  c:url 用来重写url地址

     因为url重写机制不太安全,使用较少。

    

7.session活化钝化

          1)服务器停止session去哪儿了

         

          钝化:把session从内存序列化到磁盘

               1、服务器停止,session以及他里面所有的数据都会序列化到磁盘中。

               保存为一个SESSIONS.ser文件。位置在服务器/work/../../自己的项目根目录

               2、当大量session存在的时候将一些不经常使用的session先钝化起来。

                    下次使用的时候再活化

               3、当session超过一定不使用时间(30分钟内)后也会钝化。

              

          活化:把session从磁盘反序列化加载到内存。

               服务器启动,session会从磁盘反序列化到内存中

               钝化后的session对象再次使用就会活化。

 

          对象要能同session一起活化钝化必须实现序列化接口

 

8、session典型应用。

     session.setAttribute(key,value);//在会话域中共享数据

     session.getAttribute(key);

    

     1)用户登陆和退出。将用户信息放在session域中。

          整个会话期间都能获取到用户数据

     2)防止表单重复提交

   

     表单重复提交

     1、提交数据以后,直接刷新页面会提交上次请求。

          因为转发来到页面,导致浏览器从请求发起到请求完成页面响应到内容,浏览器的地址栏没变。

          解决:可以将转发改为重定向。

          但是2、3情况不能防止    

    

     2、网速慢的情况下,用户不知道,多次点击提交按钮。将同一个请求又提交多次

          根本原因是按钮能点击无数次。我们只需要将按钮做成只能点击一次。

          var btn = document.getElementById("subBtn");

          2、绑定单击事件

          btn.onclick = function(){

          3、将按钮设置为不可用  submitObject.disabled=true|false

               this.disabled = true;//禁用,还会阻止表单提交

          4、找到表单,手动提交

               var formEle = document.getElementById("form1");

               //提交表单

               formEle.submit();

          };

         

          不能解决问题1、不能解决问题3

    

     3、用户点击后退按钮,回到之前页面,之前的数据还在,再次提交

     深入底层分析:

          表单重复提交的根本原因。两次请求的内容都是相同的。

          1、刷新就是将上次请求再发一遍。所以多次请求都是一模一样的

          2、多次点击提交按钮。也是发送相同的请求内容。

          3、用户后退,发送的内容和上几次都是一样的。

         

          HTTP协议是一个无状态协议。

          服务器无法识别上次的请求和这次的请求是否同一请求(请求里面的所有东西都一样)。

 

          只要服务器知道两次请求是同一个请求即可。如果第二次请求过来和上次的是一模一样的,

          服务器就可以拒绝处理

         

     如何让服务器知道两次请求是同一请求。

          令牌机制

          虎符:

               两半。

               皇帝手中一半

               将军手中一半

               将军必须两半和一起你对比成功才能调兵遣将。

              

          我们也可以创建一个令牌。

               可以创建两份。

 

               浏览器交一份

               服务器交一份

              

               每次提交请求,浏览器可以带上她的令牌,服务器处理请求之前验证浏览器带的令牌,是不是正确的。

               如果正确则处理请求,否则拒绝处理。

         

          表单重复提交多次,每次的数据都是一模一样的。(根据重复提交的特点);

          1)访问页面的时候可以创建两个令牌。这两个令牌一模一样。给浏览器一份,给服务器一份

          2)浏览器访问服务器提交表单的时候带上她的令牌

          3)服务器处理请求之前先看一看令牌。如果和自己的一样就处理请求, 服务器令牌一但用过一次立即作废

          4)以后重复提交表单的时候令牌也是上次的,而服务器的令牌已经变了,验证失败就不能提交数据

              

你可能感兴趣的:(java,基础知识)