Shiro集群实现

本文详细介绍如何使用Redis实现Apache Shiro的会话管理和缓存功能。通过具体配置示例和源码分析,展示了如何设置Redis连接、选择序列化方式,并实现会话DAO及缓存管理器的具体操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

apache shiro集群实现(一) session共享 [url]http://blog.youkuaiyun.com/michaelliuyang/article/details/8819852[/url]
apache shiro集群实现(二)— cache共享 [url]http://blog.youkuaiyun.com/michaelliuyang/article/details/8820390[/url]
Redis整合Spring结合使用缓存实例 [url]http://blog.youkuaiyun.com/evankaka/article/details/50396325[/url]


原文的修改: 很多人留言希望提供基础代码, 但原文的作者不愿意提供基础代码, 让人很纳闷, 所以自己找了很久, 决定替换和修改原文的代码
[b][color=red]针对redis的session共享的配置或者源码[/color][/b]
<bean id="jdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"></bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="192.168.0.198"/>
<property name="port" value="6379"/>
<property name="password" value="12345"/>
<property name="timeout" value="1000"/>
<property name="poolConfig" ref="jedisPoolConfig"/>
<property name="usePool" value="true"/>
</bean>
<!--
GenericToStringSerializer: 可以将任何对象泛化为字符串并序列化
Jackson2JsonRedisSerializer: 跟JacksonJsonRedisSerializer实际上是一样的
JacksonJsonRedisSerializer: 序列化object对象为json字符串
JdkSerializationRedisSerializer: 序列化java对象
StringRedisSerializer: 简单的字符串序列化
-->
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<property name="defaultSerializer" ref="jdkSerializationRedisSerializer" />
<property name="keySerializer" ref="stringRedisSerializer"/>
<property name="hashKeySerializer" ref="stringRedisSerializer"/>
<property name="valueSerializer" ref="jdkSerializationRedisSerializer"/>
<property name="hashValueSerializer" ref="jdkSerializationRedisSerializer"/>
</bean>
<bean id="redisUtil" class="com.pandy.framework.base.redis.utils.RedisUtil">
<property name="redisTemplate" ref="redisTemplate"/>
</bean>



package com.pandy.framework.base.shiro.session.dao.impl;

import com.pandy.framework.base.redis.utils.RedisUtil;
import com.pandy.framework.base.shiro.session.dao.ShiroSessionRepository;
import org.apache.shiro.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
* Created by pandy on 16-5-3.
*/
public class JedisShiroSessionRepository implements ShiroSessionRepository {
private Logger logger = LoggerFactory.getLogger(JedisShiroSessionRepository.class);
private RedisUtil redisUtil;

/**
* redis session key前缀
*/
private final String REDIS_SHIRO_SESSION = "PANDY-WP-FRAMEWORK-SESSION";
private String redisShiroSessionPre;

public void saveSession(Session session) {
if (session == null || session.getId() == null) {
logger.error("session或者session id为空");
return;
}
redisUtil.set(getRedisSessionKey(session.getId()), session);

}

public void deleteSession(Serializable id) {
if (id == null) {
logger.error("id为空");
return;
}
redisUtil.remove(getRedisSessionKey(id));
}

public Session getSession(Serializable id) {
if (id == null) {
logger.error("id为空");
return null;
}
Session session = redisUtil.get(getRedisSessionKey(id), Session.class);
return session;
}

public Collection<Session> getAllSessions() {
Set<Session> sessions = new HashSet<Session>();
Set<String> set = redisUtil.getPatternKey("*");

if (set == null || set.size() == 0)
return sessions;
Iterator<String> it = set.iterator();
while (it.hasNext()) {
try {
String key = it.next();
if(key!=null && key.indexOf(REDIS_SHIRO_SESSION)>=0){
Session session = redisUtil.get(key, Session.class);
sessions.add(session);
}

}catch (Exception e){
e.printStackTrace();
}
}

return sessions;
}

/**
* 获取redis中的session key
*
* @param sessionId
* @return
*/
private String getRedisSessionKey(Serializable sessionId) {
return getRedisShiroSessionPre() + sessionId;
}


public RedisUtil getRedisUtil() {
return redisUtil;
}

public void setRedisUtil(RedisUtil redisUtil) {
this.redisUtil = redisUtil;
}

public String getRedisShiroSessionPre() {
if (redisShiroSessionPre == null || redisShiroSessionPre.trim().length() == 0) {
return REDIS_SHIRO_SESSION + ":";
}
return REDIS_SHIRO_SESSION + "-" + redisShiroSessionPre + ":";
}

public void setRedisShiroSessionPre(String redisShiroSessionPre) {
this.redisShiroSessionPre = redisShiroSessionPre;
}
}



