程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程解疑 >> redis+shiro-shiro-redis集成時,權限的緩存清空存在一個bug

redis+shiro-shiro-redis集成時,權限的緩存清空存在一個bug

編輯:編程解疑
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的前綴,所以根本取不出來

有沒有大神 指點一波 
難道只有改源碼了麼?

最佳回答:


自己已經解決 詳情請看 http://blog.csdn.net/u011267231/article/details/53377992

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved