第十章 会话管理(四) 会话存储/持久化

第十章 Demo(待完善)


Shiro 提供SessionDAO 用于会话的CRUD,即DAO(Data Access Object)模式实现:

1. 如DefaultSessionManager 在创建完session 后会调用该方法;如保存到关系数据库/文件系统/NoSQL 数据库;即可以实现会话的持久化;返回会话ID;主要此处返回的ID.equals(session.getId());

Serializable create(Session session);

2. 根据会话ID获取会话

Session readSession(Serializable sessionId) throws UnknownSessionException;

3. 更新会话;如更新会话最后访问时间/停止会话/设置超时时间/设置移除属性等会调用

void update(Session session) throws UnknownSessionException;

4. 删除会话;当会话过期/会话停止(如用户退出时)会调用

void delete(Session session);

5. 获取当前所有活跃用户,如果用户量多此方法影响性能

Collection<Session> getActiveSessions();

Shiro 内嵌了如下SessionDAO 实现:


AbstractSessionDAO提供了SessionDAO的基础实现,如生成会话ID等;

CachingSessionDAO提供了对开发者透明的会话缓存的功能,只需要设置相应的CacheManager 即可;

MemorySessionDAO 直接在内存中进行会话维护;

EnterpriseCacheSessionDAO 提供了缓存功能的会话维护,默认情况下使用MapCache 实现,内部使用ConcurrentHashMap 保存缓存的会话。


可以通过如下配置设置SessionDAO:

sessionDAO=org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
sessionManager.sessionDAO=$sessionDAO

一、 Shiro 提供了使用Ehcache 进行会话存储,Ehcache 可以配合TerraCotta 实现容器无关的分布式集群。

首先在pom.xml里添加如下依赖:

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-ehcache</artifactId>
    <version>1.2.2</version>
</dependency>


接着配置shiro-web.ini文件:

sessionDAO=org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
sessionDAO.activeSessionsCacheName=shiro-activeSessionCache
sessionIdGenerator=org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator
sessionDAO.sessionIdGenerator=$sessionIdGenerator
sessionManager.sessionDAO=$sessionDAO
cacheManager=org.apache.shiro.cache.ehcache.EhCacheManager
cacheManager.cacheManagerConfigFile=classpath:ehcache.xml
securityManager.cacheManager=$cacheManager
securityManager.sessionManager=$sessionManager

sessionDAO. activeSessionsCacheName : 设置Session 缓存名字, 默认就是shiro-activeSessionCache;

cacheManager:缓存管理器,用于管理缓存的,此处使用Ehcache实现;

cacheManager.cacheManagerConfigFile:设置ehcache缓存的配置文件;

securityManager.cacheManager:设置SecurityManager的cacheManager,会自动设置实现了CacheManagerAware接口的相应对象,如SessionDAO 的cacheManager;


然后配置ehcache.xml:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="es">
<!--     <diskStore path="java.io.tmpdir"/> -->
    <cache name="shiro-activeSessionCache"
           maxEntriesLocalHeap="10000"
           overflowToDisk="false"
           eternal="false"
           diskPersistent="false"
           timeToLiveSeconds="0"
           timeToIdleSeconds="0"
           statistics="true"/>
</ehcache>

Cache的名字为shiro-activeSessionCache,即设置的sessionDAO的activeSessionsCacheName属性值。

另外可以通过如下ini配置设置会话ID 生成器:

sessionIdGenerator=org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator
sessionDAO.sessionIdGenerator=$sessionIdGenerator

用于生成会话ID,默认就是JavaUuidSessionIdGenerator,使用java.util.UUID生成。


如果自定义实现SessionDAO,继承CachingSessionDAO 即可:

public class MySessionDao extends CachingSessionDAO{
	private JdbcTemplate jdbcTemplate = JdbcTemplateUtils.jdbcTemplate();
	protected Serializable doCreate(Session session) {
		System.out.println("doCreate");
		Serializable sessionId = generateSessionId(session);
		assignSessionId(session, sessionId);
		String sql = "insert into sessions (id,session) values (?,?)";
		jdbcTemplate.update(sql, sessionId,SerializableUtils.serialize(session));
		return session.getId();
	}
	protected void doUpdate(Session session) {
		System.out.println("doUpdate");
		if(session instanceof ValidatingSession && !((ValidatingSession)session).isValid()){
			return;//如果会话过期/停止,没必要再更新了
		}
		String sql = "update sessions set session=? where id=?";
		jdbcTemplate.update(sql,SerializableUtils.serialize(session),session.getId());
	}
	protected void doDelete(Session session) {
		System.out.println("doDelete");
		String sql="delete from sessions where id = ?";
		jdbcTemplate.update(sql,session.getId());
	}
	protected Session doReadSession(Serializable sessionId) {
		System.out.println("doReadSession");
		String sql = "select session from sessions where id = ?";
		List<String> sessionStrList = jdbcTemplate.queryForList(sql,String.class,sessionId);
		if(sessionStrList.size()==0) return null;
		return SerializableUtils.deserialize(sessionStrList.get(0));
	}
}

doCreate/doUpdate/doDelete/doReadSession 分别代表创建/修改/删除/读取会话;此处通过把会话序列化后存储到数据库实现;接着在shiro-web.ini中配置:

sessionDAO=session.dao.MySessionDao

其他设置和之前一样,因为继承了CachingSessionDAO;所有在读取时会先查缓存中是否存在,如果找不到才到数据库中查找。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值