Tomcat 之session 持久化原理

几个概念:

Manager 接口,其实就是指的是对  其Sesison 的管理, 其默认实现是StandardManager (内部没有任何Store对象实例,而仅仅是通过 File 序列化实现的),它其实就是把session 保存到了本地的名为SESSIONS.ser 的文件;另外有PersistentManager,保存到本地文件(内部有一个FileStore)或数据库表(通过JDBCStore)。 除此之外,还有提供 集群的BackupManager 等。

Store 则是专门指的是对Session 的存储接口。

Store 有几个实现, 一是基于本地文件的实现: FileStore, 另外一个是基于数据库的实现: JDBCStore。 当然,这里是没有内存的实现的, 试想,基于的内存的话,又如何做持久化呢?

大致的原理:

Tomcat 是怎么具体实行 session 持久的呢? 这样的, 当我们访问某个web 应用的时候,然后进行某些操作,这样Session里面会存在一些属性,然后我们关闭tomcat,tomcat会把session 通过  Manager  写到本地会数据库中,然后我们启动tomcat,tomcat会通过 Manger 恢复原先持久化的 Session相关属性( 不管是StandardManager ,PersistentManager 都是这样)。

注意,这里我们必须要对某个web 应用做一些操作, 这样, tomcat才会对应的分配一个 session, 否则session不存在, 自然, 也是无法持久化的; 另外 我们必须优雅的关闭tomcat, 这样tomcat才会有机会在shutdown的时候 将session持久化。 通过 ctrl + c 或 shutdown脚本都是可以的, 但是 直接 kill, 是不行的。

Tomcat 的session 持久,默认是支持的, 好奇怪,竟然一直没有发现! 那让我们做个测试吧!

简单测试:

这里我做了个简单的测试。怎么测试呢?

思路:

就是通过LkServlet 对Session写入一些东西, 然后停掉tomcat,再启动tomcat,看tomcat 是否能够把session恢复过来。

怎么看它是否能够恢复呢?  那就是 重启后, 直接访问SomeServlet, 通过SomeServlet 读取 Session的 attribute, 读取到了就是说明恢复成功,否则就是说明失败。

写session的 servlet:

package com.lk;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class LkServlet extends HttpServlet { @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { String username = req.getParameter("username");
String password = req.getParameter("password"); if ("aa".equals(username) && "bb".equals(password)) {
req.getRequestDispatcher("index.jsp").forward(req, resp);
User user = new User();
user.setUsername(username);
user.setPassword(password); req.getSession().setAttribute("user", user); // 这里的user 必须实现Serializeable 接口, 否则无法恢复
req.getSession().setAttribute("aaa", "AAAAAA");// 普通 字符串属性
req.getSession().setAttribute("bb", );  // 普通 数值属性
req.getSession().setAttribute("ccc", "how are you ! 你好啊 ! ");
}
} }

测试用的 Servlet:

package com.lk;

import java.io.IOException;
import java.util.Enumeration; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; public class SomeServlet extends HttpServlet { @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { HttpSession session = req.getSession();
Enumeration<String> attributeNames = session.getAttributeNames();
while (attributeNames.hasMoreElements()) {
String string = (String) attributeNames.nextElement();
System.out.println( string + " SomeServlet " + session.getAttribute(string));
} req.getRequestDispatcher("sess.jsp").forward(req, resp);
} }

其中:

package com.lk;

import java.io.Serializable;

public class User implements Serializable {

    /**
*
*/
private static final long serialVersionUID = 1L; @Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
private String username;
private String password; }

这里的User 是必须实现Serializable 接口的, 否则呢, tomcat 是不能够它持久到 本地文件或 数据库中去的。 不过奇怪的是, 不实现虽然不能进行持久化,却也不报错, 这个让我开始测试的时候, 迷惑了很久, 还以为是我哪里配置的问题呢!!

但是 其他的一些基本属性倒是 默认支持的。

web.xml 配置:

  <servlet>
<servlet-name>aaa</servlet-name>
<servlet-class>com.lk.LkServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>aaa</servlet-name>
<url-pattern>/lk</url-pattern>
</servlet-mapping> <servlet>
<servlet-name>ss</servlet-name>
<servlet-class>com.lk.SomeServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>ss</servlet-name>
<url-pattern>/ss</url-pattern>
</servlet-mapping>

重启后立即访问 http://localhost/ktb/ss , 结果:

十月 ,  :: 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["http-bio-80"]
十月 , :: 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["ajp-bio-8019"]
十月 , :: 下午 org.apache.catalina.startup.Catalina start
信息: Server startup in ms
aaa SomeServlet AAAAAA
bb SomeServlet
ccc SomeServlet how are you ! 你好啊 !
user SomeServlet User [username=aa, password=bb]

