源码下载:http://pan.baidu.com/s/1ntD0BwP
1、原理
所有session集中管理,根据sessionId做标识,session对象用objectStream做序列化,缓存到redis中
2、环境搭建
①配置jdk7、gradle2.2.1、redis3.0.4环境;
②在java代码中配置org.demo.shiro.rediscache.RedisClient.redisServerIp
3、运行shiro-redis-session\gradle-jettyRun.bat(不用打开eclipse)
4、关键代码分析(重写shiro的会话dao)
package org.demo.shiro.rediscache;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RedisSessionDao extends AbstractSessionDAO {
private RedisClient sessionCacheClient=new RedisClient();
Logger log= LoggerFactory.getLogger(getClass());
@Override
public void update(Session session) throws UnknownSessionException {
log.info("更新seesion,id=[{}]",session.getId().toString());
try {
sessionCacheClient.replace(session.getId().toString(), session);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void delete(Session session) {
log.info("删除seesion,id=[{}]",session.getId().toString());
try {
sessionCacheClient.delete(session.getId().toString());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Collection<Session> getActiveSessions() {
log.info("获取存活的session");
return Collections.emptySet();
}
@Override
protected Serializable doCreate(Session session) {
Serializable sessionId = generateSessionId(session);
assignSessionId(session, sessionId);
log.info("创建seesion,id=[{}]",session.getId().toString());
try {
sessionCacheClient.set(sessionId.toString(), session);
} catch (Exception e) {
log.error(e.getMessage());
}
return sessionId;
}
@Override
protected Session doReadSession(Serializable sessionId) {
log.info("获取seesion,id=[{}]",sessionId.toString());
Session session = null;
try {
session = (Session) sessionCacheClient.get(sessionId.toString());
} catch (Exception e) {
log.error(e.getMessage());
}
return session;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="myRealm" class="org.demo.shiro.MyRealm" />
<!-- 会话管理器 -->
<bean id="sessionManager"
class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionValidationSchedulerEnabled" value="false" />
<property name="sessionDAO" ref="sessionDAO" />
<property name="globalSessionTimeout" value="60000" />
</bean>
<bean id="sessionDAO" class="org.demo.shiro.rediscache.RedisSessionDao"></bean>
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="sessionManager" ref="sessionManager" />
<!-- <property name="cacheManager" ref="shiroCacheManager" /> -->
<property name="realm" ref="myRealm" />
</bean>
<bean id="shiroFilter" class="org.demo.shiro.MyShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/" />
<!-- <property name="successUrl" value="/system/main"/> -->
<property name="unauthorizedUrl" value="/" />
</bean>
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
</beans>
package org.demo.shiro.rediscache;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.session.Session;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class RedisClient {
private static JedisPool pool;
private static String redisServerIp="124.193.90.xx";
/**
* 建立连接池 真实环境,一般把配置参数缺抽取出来。
*
*/
private static void createJedisPool() {
// 建立连接池配置参数
JedisPoolConfig config = new JedisPoolConfig();
// 设置最大连接数
config.setMaxActive(1000);
// 设置最大阻塞时间,记住是毫秒数milliseconds
config.setMaxWait(1000);
// 设置空间连接
config.setMaxIdle(10);
// 创建连接池
pool = new JedisPool(config, redisServerIp, 6379);
}
/**
* 在多线程环境同步初始化
*/
private static synchronized void poolInit() {
if (pool == null)
createJedisPool();
}
/**
* 获取一个jedis 对象
*
* @return
*/
private static Jedis getJedis() {
if (pool == null)
poolInit();
return pool.getResource();
}
/**
* 归还一个连接
*
* @param jedis
*/
private static void returnRes(Jedis jedis) {
pool.returnResource(jedis);
}
void set(String sessionId, Session session) {
jedis = getJedis();
jedis.append(sessionId, serialize(session));
returnRes(jedis);
}
void replace(String sessionId, Session session) {
set(sessionId, session);
}
Jedis jedis = null;
void delete(String sessionId) {
jedis = getJedis();
jedis.del(sessionId);
returnRes(jedis);
}
Object get(String sessionId) {
jedis = getJedis();
Object obj = deserialize(jedis.get(sessionId));
returnRes(jedis);
return obj;
}
private static Object deserialize(String str) {
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
bis = new ByteArrayInputStream(Base64.decode(str));
ois = new ObjectInputStream(bis);
return ois.readObject();
} catch (Exception e) {
throw new RuntimeException("deserialize session error", e);
} finally {
try {
ois.close();
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static String serialize(Object obj) {
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
try {
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
return Base64.encodeToString(bos.toByteArray());
} catch (Exception e) {
throw new RuntimeException("serialize session error", e);
} finally {
try {
oos.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}