spring,shiro,redis實現session共用

來源:互聯網
上載者:User

spring-shiro 整合請看shiro springmvc整合第一步

spring-redis整合請看spring redis整合

用到的redis jar如下

<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.6.2</version></dependency><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>1.4.1.RELEASE</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.2</version></dependency>

想要實現使用redis管理session 需要在shiro 的sessionmanager添加sessionDAO屬性 如下

<bean id="sessionManager"class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"><property name="sessionDAO" ref="sessionDao"></property><property name="globalSessionTimeout" value="60000" /><!-- 刪除失效session --><property name="sessionValidationSchedulerEnabled" value="true" /><property name="sessionListeners" ref="myShiroSessionListener"></property></bean><bean id="myShiroSessionListener" class="com.zyc.listener.MyShiroSessionListener"></bean><bean id="sessionDao" class="com.zyc.security.SessionDao"><property name="redisUtil" ref="redisUtil"></property></bean>
redis配置如下

<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"><property name="maxIdle" value="100" /><property name="maxWaitMillis" value="10000" /><property name="testOnBorrow" value="true" /></bean><!-- redis伺服器中心 --><bean id="connectionFactory"class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"><property name="poolConfig" ref="poolConfig" /><property name="port" value="63791" /><property name="hostName" value="127.0.0.1" /><!-- <property name="password" value="${redis.password}" /> --><property name="timeout" value="10000"></property></bean><bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"><property name="connectionFactory" ref="connectionFactory" /><property name="keySerializer"><beanclass="org.springframework.data.redis.serializer.StringRedisSerializer" /></property><property name="valueSerializer"><beanclass="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" /></property></bean>

sessionDao需要實現EnterpriseCacheSessionDAO類或者CachingSessionDAO類,咱們這裡以EnterpriseCacheSessionDAO類為例如下:

package com.zyc.security;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutput;import java.io.ObjectOutputStream;import java.io.Serializable;import org.apache.shiro.session.Session;import org.apache.shiro.session.mgt.SimpleSession;import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;public class SessionDao extends EnterpriseCacheSessionDAO {private RedisUtil redisUtil;public RedisUtil getRedisUtil() {return redisUtil;}public void setRedisUtil(RedisUtil redisUtil) {this.redisUtil = redisUtil;}// 建立session,儲存到資料庫    @Override    protected Serializable doCreate(Session session) {        Serializable sessionId = super.doCreate(session);        redisUtil.set(sessionId.toString(), sessionToByte(session),1*60L);                return sessionId;    }    // 擷取session    @Override    protected Session doReadSession(Serializable sessionId) {        // 先從緩衝中擷取session,如果沒有再去資料庫中擷取        Session session = super.doReadSession(sessionId);         if(session == null){            byte[] bytes = (byte[]) redisUtil.get(sessionId.toString());            if(bytes != null && bytes.length > 0){                session = byteToSession(bytes);                }        }        return session;    }    // 更新session的最後一次訪問時間    @Override    protected void doUpdate(Session session) {        super.doUpdate(session);        redisUtil.set(session.getId().toString(), sessionToByte(session),1*60L);    }    // 刪除session    @Override    protected void doDelete(Session session) {        super.doDelete(session);        redisUtil.remove(session.getId().toString());    }    // 把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;    }}
RedisUtil工具類如下:

package com.zyc.security;import java.io.Serializable;import java.util.Set;import java.util.concurrent.TimeUnit;import javax.annotation.Resource;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.ValueOperations;import org.springframework.stereotype.Service;/** * @author: zyc * @date:2017年10月24日 上午9:26:55 * @description: * @version : *  */@Service("redisUtil")public class RedisUtil {private Logger logger = LoggerFactory.getLogger(RedisUtil.class);@Resource(name = "redisTemplate")private RedisTemplate<Serializable, Object> redisTemplate;/** * 大量刪除對應的value *  * @param keys */public void remove(final String... keys) {for (String key : keys) {remove(key);}}/** * 大量刪除key *  * @param pattern */public void removePattern(final String pattern) {Set<Serializable> keys = redisTemplate.keys(pattern);if (keys.size() > 0)redisTemplate.delete(keys);}/** * 刪除對應的value *  * @param key */public void remove(final String key) {if (exists(key)) {redisTemplate.delete(key);}}/** * 判斷緩衝中是否有對應的value *  * @param key * @return */public boolean exists(final String key) {return redisTemplate.hasKey(key);}/** * 擷取所有的key *  * @return */public Set<Serializable> keys() {return redisTemplate.keys("*");}/** * 讀取緩衝 *  * @param key * @return */public Object get(final String key) {Object result = null;ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();result = operations.get(key);return result;}/** * 寫入緩衝 *  * @param key * @param value * @return */public boolean set(final String key, Object value) {boolean result = false;try {ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();operations.set(key, value);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/** * 寫入緩衝 *  * @param key * @param value * @return */public boolean set(final String key, Object value, Long expireTime) {boolean result = false;try {ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();operations.set(key, value);redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);result = true;} catch (Exception e) {e.printStackTrace();}return result;}public void setRedisTemplate(RedisTemplate<Serializable, Object> redisTemplate) {this.redisTemplate = redisTemplate;}}

session監聽類如下(可寫可不寫,不寫需要在配置中將監聽器給去掉):

package com.zyc.listener;import org.apache.shiro.session.Session;import org.apache.shiro.session.SessionListener;import com.zyc.security.RedisUtil;import com.zyc.security.SpringContext;public class MyShiroSessionListener implements SessionListener {@Overridepublic void onStart(Session session) {}@Overridepublic void onStop(Session session) {// TODO Auto-generated method stubSystem.out.println("onStop==="+session.getId());RedisUtil redisUtil=(RedisUtil) SpringContext.getBean("redisUtil");redisUtil.remove(session.getId().toString());}@Overridepublic void onExpiration(Session session) {System.out.println("onExpiration==="+session.getId());RedisUtil redisUtil=(RedisUtil) SpringContext.getBean("redisUtil");redisUtil.remove(session.getId().toString());}}
SpringContext是擷取bean的一個工具類:

package com.zyc.security;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Component;@Componentpublic class SpringContext implements  ApplicationContextAware{private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext arg0)throws BeansException {// TODO Auto-generated method stubapplicationContext=arg0;}public static Object getBean(String name){if(applicationContext!=null){return applicationContext.getBean(name);}return null;}}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.