2018年03月14日 16:22:50
阅读数:16
转载地址:https://blog.csdn.net/yr_xiaozheng/article/details/79556137
参考资料:http://blog.csdn.net/lishehe/article/details/45223823
写的非常棒,只是缺少了几个工具类,我在这里给出了自己的代码,方便用到。
- redis.properties
[java] view plain
copy
- redis.host=
127.0
.
0.1
- redis.port=
6379
- redis.
default
.db=
2
- redis.timeout=
100000
- redis.maxIdle=
100
- redis.maxWaitMillis=
30000
- redis.testOnBorrow=
true
2. applicationContext-shiro.xml
[html] view plain
copy
-
<?
xml
version
"1.0"
encoding
"UTF-8"
?>
- <
beans
xmlns
"http://www.springframework.org/schema/beans"
xmlns:xsi
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
<
bean
id
"securityManager"
class
"org.apache.shiro.web.mgt.DefaultWebSecurityManager"
<!–配置 session 管理–>
<
property
name
"sessionManager"
ref
"sessionManager"
/>
<!–配置 记住我–>
<
property
name
"rememberMeManager"
ref
"rememberMeManager"
/>
<!– 配置多个Realm的登录认证 –>
<
property
name
"authenticator"
ref
"authenticator"
/>
<!– 配置多个Realm的权限认证 –>
<
property
name
"authorizer"
ref
"authorizer"
/>
<!– redis缓存 –>
<
property
name
"cacheManager"
ref
"redisCacheManager"
/>
</
bean
<!–配置多个 realm 的权限权限认证–>
<
bean
id
"authorizer"
class
"org.apache.shiro.authz.ModularRealmAuthorizer"
<
property
name
"realms"
<
list
<!–这个实现权限匹配的方法–>
<
ref
bean
"myRealm"
/>
</
list
</
property
</
bean
<!– 配置多个Realm –>
<
bean
id
"authenticator"
class
"org.apache.shiro.authc.pam.ModularRealmAuthenticator"
<!–验证的时候,是用迭代器,所以可以认为验证的顺序就是这个 list 的顺序–>
<
property
name
"realms"
<
list
<!–<ref bean="otherRealm"/>–>
<
ref
bean
"myRealm"
/>
</
list
</
property
<
property
name
"authenticationStrategy"
<!–所有 realm 认证通过才算登录成功–>
<!–<bean id="authenticationStrategy" class="org.apache.shiro.authc.pam.AllSuccessfulStrategy"/>–>
<!–验证某个 realm 成功后直接返回,不会验证后面的 realm 了–>
<
bean
id
"authenticationStrategy"
class
"org.apache.shiro.authc.pam.FirstSuccessfulStrategy"
/>
<!–所有的 realm 都会验证,其中一个成功,也会继续验证后面的 realm,最后返回成功–>
<!–<bean id="authenticationStrategy" class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"/>–>
</
property
</
bean
<!–自定义 MyRealm,登录的认证入口 ,需要继承AuthorizingRealm,项目中会体现–>
<
bean
id
"myRealm"
class
"com.tms.shiro.MyRealm"
<!– 配置密码匹配器 –>
<
property
name
"credentialsMatcher"
<
bean
class
"org.apache.shiro.authc.credential.HashedCredentialsMatcher"
<!– 加密算法为SHA-256 –>
<
property
name
"hashAlgorithmName"
value
"SHA-256"
/>
<!– 加密迭代次数 –>
<
property
name
"hashIterations"
value
"1024"
/>
<!–是否存储散列后的密码为16进制,为 true:.toHex(),为 false:.toBase64()–>
<
property
name
"storedCredentialsHexEncoded"
value
"false"
/>
</
bean
</
property
</
bean
<!–rememberMeManager管理 配置–>
<
bean
id
"rememberMeManager"
class
"org.apache.shiro.web.mgt.CookieRememberMeManager"
<
property
name
"cookie"
<
bean
class
"org.apache.shiro.web.servlet.SimpleCookie"
<!–设置超时时间 单位 秒,一天=86400–>
<
constructor-arg
value
"shiro-cookie"
/>
<
property
name
"maxAge"
value
"86400"
/>
<
property
name
"httpOnly"
value
"true"
/>
</
bean
</
property
</
bean
<!–session管理 配置–>
<!–<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">–>
- <!–
<
bean
id
"sessionManager"
class
"com.tms.shiro.SessionManager"
- <!–session 过期时间 单位 毫秒,
2400000
40min
–
<
property
name
"globalSessionTimeout"
value
"2400000"
/>
- <!–有需要可以自行配置–
- <!–
<
property
name
"cacheManager"
ref
"xxxx"
</
property
–
- <!–有需要可以自行配置–
- <!–
<
property
name
"sessionDAO"
ref
"xxx"
</
property
–
<
property
name
"sessionIdCookie"
ref
"sessionIdCookie"
/>
</
bean
—
<!– 自定义sessionId 防止同tomcat 等容器冲突 –>
<
bean
id
"sessionIdCookie"
class
"org.apache.shiro.web.servlet.SimpleCookie"
<
constructor-arg
value
"token"
/>
<
property
name
"maxAge"
value
"86400"
/>
<
property
name
"path"
value
"/"
/>
</
bean
<!–shiro 请求拦截器,这里的 bean id 一定要对应 web.xml 中的filter-name,否则找不到这个拦截器–>
<
bean
id
"shiroFilter"
class
"com.tms.shiro.MyShiroFilterFactoryBean"
<
property
name
"securityManager"
ref
"securityManager"
/>
<!–登录地址–>
<
property
name
"loginUrl"
value
"login"
/>
<!–登录成功跳转的地址–>
<
property
name
"successUrl"
value
"/userAction_findList"
/>
<!–权限认证失败跳转的地址–>
<
property
name
"unauthorizedUrl"
value
"error"
/>
<!–需要权限拦截的路径–>
<
property
name
"filterChainDefinitions"
<
value
<!–/login = anon–>
<!–/validateCode = anon–>
<!–/\*\* = authc–>
</
value
</
property
</
bean
<!– 保证实现了Shiro内部lifecycle函数的bean执行 ,不明觉厉,没有深究–>
<
bean
id
"lifecycleBeanPostProcessor"
class
"org.apache.shiro.spring.LifecycleBeanPostProcessor"
/>
<!– 自定义redisManager-redis –>
<
bean
id
"redisCacheManager"
class
"com.tms.util.redis.RedisCacheManager"
<
property
name
"redisManager"
ref
"redisManager"
/>
</
bean
<!– 自定义cacheManager –>
<
bean
id
"redisCache"
class
"com.tms.util.redis.RedisCache"
<
constructor-arg
ref
"redisManager"
</
constructor-arg
</
bean
<
bean
id
"redisManager"
class
"com.tms.util.redis.RedisManager"
</
bean
<!– session会话存储的实现类 –>
<
bean
id
"redisShiroSessionDAO"
class
"com.tms.util.redis.RedisSessionDao"
<
property
name
"redisManager"
ref
"redisManager"
/>
</
bean
<!– session管理器 –>
<
bean
id
"sessionManager"
class
"com.tms.shiro.SessionManager"
<!– 设置全局会话超时时间,默认30分钟(1800000) –>
<
property
name
"globalSessionTimeout"
value
"1800000"
/>
<!– 是否在会话过期后会调用SessionDAO的delete方法删除会话 默认true –>
<
property
name
"deleteInvalidSessions"
value
"true"
/>
<!– 会话验证器调度时间 –>
<
property
name
"sessionValidationInterval"
value
"1800000"
/>
<!– session存储的实现 –>
<
property
name
"sessionDAO"
ref
"redisShiroSessionDAO"
/>
<!– sessionIdCookie的实现,用于重写覆盖容器默认的JSESSIONID –>
<
property
name
"sessionIdCookie"
ref
"sharesession"
/>
<!– 定时检查失效的session –>
<
property
name
"sessionValidationSchedulerEnabled"
value
"true"
/>
</
bean
<!– sessionIdCookie的实现,用于重写覆盖容器默认的JSESSIONID –>
<
bean
id
"sharesession"
class
"org.apache.shiro.web.servlet.SimpleCookie"
<!– cookie的name,对应的默认是 JSESSIONID –>
<
constructor-arg
name
"name"
value
"SHAREJSESSIONID"
/>
<!– jsessionId的path为 / 用于多个系统共享jsessionId –>
<
property
name
"path"
value
"/"
/>
<
property
name
"httpOnly"
value
"true"
/>
</
bean
<!– shiro的自带缓存管理器encahe –>
<!– <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> –>
- <!–
<
property
name
"cacheManagerConfigFile"
value
"classpath:config/ehcache-shiro.xml"
/>
—
<!– </bean> –>
<!– 开启shiro的注解,需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证 –>
<
bean
class
"org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on
"lifecycleBeanPostProcessor"
</
bean
<
bean
class
"org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"
<
property
name
"securityManager"
ref
"securityManager"
/>
</
bean
- </
beans
- redis.xml
[html] view plain
copy
-
<?
xml
version
"1.0"
encoding
"UTF-8"
?>
- <
beans
xmlns
"http://www.springframework.org/schema/beans"
xmlns:xsi
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:c
"http://www.springframework.org/schema/c"
xmlns:cache
"http://www.springframework.org/schema/cache"
xmlns:context
"http://www.springframework.org/schema/context"
xsi:schemaLocation
="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
<!– 加载Reids属性配置文件 ignore-unresolvable="true"–>
<
context:property-placeholder
location
"classpath:redis.properties"
/>
<
bean
id
"propertyConfigurerRedis"
class
"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
<
property
name
"order"
value
"1"
/>
<
property
name
"ignoreUnresolvablePlaceholders"
value
"true"
/>
<
property
name
"systemPropertiesMode"
value
"1"
/>
<
property
name
"searchSystemEnvironment"
value
"true"
/>
<
property
name
"locations"
<
list
<
value
classpath:redis.properties
</
value
</
list
</
property
</
bean
<!–支持缓存注释, 使用key生成器–>
<
bean
id
"redisCacheKeyGenerator"
class
"com.tms.util.redis.CustomRedisCacheKeyGenerator"
/>
<
cache:annotation-driven
key-generator
"redisCacheKeyGenerator"
/>
<!– 配置redis池,最大空闲实例数,(创建实例时)最大等待时间,(创建实例时)是否验证 –>
<
bean
id
"jedisPoolConfig"
class
"redis.clients.jedis.JedisPoolConfig"
<
property
name
"maxIdle"
value
"${redis.maxIdle}"
/>
<
property
name
"testOnBorrow"
value
"${redis.testOnBorrow}"
/>
<
property
name
"maxWaitMillis"
value
"${redis.maxWaitMillis}"
/>
<
property
name
"minEvictableIdleTimeMillis"
value
"300000"
/>
<
property
name
"numTestsPerEvictionRun"
value
"3"
/>
<
property
name
"timeBetweenEvictionRunsMillis"
value
"6000"
/>
</
bean
<
bean
id
"jedisConnectionFactory"
class
"org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
<
property
name
"usePool"
value
"true"
</
property
<
property
name
"hostName"
value
"${redis.host}"
/>
<
property
name
"port"
value
"${redis.port}"
/>
<
property
name
"timeout"
value
"${redis.timeout}"
/>
<
property
name
"database"
value
"${redis.default.db}"
</
property
<
property
name
"poolConfig"
ref
"jedisPoolConfig"
</
property
</
bean
<
bean
id
"jedisTemplate"
class
"org.springframework.data.redis.core.RedisTemplate"
<
property
name
"connectionFactory"
ref
"jedisConnectionFactory"
</
property
<
property
name
"keySerializer"
<
bean
class
"org.springframework.data.redis.serializer.StringRedisSerializer"
/>
</
property
<
property
name
"valueSerializer"
<
bean
class
"org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"
/>
</
property
</
bean
<!–V2 配置cacheManager, 使用默认的 用户自定义的 RedisCacheManager –>
<
bean
id
"cacheManager"
class
"com.tms.util.redis.CustomizedRedisCacheManager"
<
constructor-arg
ref
"jedisTemplate"
/>
<!–使用前缀,使用以后,以cache的value作为redis中的namespace,缓存的键也会加入这个前缀–>
<
property
name
"usePrefix"
value
"true"
/>
<!– 前缀命名,仅当usePrefix为true时才生效,本例子不使用 –>
<!–<property name="cachePrefix">–>
<!–<bean class="org.springframework.data.redis.cache.DefaultRedisCachePrefix">–>
<!–<constructor-arg name="delimiter" value=":"/>–>
<!–</bean>–>
<!–</property>–>
<!– 默认有效期1h ,本例子不使用–>
<!–<property name="defaultExpiration" value="3600"/>–>
</
bean
- </
beans
- SerializerUtil.java
[java] view plain
copy
- import
org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
- /**
- * @Author:
- * @Date: 2018-03-13 12:33
- * @Modified By:
- * @Description:
- */
- public
class
SerializerUtil {
private
static
final
JdkSerializationRedisSerializer jdkSerializationRedisSerializer =
new
JdkSerializationRedisSerializer();
/**
- * 序列化对象
- * @param obj
- * @return
- */
public
static
<T>
byte
[] serialize(T obj){
try
{
return
jdkSerializationRedisSerializer.serialize(obj);
- }
catch
(Exception e) {
throw
new
RuntimeException(
"序列化失败!"
, e);
- }
- }
/**
- * 反序列化对象
- * @param bytes 字节数组
- * @param
- * @return
- */
@SuppressWarnings
(
"unchecked"
)
public
static
<T> T deserialize(
byte
[] bytes){
try
{
return
(T) jdkSerializationRedisSerializer.deserialize(bytes);
- }
catch
(Exception e) {
throw
new
RuntimeException(
"反序列化失败!"
, e);
-
}
-
}
-
-
}
-
RedisSessionDao.java
[java] view plain
copy
- import
org.apache.shiro.session.Session;
- import
org.apache.shiro.session.UnknownSessionException;
- import
org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
- import
org.slf4j.Logger;
- import
org.slf4j.LoggerFactory;
- import
java.io.Serializable;
- import
java.util.Collection;
- import
java.util.HashSet;
- import
java.util.Set;
- /**
- * @Author:
- * @Date: 2018-03-13 12:35
- * @Modified By:
- * @Description:
- */
- public
class
RedisSessionDao
extends
AbstractSessionDAO {
private
Logger logger = LoggerFactory.getLogger(
this
.getClass());
private
RedisManager redisManager;
/**
- * The Redis key prefix for the sessions
- */
private
static
final
String KEY_PREFIX =
"shiro_redis_session:"
;
private
byte
[] getByteKey(String key){
return
key.getBytes();
- }
@Override
public
void
update(Session session)
throws
UnknownSessionException {
this
.saveSession(session);
- }
@Override
public
void
delete(Session session) {
if
(session ==
null
|| session.getId() ==
null
) {
- logger.error(
"session or session id is null"
);
return
;
- }
- redisManager.del(getByteKey(KEY_PREFIX + session.getId()));
- }
@Override
public
Collection<Session> getActiveSessions() {
- Set<Session> sessions =
new
HashSet<Session>();
- Set<
byte
[]> keys = redisManager.keys(KEY_PREFIX +
"*"
);
if
(keys !=
null
&& keys.size()>
0
){
for
(
byte
[] key : keys){
- Session s = (Session) SerializerUtil.deserialize(redisManager.get(SerializerUtil.deserialize(key)));
- sessions.add(s);
- }
- }
return
sessions;
- }
@Override
protected
Serializable doCreate(Session session) {
- Serializable sessionId =
this
.generateSessionId(session);
this
.assignSessionId(session, sessionId);
this
.saveSession(session);
return
sessionId;
- }
@Override
protected
Session doReadSession(Serializable sessionId) {
if
(sessionId ==
null
){
- logger.error(
"session id is null"
);
return
null
;
- }
- Session s = (Session)redisManager.get(getByteKey(KEY_PREFIX + sessionId));
return
s;
- }
private
void
saveSession(Session session)
throws
UnknownSessionException{
if
(session ==
null
|| session.getId() ==
null
) {
- logger.error(
"session or session id is null"
);
return
;
- }
//设置过期时间
long
expireTime = 1800000l;
- session.setTimeout(expireTime);
- redisManager.setEx(KEY_PREFIX + session.getId(), session, expireTime);
- }
public
void
setRedisManager(RedisManager redisManager) {
this
.redisManager = redisManager;
- }
public
RedisManager getRedisManager() {
return
redisManager;
-
}
-
-
}
-
RedisManager.java
[java] view plain
copy
- import
org.apache.commons.lang3.StringUtils;
- import
org.apache.shiro.dao.DataAccessException;
- import
org.springframework.beans.factory.annotation.Autowired;
- import
org.springframework.data.redis.connection.RedisConnection;
- import
org.springframework.data.redis.core.RedisCallback;
- import
org.springframework.data.redis.core.RedisTemplate;
- import
java.io.Serializable;
- import
java.util.Set;
- /**
- * @Author:
- * @Date: 2018-03-13 12:30
- * @Modified By:
- * @Description:
- */
- public
class
RedisManager {
@Autowired
private
RedisTemplate<Serializable, Serializable> redisTemplate;
/**
- * 过期时间
- */
/**
- * 添加缓存数据(给定key已存在,进行覆盖)
- * @param key
- * @param obj
- * @throws DataAccessException
- */
public
<T>
void
set(
byte
[] key, T obj)
throws
DataAccessException{
final
byte
[] bkey = key;
final
byte
[] bvalue = SerializerUtil.serialize(obj);
- redisTemplate.execute(
new
RedisCallback<Void>() {
@Override
public
Void doInRedis(RedisConnection connection)
throws
DataAccessException {
- connection.set(bkey, bvalue);
return
null
;
- }
- });
- }
/**
- * 添加缓存数据(给定key已存在,不进行覆盖,直接返回false)
- * @param key
- * @param obj
- * @return 操作成功返回true,否则返回false
- * @throws DataAccessException
- */
public
<T>
boolean
setNX(String key, T obj)
throws
DataAccessException{
final
byte
[] bkey = key.getBytes();
final
byte
[] bvalue = SerializerUtil.serialize(obj);
boolean
result = redisTemplate.execute(
new
RedisCallback<Boolean>() {
@Override
public
Boolean doInRedis(RedisConnection connection)
throws
DataAccessException {
return
connection.setNX(bkey, bvalue);
- }
- });
return
result;
- }
/**
- * 添加缓存数据,设定缓存失效时间
- * @param key
- * @param obj
- * @param expireSeconds 过期时间,单位 秒
- * @throws DataAccessException
- */
public
<T>
void
setEx(String key, T obj,
final
long
expireSeconds)
throws
DataAccessException{
final
byte
[] bkey = key.getBytes();
final
byte
[] bvalue = SerializerUtil.serialize(obj);
- redisTemplate.execute(
new
RedisCallback<Boolean>() {
@Override
public
Boolean doInRedis(RedisConnection connection)
throws
DataAccessException {
- connection.setEx(bkey, expireSeconds, bvalue);
return
true
;
- }
- });
- }
/**
- * 获取key对应value
- * @param key
- * @return
- * @throws DataAccessException
- */
public
<T> T get(
final
byte
[] key)
throws
DataAccessException{
byte
[] result = redisTemplate.execute(
new
RedisCallback<
byte
[]>() {
@Override
public
byte
[] doInRedis(RedisConnection connection)
throws
DataAccessException {
return
connection.get(key);
- }
- });
if
(result ==
null
) {
return
null
;
- }
return
SerializerUtil.deserialize(result);
- }
/**
- * 删除指定key数据
- * @param key
- * @return 返回操作影响记录数
- */
public
Long del(
final
byte
[] key){
if
(key.length ==
0
) {
return
0l;
- }
- Long delNum = redisTemplate.execute(
new
RedisCallback<Long>() {
@Override
public
Long doInRedis(RedisConnection connection)
throws
DataAccessException {
byte
[] keys = key;
return
connection.del(keys);
- }
- });
return
delNum;
- }
public
Set<
byte
[]> keys(
final
String key){
if
(StringUtils.isEmpty(key)) {
return
null
;
- }
- Set<
byte
[]> bytesSet = redisTemplate.execute(
new
RedisCallback<Set<
byte
[]>>() {
@Override
public
Set<
byte
[]> doInRedis(RedisConnection connection)
throws
DataAccessException {
byte
[] keys = key.getBytes();
return
connection.keys(keys);
- }
- });
return
bytesSet;
- }
/**
- * dbSize
- */
public
Long dbSize(){
- Long delNum = redisTemplate.execute(
new
RedisCallback<Long>() {
@Override
public
Long doInRedis(RedisConnection connection)
throws
DataAccessException {
return
connection.dbSize();
- }
- });
return
delNum;
- }
/**
- * flushDB
- */
public
void
flushDB()
throws
DataAccessException{
- redisTemplate.execute(
new
RedisCallback<Void>() {
@Override
public
Void doInRedis(RedisConnection connection)
throws
DataAccessException {
- connection.flushDb();
return
null
;
-
}
-
});
-
}}
-
RedisCacheManager.java
[java] view plain
copy
- import
org.apache.shiro.cache.Cache;
- import
org.apache.shiro.cache.CacheException;
- import
org.apache.shiro.cache.CacheManager;
- import
org.slf4j.Logger;
- import
org.slf4j.LoggerFactory;
- import
java.util.concurrent.ConcurrentHashMap;
- import
java.util.concurrent.ConcurrentMap;
- /**
- * @Author:
- * @Date: 2018-03-13 14:08
- * @Modified By:
- * @Description:
- */
- public
class
RedisCacheManager
implements
CacheManager{
private
static
final
Logger logger = LoggerFactory
- .getLogger(RedisCacheManager.
class
);
private
final
ConcurrentMap<String, Cache> caches =
new
ConcurrentHashMap<String, Cache>();
private
RedisManager redisManager;
/**
- * The Redis key prefix for caches
- */
private
String keyPrefix =
"shiro_redis_cache:"
;
/**
- * Returns the Redis session keys
- * prefix.
- * @return The prefix
- */
public
String getKeyPrefix() {
return
keyPrefix;
- }
/**
- * Sets the Redis sessions key
- * prefix.
- * @param keyPrefix The prefix
- */
public
void
setKeyPrefix(String keyPrefix) {
this
.keyPrefix = keyPrefix;
- }
@Override
public
<K, V> Cache<K, V> getCache(String name)
throws
CacheException {
- logger.debug(
"获取名称为: "
+ name +
" 的RedisCache实例"
);
- Cache c = caches.get(name);
if
(c ==
null
) {
// initialize the Redis manager instance
- redisManager.init();
// create a new cache instance
- c =
new
RedisCache<K, V>(redisManager, keyPrefix);
// add it to the cache collection
- caches.put(name, c);
- }
return
c;
- }
public
RedisManager getRedisManager() {
return
redisManager;
- }
public
void
setRedisManager(RedisManager redisManager) {
this
.redisManager = redisManager;
-
}
-
-
}
-
RedisCache.java
[java] view plain
copy
- import
org.apache.shiro.cache.Cache;
- import
org.apache.shiro.cache.CacheException;
- import
org.apache.shiro.util.CollectionUtils;
- import
org.slf4j.Logger;
- import
org.slf4j.LoggerFactory;
- import
java.util.*;
- /**
- * @Author:
- * @Date: 2018-03-13 14:10
- * @Modified By:
- * @Description:
- */
- public
class
RedisCache<K,V>
implements
Cache<K,V> {
private
Logger logger = LoggerFactory.getLogger(
this
.getClass());
/**
- * The wrapped Jedis instance.
- */
private
RedisManager cache;
/**
- * The Redis key prefix for the sessions
- */
private
String keyPrefix =
"shiro_redis_session:"
;
/**
- * Returns the Redis session keys
- * prefix.
- * @return The prefix
- */
public
String getKeyPrefix() {
return
keyPrefix;
- }
/**
- * Sets the Redis sessions key
- * prefix.
- * @param keyPrefix The prefix
- */
public
void
setKeyPrefix(String keyPrefix) {
this
.keyPrefix = keyPrefix;
- }
/**
- * 通过一个JedisManager实例构造RedisCache
- */
public
RedisCache(RedisManager cache){
if
(cache ==
null
) {
throw
new
IllegalArgumentException(
"Cache argument cannot be null."
);
- }
this
.cache = cache;
- }
/**
- * Constructs a cache instance with the specified
- * Redis manager and using a custom key prefix.
- * @param cache The cache manager instance
- * @param prefix The Redis key prefix
- */
public
RedisCache(RedisManager cache,
- String prefix){
this
( cache );
this
.keyPrefix = prefix;
- }
/**
- * 获得byte[]型的key
- * @param key
- * @return
- */
private
byte
[] getByteKey(K key){
if
(key
instanceof
String){
- String preKey =
this
.keyPrefix + key;
return
preKey.getBytes();
- }
else
{
return
SerializerUtil.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) SerializerUtil.deserialize(rawValue);
return
value;
- }
- }
catch
(Throwable t) {
throw
new
CacheException(t);
- }
- }
@Override
public
V put(K key, V value)
throws
CacheException {
- logger.debug(
"根据key从存储 key ["
+ key +
"]"
);
try
{
- cache.set(getByteKey(key), SerializerUtil.serialize(value));
return
value;
- }
catch
(Throwable t) {
throw
new
CacheException(t);
- }
- }
@Override
public
V remove(K key)
throws
CacheException {
- logger.debug(
"从redis中删除 key ["
+ key +
"]"
);
try
{
- V previous = get(key);
- cache.del(getByteKey(key));
return
previous;
- }
catch
(Throwable t) {
throw
new
CacheException(t);
- }
- }
@Override
public
void
clear()
throws
CacheException {
- logger.debug(
"从redis中删除所有元素"
);
try
{
- cache.flushDB();
- }
catch
(Throwable t) {
throw
new
CacheException(t);
- }
- }
@Override
public
int
size() {
try
{
- Long longSize =
new
Long(cache.dbSize());
return
longSize.intValue();
- }
catch
(Throwable t) {
throw
new
CacheException(t);
- }
- }
@SuppressWarnings
(
"unchecked"
)
@Override
public
Set<K> keys() {
try
{
- Set<
byte
[]> keys = cache.keys(
this
.keyPrefix +
"*"
);
if
(CollectionUtils.isEmpty(keys)) {
return
Collections.emptySet();
- }
else
{
- Set<K> newKeys =
new
HashSet<K>();
for
(
byte
[] key:keys){
- newKeys.add((K)key);
- }
return
newKeys;
- }
- }
catch
(Throwable t) {
throw
new
CacheException(t);
- }
- }
@Override
public
Collection<V> values() {
try
{
- Set<
byte
[]> keys = cache.keys(
this
.keyPrefix +
"*"
);
if
(!CollectionUtils.isEmpty(keys)) {
- List<V> values =
new
ArrayList<V>(keys.size());
for
(
byte
[] key : keys) {
@SuppressWarnings
(
"unchecked"
)
- V value = get((K)key);
if
(value !=
null
) {
- values.add(value);
- }
- }
return
Collections.unmodifiableList(values);
- }
else
{
return
Collections.emptyList();
- }
- }
catch
(Throwable t) {
throw
new
CacheException(t);
- }
- }
- }