可见恢复成功!

参考:

http://www.cnblogs.com/fx2008/p/4148389.html

Tomcat 之session 持久化1的更多相关文章

  1. Tomcat 之session 持久化2

    通过前文 Tomcat 之session 持久化1 ,我们已经大概了解了这么个机制.但是我没能详细展开其底层的原理. 这篇文章,我想稍微深入一点点,再继续聊一聊其底层. Tomcat 之session ...

  2. 【Session】Tomcat中Session持久化到文件系统或数据库

    参考的优秀文章 Tomcat Session 持久化 Package org.apache.catalina.session 最近同事在做Session外置的功能,我对Session持久化.共享也不太 ...

  3. Tomcat下 session 持久化问题(重启服务器session 仍然存在)

    感谢大佬:https://www.iteye.com/blog/xiaolongfeixiang-560800 关于在线人数统计,大都使用SessionListener监听器实现. SessionLi ...

  4. 细说tomcat之session持久化探秘

    业务场景:通常,我们会在会话级别存放一些参数,期望在session生命周期内,可以一直取得保存在session中的指定数据:而只要session过期或者失效,则需要执行重新登录等操作.但是!我们对于这 ...

  5. tomcat 设置session过期时间(四种方式)

    1.在tomcat-->conf-->servler.xml文件中定义: <Context path="/test" docBase="/test&qu ...

  6. Tomcat生成的session持久化到MySQL

    Telling Tomcat to save session records in MySQL 此部分内容摘自 MySQL cookbook 3th.具体内容不做翻译,哈哈,懒 The default ...

  7. tomcat之Session的管理

    Session是由服务器端的应用服务器容器(如Tomcat.Jetty)存储的.下面分析一下Tomcat是如何管理Session的. 转自:tomcat架构分析 (Session管理) Tomcat中 ...

  8. java 中Session 持久化问题

    首先: 今天发现了个session 持久化的问题 在Tomcat 停止运行后再启动  session  中保存的东西还会存在 ,百度了一下 原理 1.Session Create 时 2.Sessio ...

  9. [转]session 持久化问题(重启服务器session 仍然存在)

    转:http://xiaolongfeixiang.iteye.com/blog/560800 关于在线人数统计,大都使用SessionListener监听器实现. SessionListener 触 ...

随机推荐

  1. ubuntu 阿里云 常出问题 运维工作日志

    一.2015-8.26(数据库 error—28) tmp文件临时数据写入不了----解决办法 1.查看临时文件 ls -l 找到了 2.由此可以查看得出来tmp文件有的权限是有的 3.查看tmp 存 ...

  2. php .htaccess文件使用详解

    1..htaccess文件使用前提 .htaccess的主要作用就是实现url改写,也就是当浏览器通过url访问到服务器某个文件夹时,作为主人,我们可以来接待这个url,具体地怎样接待它,就是此文件的 ...

  3. ubuntu 16.04 安装VS CODE时 此软件来自第三方且可能包含非自由组件

    先安装gdebi: sudo apt-get install gdebi 然后执行: sudo apt install ./vscode.deb

  4. SQL Server CONVERT() 日期转换为新数据类型的 通用函数

    http://www.w3school.com.cn/sql/func_convert.asp

  5. 【git】之常用命令

    再使用git过程常用的命令在6-10左右,但是如果你想精通git那么需要记住的命令在80左右, 下面看这张图,我们了解一下git的概念的常用操作! Workspace:工作区(例如eclipse的工作 ...

  6. C++进阶--placement new/delete

    //############################################################################ // Placement New 和 Pl ...

  7. Maven的classifier作用

    classifier可以是任意的字符串,用于拼接在GAV之后来确定指定的文件. 可用于区分不同jdk版本所生成的jar包 <dependency> <groupId>net.s ...

  8. [UE4]区分敌我

    第一方法是:使用Actor对象的Tag: 只要继承自Actor的对象,都会有Tags这个属性,这是一个数组,可以添加多个Tag. 在蓝图中可以使用“get Components by Tag”获得某个 ...

  9. 高通9X07模块QMI架构使用入门

    QMI(Qualcomm Message Interface) 高通用来替代OneRPC/DM的协议,用来与modem通信.本文是摸索高通QMI机制一点经验,重点解读了如果建立拨号连接,仅供参考.qm ...

  10. 第11章 拾遗5:IPv6和IPv4共存技术(2)_ISATAP隧道技术

    6.3 ISATAP隧道技术 (1)基本概念 ①在一个IPv4网络中主机与路由器之间创建一条ISATAP隧道,以便让该主机可以访问IPv6网络中的资源. ②条件:IPv4中的PC主机需要支持IPv4和 ...