apache shiro分布式session共享实战(redis版)

时间:2022-12-22 16:25:02

源码下载: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();			}		}	}}


5、上图:

apache shiro分布式session共享实战(redis版)