博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring shiro redis : 将session存入redis,实现session共享
阅读量:4291 次
发布时间:2019-05-27

本文共 4795 字,大约阅读时间需要 15 分钟。

最近一年由于工作繁忙,加上各种事情比较多,好久没有更新文章了,向大家,也向自己说声抱歉!后面会继续将学习的内容分享出来!

项目遇到的问题:

启动项目,登录网站,输入用户名、密码,访问,
当项目tomcat停止,然后重新启动,
在网页继续访问时,因为session失效,被强制跳转到登录页面,提示重新登录,
这样在tomcat集群时,就会有问题,因此需要将session统一存放到redis中,项目的启动和停止不影响session。

我们的项目已经集成好了spring shiro redis,但是session没有存入redis实现共享,因此此文是实现session存入redis集群,共享部分功能:

(该项目借鉴了博文:)

解决步骤:

 

1-sessionManager添加sessionDAO属性

想要实现使用redis管理session 需要在shiro 的sessionmanager添加sessionDAO属性 如下

     a)如果是使用xml配置,如下:

b)如果是使用的spring注解配置,如下:

@Configurationpublic class ShiroConfig {	@Bean	public SessionManager sessionManager() {		DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();		Collection
listeners = new ArrayList
(); listeners.add(new ShiroSessionListener()); sessionManager.setSessionListeners(listeners); sessionManager.setSessionDAO(sessionDAO()); return sessionManager; } //SessionDAO是一个接口: org.apache.shiro.session.mgt.eis.SessionDAO //我们自己写一个类,类名是SessionDao ,继承EnterpriseCacheSessionDAO //而EnterpriseCacheSessionDAO和 SessionDAO的关系如下: //EnterpriseCacheSessionDAO extends CachingSessionDAO //CachingSessionDAO extends AbstractSessionDAO //AbstractSessionDAO implements SessionDAO @Bean public SessionDAO sessionDAO() { //改造后 SessionDao sessionDao = new SessionDao() ; return sessionDao ; //改造前// MemorySessionDAO sessionDAO = new MemorySessionDAO();// return sessionDAO; }}

2- 创建sessionDao类

sessionDao需要实现EnterpriseCacheSessionDAO类或者CachingSessionDAO类,咱们这里以EnterpriseCacheSessionDAO类为例如下:

public class SessionDao extends EnterpriseCacheSessionDAO {	//	Integer expireSeconds = 60*60*24 ;//60*60*24=7天		@Override	protected Serializable doCreate(Session session) {		Serializable sessionId = super.doCreate(session);		byte[] session_value = sessionToByte(session) ;		byte[] sessionId_key = sessionId.toString().getBytes() ;		RedisUtil.set(sessionId_key, session_value) ; 		return sessionId ;	}	@Override	protected void doDelete(Session session) {		super.doDelete(session);		RedisUtil.remove(session.getId().toString());	}	@Override	protected Session doReadSession(Serializable sessionId) {		Session session = super.doReadSession(sessionId);		if(session == null) {			byte[] sessionId_key = sessionId.toString().getBytes() ;			byte[] session_value = RedisUtil.get(sessionId_key) ;			if(session_value != null && session_value.length > 0){				session = byteToSession(session_value) ;			}		}		return session ;	}	@Override	protected void doUpdate(Session session) {		super.doUpdate(session);		byte[] session_value = sessionToByte(session) ;		byte[] sessionId_key = session.getId().toString().getBytes() ;		RedisUtil.set(sessionId_key, session_value) ; 	}		// 把session对象转化为byte保存到redis中    public byte[] sessionToByte(Session session){        ByteArrayOutputStream bo = new ByteArrayOutputStream();        byte[] bytes = null;        try {            ObjectOutput oo = new ObjectOutputStream(bo);            oo.writeObject(session);            bytes = bo.toByteArray();        } catch (IOException e) {            e.printStackTrace();        }        return bytes;    }     // 把byte还原为session    public Session byteToSession(byte[] bytes){        ByteArrayInputStream bi = new ByteArrayInputStream(bytes);        ObjectInputStream in;        SimpleSession session = null;        try {            in = new ObjectInputStream(bi);            session = (SimpleSession) in.readObject();        } catch (ClassNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }            return session;    }}

3-redisUtil类如下:

@Componentpublic class RedisUtil {	@Autowired	private JedisCluster jCluster ;		private static JedisCluster jedisCluster ;		@PostConstruct	public void init() {		jedisCluster = jCluster ;	}	/**	 * 写入缓存,无超时功能	 * 	 * @param key	 * @param value	 * @return	 */	public static boolean set(final byte[] key, byte[] value) {		boolean result = false;		try {			jedisCluster.set(key, value) ;			result = true;		} catch (Exception e) {			e.printStackTrace();		}		return result;	}	/**	 * 写入缓存,带有超时功能	 * 	 * @param key	 * @param value	 * @param expireSeconds	 * @return	 */	public static boolean set(final byte[] key, byte[] value, int expireSeconds) {		boolean result = false;		try {			jedisCluster.set(key, value) ;			jedisCluster.expire(key, expireSeconds) ;			result = true;		} catch (Exception e) {			e.printStackTrace();		}		return result;	}		public static void remove(final String key) {		if (exists(key)) {			jedisCluster.del(key);		}	}		public static boolean exists(final String key) {		return jedisCluster.exists(key);	}		public static byte[] get(final byte[] key) {		byte[] result = jedisCluster.get(key) ;		return result;	}}

测试:

启动项目,登录网站,访问,

然后将项目停止,重新启动,

继续访问,依然可以正常使用登录后的一起状态。

测试成功

 

转载地址:http://sbqgi.baihongyu.com/

你可能感兴趣的文章
jdbc_javax包
查看>>
Android 6.0 APIs_新特性(google官方)
查看>>
maxwell斗胆也来谈谈"学习方法“_转自黑马论坛
查看>>
XML解析
查看>>
AndroidManifest.xml详解
查看>>
activity的xml详解
查看>>
JNI 简介与实现-JavaNativeInterface
查看>>
ResourceBundle和Properties
查看>>
javascript *** is not a function
查看>>
老韩思考:卖点----卖豆腐的能转行IT
查看>>
Android_属性动画
查看>>
网络下载-xUtils,HttpUtils
查看>>
网络下载-AsyncHttpClient
查看>>
myUtils-多线程下载
查看>>
网络下载-断点续传原理
查看>>
线程-消息回环处理机制
查看>>
感谢伤害我的人
查看>>
请不要做浮躁的人----(学习编程的忠告)
查看>>
网络_volley_使用方法和代码
查看>>
网络_AsyncHttpClient_使用方法和代码
查看>>