session的机制



http是无状态的协议,客户每次读取web页面时,server都打开新的会话,并且server也不会自己主动维护客户的上下文信息,那么要怎么才干实现会话跟踪呢?session就是一种保存上下文信息的机制,它是针对每个用户的,变量的值保存在server端,通过SessionID来区分不同的客户,session是以cookie或URL重写为基础的,默认使用cookie来实现,系统会创造一个名为JSESSIONID的输出返回给clientCookie保存。



保存session id的几种方式



A.保存session id的方式能够採用cookie,这样在交互过程中浏览器能够自己主动的依照规则把这个标识发送给server。

B.因为cookie可以被人为的禁止,必须有其他的机制以便在cookie被禁止时仍然可以把session id传递回server,常常採用的一种技术叫做URL重写,就是把session id附加在URL路径的后面,附加的方式也有两种,一种是作为URL路径的附加信息,还有一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终保持状态,就必须在每一个client可能请求的路径后面都包括这个session id。

C.还有一种技术叫做表单隐藏字段。就是server会自己主动改动表单,加入一个隐藏字段,以便在表单提交时可以把session id传递回server。



session何时被删除



session在下列情况下被删除:

A.程序调用HttpSession.invalidate()

B.距离上一次收到client发送的session id时间间隔超过了session的最大有效时间

C.server进程被停止



再次注意关闭浏览器仅仅会使存储在client浏览器内存中的session cookie失效,不会使server端的session对象失效。



URL重写有什么缺点



对全部的URL使用URL重写,包含超链接,form的action,和重定向的URL。每一个引用你的网站的URL,以及那些返回给用户的URL(即使通过间接手段,比方server重定向中的Location字段)都要加入额外的信息。

这意味着在你的网站上不能有不论什么静态的HTML页面(至少静态页面中不能有不论什么链接到网站动态页面的链接)。因此,每一个页面都必须使用servlet或JSP动态生成。即使全部的页面都动态生成,假设用户离开了会话并通过书签或链接再次回来,会话的信息都会丢失,由于存储下来的链接含有错误的标识信息-该URL后面的SESSION ID已经过期了。



使用隐藏的表单域有什么缺点



仅当每一个页面都是有表单提交而动态生成时,才干使用这样的方法。单击常规的<A HREF..>超文本链接并不产生表单提交,因此隐藏的表单域仅仅能用于一系列特定的操作中,比方在线商店的结账过程。



怎样将信息与会话关联起来



setAttribute会替换不论什么之前设定的值;假设想要在不提供不论什么取代的情况下移除某个值,则应使用removeAttribute。这种方法会触发全部实现了HttpSessionBindingListener接口的值的valueUnbound方法。



会话属性的类型有什么限制吗



一般会话属性的类型仅仅要是Object就能够了。除了null或基本类型,如int,double,boolean。

假设要使用基本类型的值作为属性,必须将其转换为对应的封装类对象



使用isNew来推断用户是否为新旧用户的错误做法



public boolean isNew()方法假设会话尚未和客户程序(浏览器)发生不论什么联系,则这种方法返回true,这通常是由于会话是新建的,不是由输入的客户请求所引起的。

但假设isNew返回false,仅仅只是是说明他之前以前訪问该Web应用,并不代表他们曾訪问过我们的servlet或JSP页面。

由于session是与用户相关的,在用户之前訪问的每个页面都有可能创建了会话。因此isNew为false仅仅能说用户之前訪问过该Web应用,session能够是当前页面创建,也可能是由用户之前訪问过的页面创建的。

正确的做法是推断某个session中是否存在某个特定的key且其value是否正确



是否仅仅要关闭浏览器,session就消失了



程序一般都是在用户做log off的时候发个指令去删除session,然而浏览器从来不会主动在关闭之前通知server它将要被关闭,因此server根本不会有机会知道浏览器已经关闭。server会一直保留这个会话对象直到它处于非活动状态超过设定的间隔为止。

