关于session的使用之我见

在J2EE的开发与之用中,session所起到的作用是有目共睹的。它所能方便我们与服务器之间进行会话,就好像人与人之间交流一样。一个会话用一个session来表示,这样就可以保证服务器不会被忙晕了。谈到session,就很容易让人产生一个误区,那就是:是不是我开一个页面就有一个会话?如果我关掉了与服务器之间的会话(通常是以关掉浏览器的方式来实现)我的这个session就相应的不存在了?是不是有了session,服务端就知道我在干什么(因为只有这样他才知道我想要什么)?
由于日常的习惯和一些惯性思维,就很容易涉入这些误区。其实事实并非如此。
在B/S(浏览器/服务器)体系里面,实现服务端与客户端通信的,的确是采取一个用户一个session的方式,用户通过在浏览器端的一些动作来达到与服务器的“交流”,似乎服务器能知道我在做什么似的。其实不然。我们的浏览器大多数都是支持W3C标准的,http协议都是以无状态的形式存在,而服务端是时刻都在“活动”,真正实现浏览器与服务端通信的其实是请求的提交。服务端则根据请求URL的不同响应不同的内容。也就是说,如果浏览器没有发出请求,服务端是不知道用户在做什么的。Session是驻留在服务端内存当中的,记录了客户端的一些基本信息。
由于必须为每个session都分配相应的内存资源,这就要求有条件的去限制session的数量。试想一下,如果平均一个session占1M的内存,那么当同时在线的用户很多的时候我们的服务器可能会崩溃掉。所有要采取很多种方法去尽量减轻服务器端的压力。
那么浏览器是怎么知道我的这个session的呢?当用户向服务端提交一个请求之后,服务会自动为它分配一个唯一的session标示id。然后通过response响应到用户的浏览器,在存储在用户浏览器的cookie中,只要用户打开网页的方式是采取window.open的方式,而不是,直接打开新的浏览器,他的这个session id是多页面共用的。当然,有很多浏览器的cookie为了考虑安全性而禁掉。虽然有的浏览器会自动去开,但是并不是全部。为了考虑更好的兼容性,可以将这个session的id采取在URL后面加上?jsessionid的方式带上,这样就确保了用户会话的流畅性。
那么,当用户关掉所有的浏览器之后,是不是这个session会话就会销毁呢?
答案是否定的。前面已经说到,客户端的浏览器与服务器其实是无状态连接。也就意味着,只要用户不向服务器端发送请求,服务器端是永远不知道用户此刻的状态。这样就遇到了新的问题,那就是:要是不销毁这些session,一直让它存在着,这不是更大程度的加大了服务器的负担么?是的。所以有了新的机制,那就是session失效的机制。在J2EE开发中,应用服务器通常默认的session失效时间是30分钟,但是也可以在部署描述符web.xml中通过这样的一条语句来配置这个失效时间:<session-config><session-timeout>30</session-timeout></session-config>。当用户在指定的失效时间内没有向服务端提交请求,session将会被应用服务器销毁。用户必须从重新登录来获得新的session。有时候为了方便用户在退出的时候更快速的销毁session,一般情况下会提供一个发送请求的方式去调用session.invalidate();去销毁这个session。其实用户关闭浏览器只是在用户的机器上失去了这个session的id。服务端是不知道用户的浏览器关闭了的,只能等失效时间到了就去销毁这个session了。要想在用户关闭浏览器的时候就去销毁session并不是没有办法。我们可以通过js来监听用户的关闭操作,一旦触发,就可以在这个js事件中手动发送一个销毁session的请求。
当然,以上只是讲了些session在客户端与服务端之间的用处。其实session的用处远远不止于此。在J2EE中,session是仅次于application的作用范围。我们可以利用它在我们整个会话中实现数据的共享,如果是jsp页面,可以使用其内置的隐藏对象session来设置和获取值,在多个页面之间共享。Session在自定义标签里面的使用可以使得代码的重用性达到更好。当然,如果是单个页面中的数据共享最好还是采用pageContext。这就涉及到J2EE中的几个表示范围的对象了。application可以用来在整个应用中共享数据,request可以在用户的请求与请求之间共享数据,而pageContext则可以在通页面中共享数据。他们之间也是各有千秋。session可以以单个用户的所有操作进行数据共享,这样既做到了不会干扰其他用户的操作(因为session的id在服务端是不会重复的),又可以让整个会话之间的数据传递变的更多元化、更方便。但是,session中存储的数据越多对服务端的压力也越大,这样就会影响到用户的访问速度。通常情况下,session的大小不应该超过10M,一个普通的对象大概占用1KB的大小,也就是说一个session最多不要放超过1万个对象的实例。在我们的应用中,需要传递的对象数量有很多,很可能会超过这个数量,这就需要我们在一些地方借助与request和pageContext来暂存数据,为session分忧!
同理,一旦对象或者数据存储在此session中,只要这个session的id不失去,就可以在应用代码中通过request来获取这个session,如果有不法之徒采取这种方式,那么就会显得不安全了,这就是为什么一些保密性要求比较高的网站会尽快的去销毁session的原因。
在servlet、自定义标签中都可以根据request对象来获得session,有了session就可以将处理出来的数据进行保存、获取等各种方便开发的动作了。有点值得注意的就是此处需要用HttpServletRequest对象通过getSession()的方法来获得session了。有了session的帮忙,自定义标签可以写的更具有通用性、扩展性。标签体组装数据,然后通过session来存储用户的这些数据,让开发更自由。
在用户发送请求的时候,通常会在服务端先过滤一下。常用的方式是采取Filter过滤器过滤,在filter中也可以通过request请求来获得session。例如在权限过滤中有一种方式就是当用户登录之后,将用户的一些状态保存在此用户的session中,例如一些用户可以访问的资源等。这样就可以利用session让每次用户访问的时候都可以在filter中对用户权限进行过滤。
总之,我的见解就是,session的失去不等于销毁、session的存在是服务器、session的标示是id、session的作用很大、session不应该被误解!


--作者:龚世俊
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值