解决J2EE-session在浏览器关闭后失效问题

前几天在做一个签到系统时,遇到了喜闻乐见的session问题,项目为Spring+SpringMVC+Mybatis框架,maven管理目录的javaweb端系统,对于session的一些问题,作出以下分析,在这里,着重讨论session生命周期的问题,至于其他定义,不做解释:

首先,说明一下session的生命周期:

存储:Session存储在服务器端,一般为了防止在服务器的内存中(为了高速存取),Sessinon在用户访问第一次访问服务器时创建,需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session。在一个javaweb应用中,可调用request.getSession(boolean xxx)生成Session。注意,boolean型参数为true时,在此处强制生成一个新的session。

1.session失效时间:

距离上一次使用该session的时间达到设置的失效时间,session失效

2.还有一种是方法 session.invalidate()被执行,主动使得session失效

对于失效时间,可以通过配置web.xml中的属性来定义:

 <session-config>
 <session-timeout>失效时间</session-timeout>
 </session-config>

失效时间单位为分钟,若要使session有效时间为一天,则可以设为60*24,当设置为0或负数时,session永久有效,根据失效时间的定义,很容易理解这一情况。

session为什么在浏览器关闭之后失效了?

  • 未设置session失效时间,默认为浏览器关闭后失效;
  • 大部分的session机制都是采用进程中的cookie来保存sessionid的,也就是JSESSIONID,浏览器关闭后进程消失,进程中的cookie消失,那么sessionid也就跟着消失了。

根据已知的内容,写了一个简单的例子:

@Controller
public class SessionTest {
 @RequestMapping("/sessionTest")
 public String sessionTest(HttpServletRequest request, HttpServletResponse response){
  System.out.println("success!");
  HttpSession session = request.getSession();
  session.setMaxInactiveInterval(259200);
  request.setAttribute("creationtime",session.getCreationTime());//创建时间
  request.setAttribute("id",session.getId());//id
  request.setAttribute("max",session.getMaxInactiveInterval(-1));//最大失效时间
  //在这里,MaxInactiveInterval的优先级高于web.xml中的session-cofig,单位为秒
  request.setAttribute("lasttime",session.getLastAccessedTime());//上次使用时间
  request.setAttribute("sessionTest",session);
//  System.out.println(session.getCreationTime());
//  System.out.println(session.getMaxInactiveInterval());
//  System.out.println(session.getLastAccessedTime());
  return "page/showSession";
 }
 <table border="1" cellspacing="0" cellpadding="0">
  <tr><td>创建时间:</td><td>${creationtime}</td></tr>
  <tr><td>id:</td><td>${id}</td></tr>
  <tr><td>最大存活时间:</td><td>${max}</td></tr>
  <tr><td>上次使用时间:</td><td>${lasttime}</td></tr>
  <tr><td>session:</td><td>${sessionTest}</td></tr>
 </table>

解析:

  • 上面的代码模拟了一次登录情况,控制器中,创建了一个HttpSession对象,基本设置了所有能设置的参数,
  • 但是在浏览器关闭后,再次进入主页面时,还是需要再次登录,说明浏览器端是没有再次拿到这个session对象的,我们可以在chrome浏览器的设置->显示高级设置->隐私设置的内容设置->所有cookie与网站数据中,搜索本地tomcat服务器去查看本次存入的session,即一个名为JSESSIONID的cookie,情况如下


可见,session的失效时间其实还是在浏览器关闭时,所以只有浏览器不关闭再次访问的情况,才能继续使用登录状态,到底上面我们所设置的失效时间代表的是什么?

浏览器和服务器之间创建了一个Session,由于客户端长时间(休眠时间)没有与服务器交互,服务器将此Session销毁,客户端再一次与服务器交互时之前的Session就不存在了,我的理解是,失效时间只生效在一次会话过程中,若浏览器关闭,会话结束,其实失效时间设置为永久有效,就是到浏览器关闭,会话关闭的那个时刻。要解决这个问题,可以把cookie与session混用,有这么的笨办法:

主动添加Cookie,设置保存目录与存活时间

public static void addCookie(String name, String value, int age, HttpServletResponse response) throws
   UnsupportedEncodingException {
  Cookie c = new Cookie(name, URLEncoder.encode(value, "utf-8"));
  c.setMaxAge(age);
  c.setPath(path);
  response.addCookie(c);
 }

在再次访问时,使用Cookie[] cookies = request.getCookies();遍历cookie,根据cookie的名字获取想要的cookie,也可说是session,最后,得到了自己想要的结果,session(这个名为JSESSIONID的cookie)逃出了浏览器的监禁。

总结

以上所述是小编给大家介绍的解决J2EE-session在浏览器关闭后失效问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

您可能感兴趣的文章:

