1.序列化工具類:java
import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.SerializationException; import org.springframework.core.convert.converter.Converter; import org.springframework.core.serializer.support.DeserializingConverter; import org.springframework.core.serializer.support.SerializingConverter; /** * redis序列化對象 */ public class RedisObjectSerializer implements RedisSerializer<Object> { private Converter<Object, byte[]> serializer = new SerializingConverter(); private Converter<byte[], Object> deserializer = new DeserializingConverter(); static final byte[] EMPTY_ARRAY = new byte[0]; public Object deserialize(byte[] bytes) { if (isEmpty(bytes)) { return null; } try { return deserializer.convert(bytes); } catch (Exception ex) { throw new SerializationException("Cannot deserialize", ex); } } public byte[] serialize(Object object) { if (object == null) { return EMPTY_ARRAY; } try { return serializer.convert(object); } catch (Exception ex) { return EMPTY_ARRAY; } } private boolean isEmpty(byte[] data) { return (data == null || data.length == 0); } }
2.從redis讀寫session的類:RedisSessionDAO,實現共享sessionweb
/** * redis實現共享session */ public class RedisSessionDAO extends EnterpriseCacheSessionDAO { private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class); // session 在redis過時時間是30分鐘30*60 private static int expireTime = 1800; private static String prefix = "shiro_redis_session:"; @Resource private RedisTemplate<String, Object> redisTemplate; public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) { this.redisTemplate = redisTemplate; } // 建立session,保存到數據庫 @Override protected Serializable doCreate(Session session) { Serializable sessionId = super.doCreate(session); logger.debug("建立session:{}", session.getId()); redisTemplate.opsForValue().set(prefix + sessionId.toString(), session); return sessionId; } // 獲取session @Override protected Session doReadSession(Serializable sessionId) { logger.debug("獲取session:{}", sessionId); // 先從緩存中獲取session,若是沒有再去數據庫中獲取 Session session = super.doReadSession(sessionId); if (session == null) { session = (Session) redisTemplate.opsForValue().get(prefix + sessionId.toString()); } return session; } // 更新session的最後一次訪問時間 @Override protected void doUpdate(Session session) { super.doUpdate(session); logger.debug("獲取session:{}", session.getId()); String key = prefix + session.getId().toString(); if (!redisTemplate.hasKey(key)) { redisTemplate.opsForValue().set(key, session); } redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); } // 刪除session @Override protected void doDelete(Session session) { logger.debug("刪除session:{}", session.getId()); super.doDelete(session); redisTemplate.delete(prefix + session.getId().toString()); } }
3.RedisCacheManager,實現redis進行緩存管理:redis
import javax.annotation.Resource; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheException; import org.apache.shiro.cache.CacheManager; import org.springframework.data.redis.core.RedisTemplate; public class RedisCacheManager implements CacheManager { @Resource private RedisTemplate<String, Object> redisTemplate; @Override public <K, V> Cache<K, V> getCache(String name) throws CacheException { return new ShiroCache<K, V>(name, redisTemplate); } public RedisTemplate<String, Object> getRedisTemplate() { return redisTemplate; } public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) { this.redisTemplate = redisTemplate; } }
4.重寫,配置緩存管理:ShiroCache<K, V>spring
import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheException; import org.springframework.data.redis.core.RedisTemplate; @SuppressWarnings("unchecked") public class ShiroCache<K, V> implements Cache<K, V> { private static final String REDIS_SHIRO_CACHE = "shiro_redis_session:"; private String cacheKey; private RedisTemplate<K, V> redisTemplate; private long globExpire = 30; @SuppressWarnings("rawtypes") public ShiroCache(String name, RedisTemplate client) { // this.cacheKey = REDIS_SHIRO_CACHE + name + ":"; this.cacheKey = REDIS_SHIRO_CACHE; this.redisTemplate = client; } @Override public V get(K key) throws CacheException { redisTemplate.boundValueOps(getCacheKey(key)).expire(globExpire, TimeUnit.MINUTES); return redisTemplate.boundValueOps(getCacheKey(key)).get(); } @Override public V put(K key, V value) throws CacheException { V old = get(key); redisTemplate.boundValueOps(getCacheKey(key)).set(value); return old; } @Override public V remove(K key) throws CacheException { V old = get(key); redisTemplate.delete(getCacheKey(key)); return old; } @Override public void clear() throws CacheException { redisTemplate.delete(keys()); } @Override public int size() { return keys().size(); } @Override public Set<K> keys() { return redisTemplate.keys(getCacheKey("*")); } @Override public Collection<V> values() { Set<K> set = keys(); List<V> list = new ArrayList<>(); for (K s : set) { list.add(get(s)); } return list; } private K getCacheKey(Object k) { return (K) (this.cacheKey + k); } }
5.配置redisConfig:數據庫
import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; import com.vcooc.experiment.utils.RedisObjectSerializer; /** * redis配置 * @author Administrator * */ @Configuration public class RedisConfig { @Bean public CacheManager cacheManager(RedisTemplate<Object, Object> redisTemplate) { RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); cacheManager.setDefaultExpiration(1800); return cacheManager; } //TODO @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new RedisObjectSerializer()); return template; } }
6.配置shiroConfig:apache
import java.util.HashMap; import java.util.Map; import org.apache.shiro.session.mgt.SessionManager; import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.RedisTemplate; import com.vcooc.experiment.shiro.RedisCacheManager; import com.vcooc.experiment.shiro.RedisSessionDAO; /** * * @author April.Chen */ @Configuration public class ShiroConfig { /* @Bean public UserRealm getUserRealm() { return new UserRealm(); }*/ @Bean public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } @Bean public RedisCacheManager redisCacheManager() { return new RedisCacheManager(); } @Bean public RedisSessionDAO redisSessionDAO() { RedisSessionDAO redisSessionDAO = new RedisSessionDAO(); redisSessionDAO.setRedisTemplate(new RedisTemplate<String,Object>()); return redisSessionDAO; } @Bean public SessionManager sessionManager() { DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); sessionManager.setSessionDAO(redisSessionDAO()); sessionManager.setGlobalSessionTimeout(1800); sessionManager.setCacheManager(redisCacheManager()); sessionManager.getSessionIdCookie().setName("vcoocUserId"); return sessionManager; } @Bean public DefaultWebSecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setSessionManager(sessionManager()); securityManager.setCacheManager(redisCacheManager()); return securityManager; } @Bean public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() { AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor(); aasa.setSecurityManager(securityManager()); return new AuthorizationAttributeSourceAdvisor(); } @Bean public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator(); daap.setProxyTargetClass(true); return daap; } @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean() { Map<String, String> filterChainDefinitionMap = new HashMap<>(); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager()); //<!-- authc:全部url都必須認證經過才能夠訪問; anon:全部url都均可以匿名訪問--> //放行靜態資源 filterChainDefinitionMap.put("/static/**", "anon"); shiroFilterFactoryBean.setLoginUrl("/toLogin"); shiroFilterFactoryBean.setSuccessUrl("/index"); filterChainDefinitionMap.put("/**", "anon"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } }
配置redis 的property:緩存
redis:
host: 127.0.0.1
port: 6379session
以上轉自另一個帖子,原帖我直接複製不可用,稍做修改,能夠運行了,上面是我修改後的。ide