灼眼de涙
2016-11-28 02:10
采纳率: 100%
浏览 7.8k

shiro-redis集成时,权限的缓存清空存在一个bug

用的这个jar包: org.crazycake.shiro

@Override
public void clearAllCachedAuthorizationInfo() {
Cache cache = getAuthorizationCache();
if (cache != null) {
for (Object key : cache.keys()) {
cache.remove(key);
}
}
}
清空所有的权限缓存时 调用这个方法的时候,会调用 redis的 keys的方法 如下
public Set keys() {
try {
Set keys = cache.keys(this.keyPrefix + "*");
if (CollectionUtils.isEmpty(keys)) {
return Collections.emptySet();
}else{
Set newKeys = new HashSet();
for(byte[] key:keys){
newKeys.add((K)key);
}
return newKeys;
}
} catch (Throwable t) {
throw new CacheException(t);
}
}

    private byte[] getByteKey(K key){
    if(key instanceof String){
        String preKey = this.keyPrefix + key;
        return preKey.getBytes();
    }else{
        return SerializeUtils.serialize(key);
    }
}

@Override
public V get(K key) throws CacheException {
    logger.debug("根据key从Redis中获取对象 key [" + key + "]");
    try {
        if (key == null) {
            return null;
        }else{
            byte[] rawValue = cache.get(getByteKey(key));
            @SuppressWarnings("unchecked")
            V value = (V)SerializeUtils.deserialize(rawValue);
            return value;
        }
    } catch (Throwable t) {
        throw new CacheException(t);
    }

}
因   权限缓存时 用的是 PrincipalCollection 这个对象当作的key
所以会调用 SerializeUtils.serialize(key); 这个方法  如下:
public static byte[] serialize(Object object) {

    byte[] result = null;

    if (object == null) {
        return new byte[0];
    }
    try {
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128);
        try  {
            if (!(object instanceof Serializable)) {
                throw new IllegalArgumentException(SerializeUtils.class.getSimpleName() + " requires a Serializable payload " +
                        "but received an object of type [" + object.getClass().getName() + "]");
            }
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream);
            objectOutputStream.writeObject(object);
            objectOutputStream.flush();
            result =  byteStream.toByteArray();
        }
        catch (Throwable ex) {
            throw new Exception("Failed to serialize", ex);
        }
    } catch (Exception ex) {
        logger.error("Failed to serialize",ex);
    }
    return result;
}

这样是把 权限缓存到redis之中了,但是取的时候确是有问题的
最开始说的keys 方法之中 
cache.keys(this.keyPrefix + "*");
取时 用了 this.keyPrefix+“*” 来取  而这个前缀 在存的时候根本没有当作key的前缀,所以根本取不出来

有没有大神 指点一波 
难道只有改源码了么?
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • 灼眼de涙 2016-11-28 09:55
    已采纳
    已采纳该答案
    打赏 评论
  • 西北码农 2017-06-26 07:51

    怎么解决的,你的连接看不了了

    打赏 评论

相关推荐 更多相似问题