<!-- 使用redis处理会话DAO -->
<bean id="jedisShiroSessionRepository" class="com.pandy.framework.base.shiro.session.dao.impl.JedisShiroSessionRepository">
<property name="redisUtil" ref="redisUtil"/>
<property name="redisShiroSessionPre" value="PANDY_WEB_APP_SESSION"/>
</bean>
<bean id="sessionDAO" class="com.pandy.framework.base.shiro.session.dao.impl.CustomShiroSessionDAO">
<property name="shiroSessionRepository" ref="jedisShiroSessionRepository" />
<property name="sessionIdGenerator" ref="sessionIdGenerator"/>
</bean>



针对redis的cache的配置或源码
package com.pandy.framework.base.shiro.cache;

import com.pandy.framework.base.redis.utils.RedisUtil;
import org.apache.shiro.cache.Cache;

/**
* Created by pandy on 16-5-4.
*/
public class JedisShiroCacheManager implements ShiroCacheManager {
private RedisUtil redisUtil;
private String redisShiroCachePre;


public <K, V> Cache<K, V> getCache(String name) {
return new JedisShiroCache<K, V>(name, redisUtil, getRedisShiroCachePre());
}

public void destroy() {
//jedisCacheManager.getJedis().shutdown();
throw new RuntimeException("这里要怎么实现啊,还不知道怎么实现");
}

public RedisUtil getRedisUtil() {
return redisUtil;
}

public void setRedisUtil(RedisUtil redisUtil) {
this.redisUtil = redisUtil;
}

public String getRedisShiroCachePre() {
return redisShiroCachePre;
}

public void setRedisShiroCachePre(String redisShiroCachePre) {
this.redisShiroCachePre = redisShiroCachePre;
}
}



package com.pandy.framework.base.shiro.cache;

import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.util.Destroyable;

/**
* Created by pandy on 16-5-4.
*/
public class CustomShiroCacheManager implements CacheManager, Destroyable {

private ShiroCacheManager shiroCacheManager;

public ShiroCacheManager getShiroCacheManager() {
return shiroCacheManager;
}

public void setShiroCacheManager(ShiroCacheManager shiroCacheManager) {
this.shiroCacheManager = shiroCacheManager;
}

public <K, V> Cache<K, V> getCache(String name) throws CacheException {
return getShiroCacheManager().getCache(name);
}

public void destroy() throws Exception {
shiroCacheManager.destroy();
}

}



package com.pandy.framework.base.shiro.cache;

import com.pandy.framework.base.redis.utils.RedisUtil;
import com.pandy.framework.base.utils.SerializeUtil;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;

import java.util.*;

/**
* Created by pandy on 16-5-4.
*/
public class JedisShiroCache<K, V> implements Cache<K, V> {
private RedisUtil redisUtil;
private final String REDIS_SHIRO_CACHE = "PANDY-WP-FRAMEWORK-CACHE";
private String redisShiroCachePre;
private String name;

public JedisShiroCache(String name, RedisUtil redisUtil, String redisShiroCachePre) {
this.name = name;
this.redisUtil = redisUtil;
this.redisShiroCachePre = redisShiroCachePre;
}

/**
* 自定义relm中的授权/认证的类名加上授权/认证英文名字
*
* @return
*/
public String getName() {
if (name == null)
return "";
return name;
}

public void setName(String name) {
this.name = name;
}

public V get(K key) throws CacheException {
byte[] byteKey = SerializeUtil.serialize(getCacheKey(key));
//byte[] byteValue = redisUtil.get(getCacheKey(key));
Object byteValue = redisUtil.get(getCacheKey(key));
return (V) byteValue;
}

public V put(K key, V value) throws CacheException {
V previos = get(key);
redisUtil.set(getCacheKey(key), value);
return previos;
}

public V remove(K key) throws CacheException {
V previos = get(key);
redisUtil.remove(getCacheKey(key));
return previos;
}

public void clear() throws CacheException {
byte[] keysPattern = SerializeUtil.serialize(this.REDIS_SHIRO_CACHE + "*");
redisUtil.removePattern(getCacheKey(keysPattern));
}

public int size() {
if (keys() == null)
return 0;
return keys().size();
}

public Set<K> keys() {
Set<K> set = (Set<K>) redisUtil.getPatternKey("*");
return set;
}

public Collection<V> values() {
List<V> result = new LinkedList<V>();
return result;
}

private String getCacheKey(Object key) {
if (redisShiroCachePre == null || redisShiroCachePre.trim().length() == 0)
return this.REDIS_SHIRO_CACHE + getName() + ":" + key;
else
return this.REDIS_SHIRO_CACHE + "-" + redisShiroCachePre + getName() + ":" + key;
}
}



<!-- 使用redis缓存管理器 -->
<bean id="jedisShiroCacheManager" class="com.pandy.framework.base.shiro.cache.JedisShiroCacheManager">
<property name="redisUtil" ref="redisUtil" />
<property name="redisShiroCachePre" value="PANDY_WEB_APP_CACHE"/>
</bean>
<bean id="cacheManagerWrapper" class="com.pandy.framework.base.shiro.cache.CustomShiroCacheManager">
<property name="shiroCacheManager" ref="jedisShiroCacheManager" />
</bean>


RedisUtil.java参考: [url]http://panyongzheng.iteye.com/blog/2295435[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值