前面缓存用的Ehcache,需要自己实现redis缓存
根据shiro提供的Ehcache实现shiro缓存的方式,只需要实现 Cache接口和CacheManager接口就行,先上Ehcache的bean文件
<!-- 缓存管理器 -->
<!--<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
</bean>-->
然后注入到SecurityManager
<!-- securityManager安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--自定义用户信息获取器-->
<property name="realm" ref="userRealm" />
<!--session管理器-->
<property name="sessionManager" ref="sessionManager"/>
<!-- 注入缓存管理器 -->
<property name="cacheManager" ref="cacheManager"/>
</bean>
通过ehcache的源码看到实现了cacheManager接口
并且只返回一个Cache就行
所以目的很明确:按着shiro的要求实现这个两个接口
org.apache.shiro.cache.CacheManager
org.apache.shiro.cache.Cache
spring整合看这篇:
整合好后,我们实现这两个接口
CacheManager
/**
* @author yanghs
* @Description:
* @date 2018/3/21 11:50
*/
public class RedisShiroManager implements CacheManager {
private RedisDao redisDao;
public <K, V> Cache<K, V> getCache(String s) throws CacheException {
return new RedisShiroCache(s,redisDao);
}
public RedisDao getRedisDao() {
return redisDao;
}
public void setRedisDao(RedisDao redisDao) {
this.redisDao = redisDao;
}
}
Cache
/**
* @author yanghs
* @Description:实现shiro提供的缓存
* @date 2018/3/21 11:47
*/
public class RedisShiroCache implements Cache {
private RedisDao redisDao;
private String name;
public RedisShiroCache(String name,RedisDao redisDao) {
this.redisDao = redisDao;
this.name = name;
}
public Object get(Object o) throws CacheException {
try {
SimplePrincipalCollection principalCollection = (SimplePrincipalCollection)o;
Userinfo userinfo = (Userinfo) principalCollection.getPrimaryPrincipal();
/*key采用缓存名字加用户id+用户名防止冲突,我这里是简单实现后面还有修改的*/
String key =name+":"+ userinfo.getUserid()+userinfo.getUsername();
byte[] b = redisDao.getValueByKey(key.getBytes());
return SerializeUtil.deserialize(b);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public Object put(Object o, Object o2) throws CacheException {
SimplePrincipalCollection principalCollection = (SimplePrincipalCollection)o;
Userinfo userinfo = (Userinfo) principalCollection.getPrimaryPrincipal();
byte[] key = (name+":"+userinfo.getUserid()+userinfo.getUsername()).getBytes();
byte[] value = SerializeUtil.serialize(o2);
try {
redisDao.saveValueByKey(key,value,-1);
} catch (Exception e) {
e.printStackTrace();
}
return get(o);
}
public Object remove(Object o) throws CacheException {
SimplePrincipalCollection principalCollection = (SimplePrincipalCollection)o;
Userinfo userinfo = (Userinfo) principalCollection.getPrimaryPrincipal();
byte[] key = (name+":"+userinfo.getUserid()+userinfo.getUsername()).getBytes();
try {
redisDao.deleteByKey(key);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void clear() throws CacheException {
}
public int size() {
return 0;
}
public Set keys() {
return null;
}
public Collection values() {
return null;
}
/**
* @author yanghs
* @Description:针对redis存储对象序列化
* @date 2018年3月21日17:29:19
*/
public class SerializeUtil {
public static byte[] serialize(Object value) {
if (value == null) {
throw new NullPointerException("Can't serialize null");
}
byte[] rv = null;
ByteArrayOutputStream bos = null;
ObjectOutputStream os = null;
try {
bos = new ByteArrayOutputStream();
os = new ObjectOutputStream(bos);
os.writeObject(value);
os.close();
bos.close();
rv = bos.toByteArray();
} catch (Exception e) {
} finally {
close(os);
close(bos);
}
return rv;
}
public static Object deserialize(byte[] in) {
return deserialize(in, Object.class);
}
public static <T> T deserialize(byte[] in, Class<T>...requiredType) {
Object rv = null;
ByteArrayInputStream bis = null;
ObjectInputStream is = null;
try {
if (in != null) {
bis = new ByteArrayInputStream(in);
is = new ObjectInputStream(bis);
rv = is.readObject();
}
} catch (Exception e) {
} finally {
close(is);
close(bis);
}
return (T) rv;
}
private static void close(Closeable closeable) {
if (closeable != null)
try {
closeable.close();
} catch (IOException e) {
}
}
}
这样就简单实现了缓存使用redis。测试成功