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. CAD求交点函数

    public void IntersectWith( Entity entityPointer, Intersect intersectType, Point3dCollection points, ...

  2. WARNING: Package of target [javax.servlet.jsp.jstl.core.LoopTagSupport$1Status@7439e436] or package of member [public int javax.servlet.jsp.jstl.core.LoopTagSupport$1Status.getIndex()] are excluded!

    Struts2爆出045漏洞后,将struts版本升级到了2.3.32.但是在验证时发现有些jstl循环未出现预期的结果. debug发现,数据没有问题,断定是前端页面显示出了问题.根据日志信息WAR ...

  3. PAT 乙级 1010 一元多项式求导 (25) C++版

    1010. 一元多项式求导 (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 设计函数求一元多项式的导数.(注:xn(n为整数)的一 ...

  4. vue之v-for

    vue.js 的循环渲染是依赖于 v-for 指令,它能够根据 vue 的实例里面的信息,循环遍历所需数据,然后渲染出相应的内容.它可以遍历数组类型以及对象类型的数据,js 里面的数组本身实质上也是对 ...

  5. CentOS7 yum安装Java+Apache(httpd)+Tomcat并开启自启动

    首先,感觉yum里的东西质量不好的可以先换源. http://blog.csdn.net/qq_36731677/article/details/58288979 一.查询 两种方式可查询安装包 yu ...

  6. 升级安装APK兼容Android7.0,解决FileUriExposedException

    见http://blog.csdn.net/ruancoder/article/details/67639621?utm_source=itdadao&utm_medium=referral

  7. vue 非父子组件传值

    /*非父子组件传值 1.新建一个js文件 然后引入vue 实例化vue 最后暴露这个实例 2.在要广播的地方引入刚才定义的实例 3.通过 VueEmit.$emit('名称','数据') 4.在接收收 ...

  8. iOS 结构化数据访问

    一.介绍 在存储大量数据时,除了最基本的打开文件,读取文件,存盘等这些没有明确管理机制的方式来存储数据外,iOS还提供了另外几种重要的数据存储方式.虽然这些方式最后还是将数据存储在文件中,但是iOS以 ...

  9. boost 学习笔记 2: timer

    boost 学习笔记 2: timer copy from:http://einverne.github.io/post/2015/12/boost-learning-note-2.html 1:ti ...

  10. gulp 编译es6 探究

    1.gulp配置: var gulp = require('gulp') var fs = require("fs") var babelify = require('babeli ...