之所以会有这样的错误的认识,是由于大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次连接到server时也就无法找到原来的session。

假设server设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求报头,把原来的session id发送到server,则再次打开浏览器仍然可以找到原来的session。

恰恰是因为关闭浏览器不会导致session被删除,迫使server为session设置了一个失效时间,当距离客户上一次使用session的时间超过了这个失效时间时,server就能够觉得client已经停止了活动,才会把session删除以节省存储空间。

由此我们能够得出例如以下结论:

关闭浏览器,仅仅会是浏览器端内存里的session cookie消失,但不会使保存在server端的session对象消失,相同也不会使已经保存到硬盘上的持久化cookie消失。



怎样使用会话显示每一个客户的訪问次数



因为客户的訪问次数是一个整型的变量,但session的属性类型中不能使用int,double,boolean等基本类型的变量,所以我们要用到这些基本类型的封装类型对象作为session对象中属性的值

但像Integer是一种不可改动(Immutable)的数据结构:构建后就不能更改。这意味着每一个请求都必须创建新的Integer对象,之后使用setAttribute来取代之前存在的老的属性的值。比如:

HttpSession session = request.getSession();

SomeImmutalbeClass value = (SomeImmutableClass)session.getAttribute(“SomeIdentifier”);

if (value= =null){

value = new SomeImmutableClass(…); // 新创建一个不可更改对象

}else{

value = new SomeImmutableClass(calculatedFrom(value)); // 对value又一次计算后创建新的对象

}

session.setAttribute(“someIdentifier”,value); // 使用新创建的对象覆盖原来的老的对象



怎样使用会话累计用户的数据



使用可变的数据结构,比方数组、List、Map或含有可写字段的应用程序专有的数据结构。通过这样的方式,除非首次分配对象,否则不须要调用setAttribute。比如



HttpSession session = request.getSession();

SomeMutableClass value = (SomeMutableClass)session.getAttribute(“someIdentifier”);

if(value = = null){

value = new SomeMutableClass(…);

session.setAttribute(“someIdentifier”,value);

}else{

value.updateInternalAttribute(…); // 假设已经存在该对象则更新其属性而不需又一次设置属性

}

最新文章

  1. Oracle 11.2.0.4 DataGuard 环境打PSU,OJVM PSU补丁快速参考
  2. Tech Websites
  3. 【JAVA集合框架之Map】
  4. [WCF]设置拦截器捕捉到request和reply消息
  5. 【Android】事件总线(解耦组件) EventBus 详解
  6. C/C++:类模板
  7. jQuery 动态绑定的点击事件
  8. 我用过的linux命令--安装Hadoop
  9. 读改善c#代码157个建议:建议10~12
  10. python爬虫从入门到放弃(九)之 实例爬取上海高级人民法院网开庭公告数据
  11. Linux 粘着位(sticky bit)
  12. cap deploy:setup报错
  13. hdu 4638 树状数组 区间内连续区间的个数(尽可能长)
  14. UWP WebView 禁用缩放
  15. python之验证码识别 特征向量提取和余弦相似性比较
  16. JavaScript是如何工作的:Service Worker的生命周期及使用场景
  17. ajax return 的问题
  18. Python&#160;基于Python实现Ftp文件上传,下载
  19. VirtualBox-5.0.16设置windows与ubuntu的共享文件夹
  20. c# winform 获取当前程序运行根目录,winform 打开程序运行的文件夹

热门文章

  1. UNIX网络编程——网络数据包检测
  2. 采用openFileOutput获取输出流
  3. 使用gettimeofday测试函数运行的时间
  4. JAVA技术专题综述之线程篇(1)
  5. Boost 库Program Options--第二篇
  6. mysql中IN和EXITS效率
  7. Java基础07 包
  8. PEM文件格式具体解析
  9. Qt之多线程
  10. MongoDB shell操作