  • jQuery访问浏览器本地存储cookie、localStorage和sessionStorage的基本用法
  • 浏览器关闭使session失效的问题多种解决方式
  • ASP.NET网站管理系统退出 清除浏览器缓存,Session的代码
(0)

相关推荐

  • 浏览器关闭使session失效的问题多种解决方式

    如果用户不点击网站的"退出"链接,而直接关闭浏览器(或者强制关闭浏览器进程.死机等),服务器无法处理用户退出网站的请求,解决方式如下: 方式1:在每个页面中加入隐藏的IFrame,以异步刷新的方式定期刷新iframe页面,如每隔10S刷新一次,当服务器在一定的时间内未收到用户的刷新请求,则认为用户已经退出 优点:能在短时间内判断出用户是否已经退出 缺点:增加用户请求次数,所消耗的服务器资源较大 方式2:使用cookie保存用户登录信息,不要设置cookie的过期时间,当关闭浏览器时,c

  • jQuery访问浏览器本地存储cookie、localStorage和sessionStorage的基本用法

    前言:cookie,localStorage和sessionStorage都是浏览器本地存储数据的地方,其用法不尽相同:总结一下基本的用法. 一.cookie 定义: 存储在本地,容量最大4k,在同源的http请求时携带传递,损耗带宽: 可设置访问路径,只有此路径及此路径的子路径才能访问此cookie,存在有效的时间. 注意点: cookie的访问需要服务器环境,直接在本地文件访问无效: cookie的访问和设置需要导入jquery.cookie.js文件: 浏览器对每一个访问的地址下可添加的c

  • ASP.NET网站管理系统退出 清除浏览器缓存,Session的代码

    1.在系统登陆成功时记录登陆的用户名.密码等信息(登陆功能的部分代码) 复制代码 代码如下: Session["id"] = user.id.ToString(); Session["name"] = user.name.ToString(); Session["pwd"] = user.password.ToString(); Session["time"] = user.LoginTime.ToString(); Sess

  • 解决J2EE-session在浏览器关闭后失效问题

    前几天在做一个签到系统时,遇到了喜闻乐见的session问题,项目为Spring+SpringMVC+Mybatis框架,maven管理目录的javaweb端系统,对于session的一些问题,作出以下分析,在这里,着重讨论session生命周期的问题,至于其他定义,不做解释: 首先,说明一下session的生命周期: 存储:Session存储在服务器端,一般为了防止在服务器的内存中(为了高速存取),Sessinon在用户访问第一次访问服务器时创建,需要注意只有访问JSP.Servlet等程序时

  • 浏览器关闭后,能继续执行的php函数(ignore_user_abort)

    多的不说,直接上代码: 复制代码 代码如下: ignore_user_abort(true); //设置客户端断开连接时是否中断脚本的执行 set_time_limit(0); $file = '/tmp/ignore_user.txt'; if(!file_exists($file)) { file_put_contents($file); } if(!$handle = fopen($file,'a+b')){ echo "not open file :".$file; exit;

