`
com_xpp
  • 浏览: 372070 次
社区版块
存档分类
最新评论

Session那些事(一)

    博客分类:
  • java
阅读更多

     前一段时间做一个应用的客户端时,涉及到用户权限的问题,所以用到了Session,遇到一些问题,网上找了各位大神的一些资料,今天汇总到这,以便以后复习。

 

1.Session

由于HTTP协议连接的无状态性,才使得session的不得已而产生。既然Web应用并不了解有关同一用户以前请求的信息,那么解决这个问题的一个办法是使用Servlet/JSP容器提供的会话跟踪功能,Servlet API规范定义了一个简单的HttpSession接口,通过它我们可以方便地实现会话跟踪。

 HttpSession接口提供了存储和返回标准会话属性的方法。标准会话属性如会话标识符、应用数据等,都以“名字-值”对的形式保存在服务器端。也就是说,HttpSession接口提供了一种把对象保存到内存、在同一用户的后继请求中提取这些对象的标准办法。在会话中保存数据的方法是setAttribute(String s, Object o),从会话提取原来所保存对象的方法是getAttribute(String s)。

在服务器端,每当新用户请求了一个使用HttpSession对象的JSP页面,Servlet、JSP容器除了发回应答页面外,它还要以cookie的形式向浏览器发送一个特殊数字,即“绘画标识符”,它是一个唯一的用户标示符,浏览器在请求session时,服务器会先得到它的sessionId,在做处理。
 会话标识符以Cookie的形式在服务器和浏览器组件传送,标准会话属性在服务器端也是以会话的形式存在,并且这个Cookie的生命周期只是临时的,即会话结束后就自动消失,没有为它指定固定的生命周期,因此可以说session是基于Cookie的技术。另外,如果客户端不支持Cookie,运用URL重写机制来保证会话标识回服务器。


2.session机制的实现:

 
(1.)session机制是一种服务器端的机制,
用来在无状态的HTTP协议下越过多个请求页面来维持状态和识别用户。
当程序需要为某个客户端的请求创建一个session的时候,
服务器首先检查这个客户端的请求里是否已包含了一个session标识。

这个标识称为session id,
如果已包含一个session id则说明以前已经为此客户端创建过session,
服务器就按照session id把这个session检索出来使用,
若没有创建过,则创建一个新的Session。

那么这个session是什么时候创建的呢?
之前一直错误地理解为:
当用户向服务器发起请求时,这个session便会立刻建立起来,
但实际上却根本不是这样。

在Servlet中,你肯定用过下面这句话,

HttpSession session = request.getSession();如果当前没有session,则会立刻建立一个session;
如果有session则返回当前session。

这句话和

HttpSession session = request.getSession(true);的效果是一样的。

但是如果你写成

HttpSession session = request.getSession(false);则不会自动建立session。
若当前没有session,你所得到的seesion只会是一个null。

总结:
session不是一打开网站就会立刻建立。
它的建立需要基于下面两个条件中的任意一个:

   a:在servlet中手动调用

HttpSession session = request.getSession();或者

HttpSession session = request.getSession(true);2:jsp中没有写
(默认情况下它是的)

如果两个条件同时都不满足,那么你建立的只是一个无seesion的连接。

 


(2.) session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。 
      当程序需要为某个客户端的请求创建一个session的时候,

第一步: 
      服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为session id, 
此时就是两种可能,客户机有session id或者没有session id

第二步: 
      如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个) 
      如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id 
(session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。)

三、保存session id 的方法 
一)、cookie: 
二)、URL重写: 
cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径

的后面。


3.session与Cookie的实现原理

Session 与 Cookie 的作用都是为了保持访问用户与后端服务器的交互状态。它们有各自的优点也有各自的缺陷。然而具有讽刺意味的是它们优点和它们的使用场景又是矛盾的,例如使用 Cookie 来传递信息时,随着 Cookie 个数的增多和访问量的增加,它占用的网络带宽也很大,试想假如 Cookie 占用 200 个字节,如果一天的 PV 有几亿的时候,它要占用多少带宽。所以大访问量的时候希望用 Session,但是 Session 的致命弱点是不容易在多台服务器之间共享,所以这也限制了 Session 的使用。

不管 Session 和 Cookie 有什么不足,我们还是要用它们。下面详细讲一下,Session 如何基于 Cookie 来工作。实际上有三种方式能可以让 Session 正常工作:

1.基于 URL Path Parameter,默认就支持
2.基于 Cookie,如果你没有修改 Context 容器个 cookies 标识的话,默认也是支持的
3.基于 SSL,默认不支持,只有 connector.getAttribute("SSLEnabled") 为 TRUE 时才支持
第一种情况下,当浏览器不支持 Cookie 功能时,浏览器会将用户的 SessionCookieName 重写到用户请求的 URL 参数中,它的传递格式如 /path/Servlet;name=value;name2=value2? Name3=value3,其中“Servlet;”后面的 K-V 对就是要传递的 Path Parameters,服务器会从这个 Path Parameters 中拿到用户配置的 SessionCookieName。关于这个 SessionCookieName,如果你在 web.xml 中配置 session-config 配置项的话,其 cookie-config 下的 name 属性就是这个 SessionCookieName 值,如果你没有配置 session-config 配置项,默认的 SessionCookieName 就是大家熟悉的“JSESSIONID”。接着 Request 根据这个 SessionCookieName 到 Parameters 拿到 Session ID 并设置到 request.setRequestedSessionId 中。

请注意如果客户端也支持 Cookie 的话,Tomcat 仍然会解析 Cookie 中的 Session ID,并会覆盖 URL 中的 Session ID。

如果是第三种情况的话将会根据 javax.servlet.request.ssl_session 属性值设置 Session ID。

有了 Session ID 服务器端就可以创建 HttpSession 对象了,第一次触发是通过 request. getSession() 方法,如果当前的 Session ID 还没有对应的 HttpSession 对象那么就创

建一个新的,并将这个对象加到 org.apache.catalina. Manager 的 sessions 容器中保存,Manager 类将管理所有 Session 的生命周期,Session 过期将被回收,服务器关闭,

Session 将被序列化到磁盘等。只要这个 HttpSession 对象存在,用户就可以根据 Session ID 来获取到这个对象,也就达到了状态的保持。

 

还有一点与 Session 关联的 Cookie 与其它 Cookie 没有什么不同,这个配置的配置可以通过 web.xml 中的 session-config 配置项来指定。


4.session中的一些问题
    (1)、session在何时被创建

  一个常见的误解是以为session在有客户端访问时就被创建,然而事实是直到某server端程序调用 HttpServletRequest.getSession(true)这样的语句时才被创建,注意如果JSP没有显示的使用 <%@pagesession="false"%> 关闭session,则JSP文件在编译成Servlet时将会自动加上这样一条语句HttpSession session = HttpServletRequest.getSession(true);这也是JSP中隐含的session对象的来历。

  由于session会消耗内存资源,因此,如果不打算使用session,应该在所有的JSP中关闭它。

 (2)、session何时被删除

  综合前面的讨论,session在下列情况下被删除a.程序调用HttpSession.invalidate();或b.距离上一次收到客户端发送的session id时间间隔超过了session的超时设置;或c.服务器进程被停止(非持久session)

 (3)、如何做到在浏览器关闭时删除session

  严格的讲,做不到这一点。可以做一点努力的办法是在所有的客户端页面里使用网页特效代码window.onclose来监视浏览器的关闭 动作,然后向服务器发送一个请求来删

除session。但是对于浏览器崩溃或者强行杀死进程这些非常规手段仍然无能为力。

 (4)、有个HttpSessionListener是怎么回事

  你可以创建这样的listener去监控session的创建和销毁事件,使得在发生这样的事件时你可以做一些相应的工作。注意是 session的创建和销毁动作触发listener,而不是相反。类似的与HttpSession有关的listener还有 HttpSessionBindingListener,HttpSessionActivationListener和 HttpSessionAttributeListener。

 (5)、存放在session中的对象必须是可序列化的吗

  不是必需的。要求对象可序列化只是为了session能够在集群中被复制或者能够持久保存或者在必要时server能够暂时把session交换出内 存。在Weblogic Server的session中放置一个不可序列化的对象在控制台上会收到一个警告。我所用过的某个iPlanet版本如果session中有不可序列化 的对象,在session销毁时会有一个Exception,很奇怪。

 (6.)、如何才能正确的应付客户端禁止cookie的可能性

  对所有的URL使用URL重写,包括超链接,form的action,和重定向的URL,具体做法参见[6]http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770

 (7.)、开两个浏览器窗口访问应用程序会使用同一个session还是不同的session

  参见第三小节对cookie的讨论,对session来说是只认id不认人,因此不同的浏览器,不同的窗口打开方式以及不同的cookie存储方式都会对这个问题的答案有影响。

    (8.)、如何防止用户打开两个浏览器窗口操作导致的session混乱

  这个问题与防止表单多次提交是类似的,可以通过设置客户端的令牌来解决。就是在服务器每次生成一个不同的id返回给客户端,同时保存在 session里,客户端提交表单时必须把这个id也返回服务器,程序首先比较返回的id与保存在session里的值是否一致,如果不一致则说明本次操 作已经被提交过了。可以参看《J2EE核心模式》关于表示层模式的部分。需要注意的是对于使用javascript window.open打开的窗口,一般不设置这个id,或者使用单独的id,以防主窗口无法操作,建议不要再window.open打开的窗口里做修改 操作,这样就可以不用设置。

      (9.)、为什么在Weblogic Server中改变session的值后要重新调用一次session.setValue做这个动作主要是为了在集群环境中提示Weblogic Server session中的值发生了改变,需要向其他服务器进程复制新的session值。

 (10)、为什么session不见了

  排除session正常失效的因素之外,服务器本身的可能性应该是微乎其微的,虽然笔者在iPlanet6SP1加若干补丁的Solaris版本上倒 也遇到过;浏览器插件的可能性次之,笔者也遇到过3721插件造成的问题;理论上防火墙或者代理服务器在cookie处理上也有可能会出现问题。

  出现这一问题的大部分原因都是程序的错误,最常见的就是在一个应用程序中去访问另外一个应用程序。

39
2
分享到:
评论
20 楼 jacklujuneye 2015-10-22  
19 楼 boblee2010 2013-04-17  
比如:登录的时候,如果不用session,那应该怎么做呢?大家都会怎么弄呢?
18 楼 liguocai2009 2012-06-12  
steven19880224 写道
dwbin 写道
不错,不过如果做电子商务的话使用session会不会有什么问题啊?比如购物车的物品之类的?如果大量用户在不同domain的站点之间进行操作,这个同步的压力会蛮大的吧?

购物车一般放在数据库零时表里面。放在session里面不安全。

1 为什么会有同步的问题?一个用户一个session怎么会有同步的问题?
2 为什么放到session会不安全?
17 楼 w156445045 2012-06-09  
一直使用session 不过没考虑这么多~
16 楼 com_xpp 2012-06-09  
不错,不过如果做电子商务的话使用session会不会有什么问题啊?比如购物车的物品之类的?如果大量用户在不同domain的站点之间进行操作,这个同步的压力会蛮大的吧?
15 楼 com_xpp 2012-06-09  
不错,不过如果做电子商务的话使用session会不会有什么问题啊?比如购物车的物品之类的?如果大量用户在不同domain的站点之间进行操作,这个同步的压力会蛮大的吧?
14 楼 s10008121y 2012-06-08  
=。=。=。=不错
13 楼 luccs624061082 2012-06-08  
1111111111111111111111111111111111111111111111111111111111111112222222222222222222222222
12 楼 luccs624061082 2012-06-08  
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112222222
11 楼 maimode 2012-06-08  
嗯,受益了,以前总以为session是http协议中的呢
10 楼 gearever 2012-06-08  
session机制可以看一下我的博客
http://gearever.iteye.com/blog/1546423
9 楼 lintghi 2012-06-07  
8 楼 hyanqing1 2012-06-07  
你好,你这UML图是用什么工具画的,蛮漂亮的,正在找UML工具呢
7 楼 sumuu 2012-06-07  
dwbin 写道
不错,不过如果做电子商务的话使用session会不会有什么问题啊?比如购物车的物品之类的?如果大量用户在不同domain的站点之间进行操作,这个同步的压力会蛮大的吧?

购物车的话用cookie或者数据库零时表好点。
6 楼 yzongjie 2012-06-07  
很好,有时间再了解一下 session 服务器,就全面了
5 楼 zhangjunbao 2012-06-07  
写的不错!
4 楼 zhouhongqiang2010 2012-06-07  
session在服务器之间不能共享。现在好多都是自己实现一个session,用缓存服务器记录要放到session中的对象。
3 楼 steven19880224 2012-06-07  
dwbin 写道
不错,不过如果做电子商务的话使用session会不会有什么问题啊?比如购物车的物品之类的?如果大量用户在不同domain的站点之间进行操作,这个同步的压力会蛮大的吧?

购物车一般放在数据库零时表里面。放在session里面不安全。
2 楼 aijuans 2012-06-07  
很好,非常好.
1 楼 dwbin 2012-06-07  
不错,不过如果做电子商务的话使用session会不会有什么问题啊?比如购物车的物品之类的?如果大量用户在不同domain的站点之间进行操作,这个同步的压力会蛮大的吧?

相关推荐

    session session session szsessdifn

    在Web开发中,Session是一个至关重要的概念,尤其是在ASP.NET框架下。Session机制是服务器端存储用户特定信息的一种方式,它允许开发者在多个页面之间保持用户状态,解决了HTTP协议无状态的问题。"szsessdifn"可能是...

    一篇优秀Session讲解

    ### 一篇优秀Session讲解 在深入探讨Session的概念之前,我们先简单回顾一下Session的基本定义及其在Web应用中的重要性。Session是一种用于维护客户端与服务器之间交互状态的技术,它能够跟踪用户的活动并保存用户...

    一个服务器搭多个tomcat导致session丢失,或者同一个IP不同端口,多个应用的session会冲突解决方法

    一个服务器上搭建了多个tomcat或者weblogic,端口不一样,同时启动访问时session丢失。如:A,B两个服务,在浏览器中登录访问A后,当前打开的浏览器上在开一个选项卡访问B服务后,回过来点击访问A时session丢失,...

    数据操作session获取的一个简单实例

    在Web开发中,Session是一种非常重要的技术,用于在多个页面之间保持用户状态。在这个"数据操作session获取的一个简单实例"中,我们将探讨如何在JSP(JavaServer Pages)页面上利用Session来处理用户数据,特别是在...

    spring session redis分布式session

    为了解决这个问题,Spring Session提供了一种优雅的解决方案,特别是结合Redis作为持久化存储时,可以实现高效的分布式Session管理。本文将详细介绍Spring Session与Redis集成,以及如何自定义Session来应对分布式...

    Jsp内置对象session总结

    当一个客户首次访问服务器上的一个 JSP 页面时,JSP 引擎产生一个 Session 对象,同时分配一个 String 类型的 Id 号,JSP 引擎同时将这个 Id 号发送到客户端,存放在 Cookie 中,这样 Session 对象和客户之间就建立...

    js操作session例子

    在Web开发中,Session是一种非常重要的机制,用于在用户的整个会话期间保持数据。JavaScript(JS)作为客户端脚本语言,通常与HTML和CSS一起工作,处理用户交互和动态更新页面内容。然而,由于安全性和同源策略的...

    Hibernate-nosession

    总结来说,Hibernate-nosession是一种优化策略,它适合于那些对性能要求较高且不涉及复杂业务逻辑的场景。通过避免频繁打开和关闭Session,可以减少资源消耗,提高系统的响应速度。在实际开发中,我们需要根据项目...

    iframe 跨域访问session

    然而,当涉及到跨域时,`iframe` 遇到的问题之一就是无法正常访问父页面或被嵌入页面的`session`。这是因为浏览器的同源策略(Same-Origin Policy)限制了不同源之间的交互,包括`session`和`cookie`。 同源策略是...

    C#不同域名之间的Session共享

    在处理用户交互时,Session是一个重要的概念,它允许开发者在用户的不同请求之间存储数据。然而,当涉及到跨域(即不同域名)的Session共享时,问题就变得稍微复杂了。本篇文章将深入探讨C#中如何实现不同域名之间的...

    Spring Session + redis实现session共享

    在现代Web应用开发中,session共享是一个至关重要的需求,特别是在分布式系统中,多个服务器节点需要共享用户的状态信息。Spring Session + Redis的结合提供了一个高效且可靠的解决方案,它允许跨服务器节点透明地...

    分布式Session的一个实现.

    分布式Session的实现是现代Web应用中一个至关重要的技术,它涉及到多服务器间的用户会话共享,以确保用户在切换服务器时仍然能保持登录状态和其他个性化设置。本文将深入探讨这个主题,结合给定的标签“源码”和...

    SpringSession+Redis实现Session共享案例

    在现代Web应用开发中,Session共享是一个常见的需求,特别是在分布式系统中。`SpringSession` 是一个优秀的框架,它提供了一种优雅的方式来进行Session管理,尤其是跨服务器的Session共享。配合`Redis`作为存储后端...

    报表session与应用session常识普及

    在Web开发中,session是用于存储特定用户会话所需的信息的一种机制。每个用户访问网站时,服务器都会为该用户创建一个唯一的会话标识(session ID),通过这个标识可以在多次请求之间共享数据。系统session和报表...

    sessionsession

    销毁Session通常有两种方式:一是通过编程方式调用session.invalidate()方法,二是服务器设置的Session超时时间到达,服务器会自动清理过期的Session。 3. **Session的存储** Session数据存储在服务器的内存中,...

    tomcat修改sessionId

    tomcat修改sessionId,同一台服务器部署多个tomcat需要修改sessionId,否则会出现session冲突的问题

    session实验

    在IT行业中,Session是一个至关重要的概念,特别是在Web开发领域。Session是服务器端用来跟踪用户状态的一种机制。在HTTP协议无状态的特性下,Session扮演了关键角色,它允许服务器保存和识别不同请求之间的用户信息...

    session共享jar包(三个)

    在IT行业中,session共享是一个重要的概念,特别是在分布式系统或者多服务器环境下的Web应用。当用户在网站上进行操作时,服务器会创建一个session来存储用户的会话信息,如登录状态、购物车等。然而,如果一个网站...

    一个关于Session的小demo

    当用户首次访问网站并创建Session时,服务器会为该用户分配一个唯一的Session ID,并通过Cookie将其返回给浏览器。之后,每次用户发送请求时,浏览器都会将这个Session ID附带在请求头中,服务器通过这个ID找到对应...

    session共享 memcached-session-manager 1.9.6 jar

    `memcached-session-manager`是Java的一个库,用于在基于Tomcat的Web应用中实现基于Memcached的session共享,这在分布式环境中尤为重要。 标题中的"session共享 memcached-session-manager 1.9.6 jar"指的正是这个...

Global site tag (gtag.js) - Google Analytics