參考的優秀文章
Package org.apache.catalina.session
最近同事在做Session外置的功能,我對Session持久化、共享也不太了解,學習一下。
一般來說,Tomcat原生的持久化Session方式,有StandardManager和PersistentManager。
版本說明:apache-tomcat-7.0.69-windows-x64
關閉、重啟Tomcat,是否持久化Session
Tomcat在關閉的時候,持久化Session到工作目錄中,然后再次啟動時再加載,對用戶感覺Session是持續地存在的。
頁面用到一個實體類:

package com.nicchagil.session; import java.io.Serializable; public class User implements Serializable { private static final long serialVersionUID = 1L; private Integer id; private String userName; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } @Override public String toString() { return "User [id=" + id + ", userName=" + userName + "]"; } }
(擴展知識)關於序列化:
需注意的是:因為到時Session需要序列化到文件系統中,而這個類的對象需要放到Session中,所以這個類需要被序列化,故實現序列化接口。
如果實現序列化接口,強烈建議顯示定義serialVersionUID,它表明了序列化版本號。如果沒定義,serialVersionUID將由JVM自動運算,而serialVersionUID的運算值高度依賴class的編譯結果,所以,基於穩定性考慮,我們還是顯式定義此class的序列化版本為上。
實驗步驟:
1、啟動Tomcat,我們寫入往Session寫入一些東西。如果不確認是否寫入,可以嘗試讀取出來,是否成功讀取。
2、關閉Tomcat,查看Tomcat的工作目錄的有沒有SESSIONS.ser文件。
文件的路徑可能跟我們運行的環境有關:
如果我用Tomcat獨立運行,該文件位於:D:\green\apache-tomcat-7.0.69-windows-x64\apache-tomcat-7.0.69\work\Catalina\localhost\041SessionSerialization\SESSIONS.ser
如果在Eclipse運行Tomcat,因Tomcat的工作目錄配置不同(不同的配置方式又不同),該文件在於:D:\workspace\jee_workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\041SessionSerialization\SESSIONS.ser
3、啟動Tomcat,在沒有寫入Session的前提下,嘗試讀取Session,以測試Tomcat是否把持久化的Session恢復。
注:
如果Session重啟后沒有恢復,檢查Tomcat的context.xml配置文件的這個部分:

<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
默認的Tomcat配置是注釋着的,說明沒有禁用持久化緩存的功能,說明Tomcat重啟時默認持久化Session。
使用PersistentManager持久化Session
PersistentManager的主要功能:在系統運行中,持久化Session或恢復Session。
它的意義在於:
1、Tomcat關閉、重啟時的Session持久化
2、備份Session以增強系統容錯能力
3、將處理內存的Session持久化到硬盤,避免因Session過多而內存溢出
持久化到文件系統
將Session持久化到文件系統的配置:

<Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true" maxActiveSession="-1" minIdleSwap="0" maxIdleSwap="30" maxIdleBackup="0" > <Store className="org.apache.catalina.session.FileStore" checkInterval="60" directory="../session/mySession.session"/> </Manager>
啟動Tomcat后,寫入Session后,觀察TOMCAT_HOME/work/Catalina/localhost/session下文件的變化。
持久化到數據庫
將Session持久化到數據庫的配置:
跟上例類似,只不過這次的store是DB的store,是存儲策略的不同。(這里測試使用MySQL 5.0)

<Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true" maxActiveSession="-1" minIdleSwap="0" maxIdleSwap="30" maxIdleBackup="0" > <!-- file store --> <!-- <Store className="org.apache.catalina.session.FileStore" checkInterval="60" directory="../session"/> --> <!-- db store --> <Store className="org.apache.catalina.session.JDBCStore" driverName="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/demo?user=root&password=123456" sessionTable="t_session" sessionIdCol="session_id" sessionDataCol="data" sessionValidCol="session_valid" sessionMaxInactiveCol="max_inactive" sessionLastAccessedCol="last_access" sessionAppCol="application_name" checkInterval="60" debug="99" /> </Manager>
然后表結構如下:

CREATE TABLE `t_session` ( `session_id` varchar(128) DEFAULT NULL, `data` mediumblob, `max_inactive` int(128) DEFAULT NULL, `last_access` bigint(20) DEFAULT NULL, `application_name` varchar(128) DEFAULT NULL, `session_valid` char(1) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
記得將MySQL的驅動包放入Tomcat的lib目錄下。
啟動后,寫入Session后,觀察t_session的變化。
附錄
用到的類的關系圖
更多配置
關於StandardManager和PersistentManager更多的配置,請見Package org.apache.catalina.session。