  • BootStrap的alert提示框的关闭后再显示怎么解决

    bootstrap中有alert组件,如果点击关闭按钮后该组件会被删除而不是被隐藏,想再显示怎么办呢? bootstrap-alert.js源码片段: function removeElement() { $parent .trigger('closed') .remove() } 理论上把.remove()改为.hide(),然后在需要重新显示的地方,加上$('#alert').show();就可以了. 但实际应用中,可以把 close button 的 data-dismiss 去掉,加上

  • 解决使用vue.js路由后失效的问题

    新学了vue.js中的路由 在之前写的vue的demo上加上了简单的路由例子(来自vue-router 2),但是加上点击后只有地址栏变化,内容并不变.且之前用jquery写的一些效果也失效了.最后找到原因是因为同一个id被启动了两次(第一次是之前使用vue组件时启动的,另外一个是路由时启动的) 附上部分代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <!-- 引入样式

  • 快速解决pyqt5窗体关闭后子线程不同时退出的问题

    用pyqt5设计了一个主窗体,在窗体运行时需要把一个无限循环放在一个线程去工作.运行后,发现通过鼠标按主窗体的关闭按键关闭主创体后,线程不会自动终止,依然在运行.尽管对我的使用场景来说,这不是问题,因为立马就关机了.但在调试阶段就恨繁,因为后台线程很占资源.怎么能让主窗体关闭是子线程也退出呢?百度了许久,很多方法都不行. 主要试过的有: 1.设置:self.thread.Daemon=True 2.在子线程设置一个变量,通过改变变量的值使循环不满足条件,自动结束 3.设置析构函数 还有别的奇葩.

  • 解决Redis设置密码重启后失效的问题

    原因可能有两个: 1.只是单纯的通过命令行设置了密码,这种设置方式是临时的,当服务器重启后,密码会失效. config set requirepass yourPassword 解决方案:在redis的配置文件中直接配置密码 配置文件中有一行是这样的 #requirepass foobared 去掉注释,并且把foobared改为自己的密码 如: requirepass mypwd 2.如果你已经按照上面的方法在配置文件中设置了密码,但启动后仍旧无效,说明你肯定没有指定配置文件运行.服务端也会报

  • 解决laravel session失效的问题

    最新在学习laravel,用到了session,因为laravel没法用$_SESSION 所以只能用框架的session. 贴上代码 <?php namespace App\Http\Controllers; use App\Http\Requests; use Request; use Illuminate\Support\Facades\Session; class CommonController extends Controller { static function login(){

  • 解决python父线程关闭后子线程不关闭问题

    我们都知道,python可以通过threading module来创建新的线程,然而在创建线程的线程(父线程)关闭之后,相应的子线程可能却没有关闭,这可能是因为代码中没有使用setDaemon(True)函数. 接下来,使用一个例子来说明: import threading def prt_hello() : while 1 : print 'hello' if __name__ == '__main__' : t = threading.Thread(target=prt_hello) t.s

  • 解决spring结合mybatis时一级缓存失效的问题

    之前了解到mybatis的一级缓存是默认开启的,作用域是sqlSession,是基 HashMap的本地缓存.不同的SqlSession之间的缓存数据区域互不影响. 当进行select.update.delete操作后并且commit事物到数据库之后,sqlSession中的Cache自动被清空 <setting name="localCacheScope" value="SESSION"/> 结论 spring结合mybatis后,一级缓存作用: 在未

  • Oracle9i数据库异常关闭后的启动

    正在看的ORACLE教程是:Oracle9i数据库异常关闭后的启动.Oracle shutdown的时候突然断电,导致使用sql/plus启动时无法连接到数据库,具体描述为: connection can not permitted, shut in progress. 到dos 提示符 键入: c:\> sqlplus /nolog 显示: sql/plus: Realease9.0.2--..all rights reserved sql> connect /as sysdba 显示已连接

随机推荐