求教怎么让一个session只存一个用户,判断当前的session是不是有效
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求教怎么让一个session只存一个用户,判断当前的session是不是有效相关的知识,希望对你有一定的参考价值。
应该怎么做?求javaweb的高手指点
第一这个session对于每个用户的浏览器都是不同的session实例也就是每个用户都有个自己的session 也跟你说的一个session中只有一个用户
我们没办法直接判断session 是否有效 因为我们不知道客服端是否还在访问
当浏览器关掉以后session 并不会马上销毁 于是我们有了关于浏览器关闭事件处理的问题在浏览器关闭是主动销毁session
一般判断session 是否有效 我们通常会试着存一个值在session 中
当需要判断session 是否有效时 我们获取这个值 通过这个值是否为空 是否为之前存的值我们就能判断了 参考技术A 比方说你在session里存了一个用户,使用IE的时候用的是IE的session,使用火狐的时候又是火狐创建的,所以每个session都是唯一的,这个不用去担心,判断当前session是否有效只需要到后台或数据库的数据进行比较。 参考技术B 应该吧SESSION ID放进数据库或者XML中,当用户登陆则进行匹配,否则SESSION数量太多
session过期怎么恢复
如果用户未操作的「长时间」超过了服务器配置的session超时时间,并导致session失效,那么我们延长session的超时时间,让用户原来的「长时间」与超时时间相比,变得不「长」,就可以解决。如果用户是长时间「未操作」导致session失效,那么我们想办法产生「操作」,让用户每隔一小段时间就「操作」一次,与服务器产生交互,那么session自然也不会失效。
一般情况下下,我们首先想到的是,通过改变服务器的配置,延长服务器的session超时时间。例如,在Tomcat服务器的web.xml文件中有如下节点内容:30这里的30表示session的超时时间,单位为分钟,如果用户登录后在30分钟内没有与服务器交互,那么当前用户的session将失效。
我们可以配置一个更大的数值(比如60),就可以延长session的超时时间,如果将该值改为0或负数的话,则表示session永不失效。
不过在实际的工作应用中,一味地上调session的超时时间设置并不怎么常见,大多数需要实现该功能的网站都将解决问题的焦点集中在第二条思路上。例如:一些在线网站均采用定时刷新页面的方法来防止session超时。 参考技术A session-timeout(web.xml)元素与session.setMaxInactiveInterval()函数
a) web app server中,如websphere里可以设置超时时间为30分钟
b)在web.xml中的session-config配置
session-timeout元素(WEB.XML文件中的元素)用来指定默认的会话超时时间间隔,以分钟为单位。该元素值必须为整数。如果session-timeout元素的值为零或负数,则表示会话将永远不会超时。如:
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<session-config>
<session-timeout>30</session-timeout>
</session-config>//30分钟
setMaxInactiveInterval设置的是当前会话的失效时间,不是整个web的时间,单位为以秒计算。如果设置的值为零或负数,则表示会话将永远不会超时。常用于设置当前会话时间。 参考技术B This account recovery session has expired. Please select \\\'Find Account\\\' and start again.这个帐户恢复会话已经过期。请选择\“发现账户\”,重新开始。 参考技术C 如何防止session超时
众所周知,当用户登录网站后较长一段时间没有与服务器进行交互,将会导致服务器上的用户会话数据(即session)被销毁。此时,当用户再次操作网页时,如果服务器进行了session校验,那么浏览器将会提醒用户session超时。
那么,如何解决用户登录后较长时间未操作而导致的session失效的问题呢?[3]
导致这个问题的关键词有两个:一个是「长时间」,一个是「未操作」。
1、如果用户未操作的「长时间」超过了服务器配置的session超时时间,并导致session失效,那么我们延长session的超时时间,让用户原来的「长时间」与超时时间相比,变得不「长」,不就可以解决了吗?
2、如果用户是长时间「未操作」导致session失效,那么我们想办法产生「操作」,让用户每隔一小段时间就「操作」一次,与服务器产生交互,那么session自然也不会失效。一般情况下下,我们首先想到的是,通过改变服务器的配置,延长服务器的session超时时间。例如,在Tomcat服务器的web.xml文件中有如下节点内容:
<session-config><session-timeout>30</session-timeout></session-config>
这里的30表示session的超时时间,单位为分钟,如果用户登录后在30分钟内没有与服务器交互,那么当前用户的session将失效。我们可以配置一个更大的数值(比如60),就可以延长session的超时时间,如果将该值改为0或负数的话,则表示session永不失效。
不过在实际的工作应用中,一味地上调session的超时时间设置并不怎么常见,大多数需要实现该功能的网站都将解决问题的焦点集中在第二条思路上。例如:一些在线网站均采用定时刷新页面的方法来防止session超时。
定时刷新页面,最常见的有两种实现方式:一种是通过JavaScript+HTMLDOM,另一种则是通过meta标签来实现。
1、JavaScript+HTMLDOM,示例代码如下:
1
2
3
4
functionrefresh(seconds)
setTimeout("self.location.reload()",seconds*1000);
refresh(600);//调用方法启动定时刷新,数值单位:秒。
2、通过meta标签来实现(在页面中添加meta标签refresh也可以指定每隔指定时间就刷新当前页面),示例代码如下:
1
<metahttp-equiv="refresh"content="600"/>
上述meta标签可以实现每过600秒就刷新一次当前页面。
在上述两种方案中,较好的为第二种,因为如果当前页面是在IE浏览器的模式窗口中打开的,默认情况下,self.location.reload()方法将会失效,而refreshmeta标签在IE模式窗口下仍然有效。
上述两种方式都实现了刷新当前页面,并且使用起来非常简单,不过很遗憾的是,它们存在一种几乎致命的缺陷。试想一下,如果在论坛发帖等需要用户输入内容的页面,用户花费较长的时间输入了许多文本内容,可是突然遇到了一个定时页面刷新,结果用户输入的所有内容都没了,估计这个时候用户连掐死你的心都有了……
因此我们需要在当前页面本身不刷新、不影响用户的任何操作的情况下实现定时刷新。最常见的解决方法仍然有两种。一种是在当前页面添加一个隐藏的iframe,然后在该iframe里面实现定时刷新。
1
<iframeid="hidden_iframe"style="display:none;"scrolling="no"frameborder="0"name="hidden_iframe"src="ping.php"></iframe>
此外,我们需要在服务器上编写对应的请求响应代码,例如ping.php中可以编写如下代码:
1
2
3
4
<?php
//每隔600秒刷新当前页面
echo'<html><head><metahttp-equiv="refresh"content="600"/></head><body></body></html>';
?>
另外一种则是使用JavaScriptImage对象来实现定时刷新,JavaScript代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
functionautoRefresh(seconds)
if(typeofperiod=="undefined")//如果是第一次执行
period=seconds*1000;//定义全局变量period
varbodyDOM=document.getElementsByTagName("body")[0];
if(bodyDOM)
bodyDOM.innerHTML+='<imgid="auto_refresh_img"src=""style="display:none"/>';//添加隐藏的图片
imgDOM=document.getElementById("auto_refresh_img");//定义全局Image对象
if(typeofimgDOM!="undefined")
imgDOM.src="ping.php?sid="+newDate().getTime();//防止缓存
setTimeout("autoRefresh("+seconds+")",period);
autoRefresh(600);//调用方法启动定时刷新
和使用iframe来实现定时刷新一样,使用JavaScriptImage对象实现定时刷新,也需要在服务器端编写类似的请求响应代码。服务器的响应可以是文字等非图片内容,非图片内容只会造成图像加载失败,而我们的图像标签本身就是隐藏的,不管是加载成功还是失败都不会显示,毕竟我们的主要目的是发送请求给服务器,让服务器保持session处于活动状态。
当然,还可以使用Ajax来实现定时刷新,不过使用Image对象会更好一些,因为有些老式浏览器的JavaScript无法实现Ajax,但是却可以使用Image对象。此外,使用Ajax需要编写更多的代码来处理XMLHttpRequest等对象的活动。
在上述两种方式中,各有其优缺点。
使用iframe标签实现定时刷新的优点是:不需要编写JavaScript代码,可以在浏览器禁用JavaScript的情况下实现定时刷新;其缺点是:在某些不支持iframe标签的老式浏览器中没有效果,此外,iframe标签在浏览器中新增加了一个独立的页面,即使没有显示出来,不过其内部解析的window、document等对象仍然存在,占用的浏览器内存相对较多。
使用Image对象的优点是:与iframe相比,占用的内存相对较少,支持Image的浏览器也相对较多(现代浏览器均支持);缺点是:在浏览器禁用JavaScript的情况下就毫无用武之地了。
开发人员应根据实际需求情况来确定使用何种实现方式更好。此外,服务器在响应定时刷新的请求时,在满足要求的情况下,应返回尽可能少的数据,以节省带宽。
有效期
编辑
PHP中的session有效期默认是1440秒(24分钟)【weiweiok 注:php5里默认的是180分】,也就是说,客户端超过24分钟没有刷新,当前session就会失效。很明显,这是不能满足需要的。
一个已知管用的方法是,使用session_set_save_handler,接管所有的session管理工作,一般是把session信息存储到数 据库,这样可以通过SQL语句来删除所有过期的session,精确地控制session的有效期。这也是基于PHP的大型网站常用的方法。但是,一般的 小型网站,似乎没有必要这么劳师动众。
但是一般的Session的生命期有限,如果用户关闭了浏览器,就不能保存Session的变量了!那么怎么样可以实现Session的永久生命期呢?
大 家知道,Session储存在服务器端,根据客户端提供的SessionID来得到这个用户的文件,然后读取文件,取得变量的值,SessionID可以 使用客户端的Cookie或者Http1.1协议的Query_String(就是访问的URL的“?”后面的部分)来传送给服务器,然后服务器读取 Session的目录……
要实现Session的永久生命期,首先需要了解一下php.ini关于Session的相关设置(打开php.ini文件,在“[Session]”部分):
1、session.use_cookies:默认的值是“1”,代表SessionID使用Cookie来传递,反之就是使用Query_String来传递;
2、session. name:这个就是SessionID储存的变量名称,可能是Cookie,也可能是Query_String来传递,默认值是“PHPSESSID”;
3、session.cookie_lifetime:这个代表SessionID在客户端Cookie储存的时间,默认是0,代表浏览器一关闭SessionID就作废……就是因为这个所以Session不能永久使用!
4、session.gc_maxlifetime:这个是Session数据在服务器端储存的时间,如果超过这个时间,那么Session数据就自动删除!
功能缺陷
编辑
目前ASP的开发人员都正在使用Session这一强大的功能,但是在他们使用的过程中却发现了ASP Session有以下缺陷:
进程依赖性
ASP Session状态存于IIS的进程中,也就是inetinfo.exe这个程序。所以当inetinfo.exe进程崩溃时,这些信息也就丢失。另外,重起或者关闭IIS服务都会造成信息的丢失。
Session状态使用范围的局限性
当一个用户从一个网站访问到另外一个网站时,这些Session信息并不会随之迁移过去。例如:新浪网站的WWW服务器可能不止一个,一个用户登录之后要去各个频道浏览,但是每个频道都在不同的服务器上,如果想在这些WWW服务器共享Session信息怎么办呢
Cookie的依赖性
实际上客户端的Session信息是存储在Cookie中的,如果客户端完全禁用掉了Cookie功能,他也就不能享受到了Session提供的功能了。
鉴于ASP Session的以上缺陷,微软的设计者们在设计开发 ASP .NET Session时进行了相应的改进,完全克服了以上缺陷,使得ASP .NET Session成为了一个更加强大的功能。
Hibernate
编辑
Session是JAVA应用程序和Hibernate进行交互时使用的主要接口,它也是持久化操作核心API,
注意这里的Session的含义,它与传统意思上web层的HttpSession并没有关系,Hibernate Session之与Hibernate,相当于JDBC Connection相对与JDBC。
Session对象是有生命周期的,它以Transaction对象的事务开始和结束边界
Session作为贯穿Hibernate的持久化管理器核心,提供了众多的持久化的方法,如save(),update,delete,find(Hibernate 3中已经取消了此方法,)等,通过这些方法我们可以透明的完成对象的增删改查(CRUD-- create read update delete),这里所谓的透明是指,Session在读取,创建和删除映射的实体对象的实例时,这一系列的操作将被转换为对数据库表中数据的增加,修改,查询和删除操作。
Session有以下的特点:
1,不是线程安全的,应该避免多个线程共享同一个Session实例
2,Session实例是轻量级的,所谓轻量级:是指他的创建和删除不需要消耗太多资源
3,Session对象内部有一个缓存,被称为Hibernate第一缓存,他存放被当前工作单元中加载的对象,每个Session实例都有自己的缓存。
org.hibernate Interface Session
public interface Session extends Serializable : 是一个Java application 和Hibernate之间主要的运行时接口,这是执行持久化服务的中心API
主要方法:
public Transaction beginTransaction() throws HibernateException:返回和当前Session对象相互联系的Transaction对象(表示在数据库中重新开始一个事务)
public Transaction getTransaction():返回和当前session联系的Transaction对象
public Connection connection close() throws HibernateExcepton:结束当前的Session对象
public void clear() :清空Session,清除所有保存在当前Session缓存中的实体对象,终止所有正在执行的方法(eg: save(),update(),delete() .....)
public Serializable save(Object object)throws HibernateException 对当前参数指定的对象进行持久化(系统会首先赋予参数对象一个标识符OID),他相当于insert语句 后面在详细介绍
public Connection connection() throws HibernateException 得到当前Session 中包含的Connection对象。
public boolean contains(Object object):判断参数给出的对象(持久化类)是否在当前Session的缓存中
public void evict(Object object) throws HibernateException :将参数给出的Object从当前Session对象类中删除,使这个对象从持久态变成游离态,这种状态的改变不会引起对数据库的同步,后面详细介绍
public Object load(Class theclass,Serializable id) throws HibernateException 返回第一个参数指定类对应的表中,第二个参数指定的行(第二个参数就是要取得对象的OID,他对应表中主键列的值)
public void update(Object object) throws HibernateException :更新一个对象到数据库中,后面在详细介绍
public void delete (Object object)throws HibernateException:从数据库中删除和参数指定的对象对应的记录
public Object get(Class class,Serializable id) throws HibernateException:和load()方法一样区别在于,如果数据库表中没有对应的记录,get()方法返回null,load()方法将报异常
以上是关于求教怎么让一个session只存一个用户,判断当前的session是不是有效的主要内容,如果未能解决你的问题,请参考以下文章