记一下Shiro重构之Redis Catch

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 记一下Shiro重构之Redis Catch

RedisCache 实现 Cache 接口

自定义Cache类,主要是将缓存全部交给Redis管理,而不是使用其默认存储体系

package com.ccb.web.shiro;
import com.ccb.web.configs.CsRedisUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import projects.commons.utils.ValidateUtils;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
/**
 * Redis Catch
 *
 * @author zhuyongsheng
 * @date 2019/8/13
 */
@Slf4j
@Data
public class RedisCache<K, V> implements Cache<K, V> {
    @Autowired
    CsRedisUtil redisUtil;
    //key前缀
    private String keyPrefix = "";
    // redis TTL
    private int expire = 0;
    //存储对象ID名称
    private String principalIdFieldName = RedisCacheManager.DEFAULT_PRINCIPAL_ID_FIELD_NAME;
    /**
     * 初始化
     *
     * @author zhuyongsheng
     * @date 2019/8/15
     */
    public RedisCache(String prefix, int expire, String principalIdFieldName) {
        if (prefix != null && !"".equals(prefix)) {
            this.keyPrefix = prefix;
        }
        if (expire != -1) {
            this.expire = expire;
        }
        if (principalIdFieldName != null && !"".equals(principalIdFieldName)) {
            this.principalIdFieldName = principalIdFieldName;
        }
    }
    /**
     * 清空缓存
     *
     * @author zhuyongsheng
     * @date 2019/8/15
     */
    @Override
    public void clear() throws CacheException {
        Set<String> keys = null;
        try {
            keys = redisUtil.scan(this.keyPrefix + "*");
        } catch (Exception e) {
            log.warn("==clear==获取key失败=={}", e.getMessage());
        }
        if (keys == null || keys.size() == 0) {
            return;
        }
        for (String key : keys) {
            redisUtil.del(key);
        }
    }
    /**
     * 根据key获取对象信息
     *
     * @return V
     * @author zhuyongsheng
     * @date 2019/8/13
     */
    @Override
    public V get(K key) throws CacheException {
        if (ValidateUtils.isNotNull(key)) {
            return null;
        }
        try {
            String redisCacheKey = getRedisCacheKey(key);
            Object rawValue = redisUtil.get(redisCacheKey);
            if (rawValue == null) {
                return null;
            }
            V value = (V) rawValue;
            return value;
        } catch (Exception e) {
            log.warn("==get==获取key失败=={}", e.getMessage());
            throw new CacheException("获取数据失败!");
        }
    }
    @SuppressWarnings("unchecked")
    @Override
    public Set<K> keys() {
        Set<String> keys;
        try {
            keys = redisUtil.scan(this.keyPrefix + "*");
        } catch (Exception e) {
            log.warn("==keys==获取key失败=={}", e.getMessage());
            return Collections.emptySet();
        }
        if (CollectionUtils.isEmpty(keys)) {
            return Collections.emptySet();
        }
        Set<K> convertedKeys = new HashSet<>();
        for (String key : keys) {
            try {
                convertedKeys.add((K) key);
            } catch (Exception e) {
                log.warn("==keys==序列化失败=={}", e.getMessage());
            }
        }
        return convertedKeys;
    }
    /**
     * 存放数据
     *
     * @return V
     * @author zhuyongsheng
     * @date 2019/8/13
     */
    @Override
    public V put(K key, V value) throws CacheException {
        if (ValidateUtils.isNotNull(key)) {
            return value;
        }
        try {
            String redisCacheKey = getRedisCacheKey(key);
            redisUtil.set(redisCacheKey, value != null ? (Serializable) value : null, expire);
            return value;
        } catch (Exception e) {
            log.warn("==put==设置key失败=={},key={},value={}}", e.getMessage(), key, value);
            throw new CacheException("获取key值失败!");
        }
    }
    /**
     * 删除数据
     *
     * @return V
     * @author zhuyongsheng
     * @date 2019/8/13
     */
    @Override
    public V remove(K key) throws CacheException {
        if (ValidateUtils.isNotNull(key)) {
            return null;
        }
        try {
            String redisCacheKey = getRedisCacheKey(key);
            Object rawValue = redisUtil.get(redisCacheKey);
            V previous = (V) rawValue;
            redisUtil.del(redisCacheKey);
            return previous;
        } catch (Exception e) {
            log.warn("==remove==获取key失败=={}", e.getMessage());
            throw new CacheException("删除数据失败!");
        }
    }
    /**
     * 获取CacheKey值
     *
     * @return java.lang.String
     * @author zhuyongsheng
     * @date 2019/8/13
     */
    private String getRedisCacheKey(K key) {
        if (ValidateUtils.isNotNull(key)) {
            return null;
        }
        return this.keyPrefix + getStringRedisKey(key);
    }
    /**
     * 获取RedisKey
     *
     * @return java.lang.String
     * @author zhuyongsheng
     * @date 2019/8/13
     */
    private String getStringRedisKey(K key) {
        String redisKey;
        if (key instanceof PrincipalCollection) {
            redisKey = getRedisKeyFromPrincipalIdField((PrincipalCollection) key);
        } else {
            redisKey = key.toString();
        }
        return redisKey;
    }
    private String getRedisKeyFromPrincipalIdField(PrincipalCollection key) {
        String redisKey;
        Object principalObject = key.getPrimaryPrincipal();
        Method pincipalIdGetter = null;
        Method[] methods = principalObject.getClass().getDeclaredMethods();
        for (Method m : methods) {
            if (RedisCacheManager.DEFAULT_PRINCIPAL_ID_FIELD_NAME.equals(this.principalIdFieldName)
                    && ("getAuthCacheKey".equals(m.getName()) || "getId".equals(m.getName()))) {
                pincipalIdGetter = m;
                break;
            }
            if (m.getName().equals("get" + this.principalIdFieldName.substring(0, 1).toUpperCase() + this.principalIdFieldName.substring(1))) {
                pincipalIdGetter = m;
                break;
            }
        }
        if (pincipalIdGetter == null) {
            throw new PrincipalInstanceException(principalObject.getClass(), this.principalIdFieldName);
        }
        try {
            Object idObj = pincipalIdGetter.invoke(principalObject);
            if (idObj == null) {
                throw new PrincipalIdNullException(principalObject.getClass(), this.principalIdFieldName);
            }
            redisKey = idObj.toString();
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new PrincipalInstanceException(principalObject.getClass(), this.principalIdFieldName, e);
        }
        return redisKey;
    }
    /**
     * 获取数量
     *
     * @return int
     * @author zhuyongsheng
     * @date 2019/8/15
     */
    @Override
    public int size() {
        Long longSize = 0L;
        try {
            longSize = redisUtil.scanSize(this.keyPrefix + "*");
        } catch (Exception e) {
            log.warn("==size==获取key失败=={}", e.getMessage());
        }
        return longSize.intValue();
    }
    @SuppressWarnings("unchecked")
    @Override
    public Collection<V> values() {
        Set<String> keys;
        try {
            keys = redisUtil.scan(this.keyPrefix + "*");
        } catch (Exception e) {
            log.warn("==values==获取key失败=={}", e.getMessage());
            return Collections.emptySet();
        }
        if (CollectionUtils.isEmpty(keys)) {
            return Collections.emptySet();
        }
        List<V> values = new ArrayList<>(keys.size());
        for (String key : keys) {
            V value = null;
            try {
                value = (V) redisUtil.get(key);
            } catch (Exception e) {
                log.warn("==values==获取key失败=={}", e.getMessage());
            }
            if (value != null) {
                values.add(value);
            }
        }
        return Collections.unmodifiableList(values);
    }
}
相关文章
|
缓存 NoSQL fastjson
Shiro Session集群共享存入Redis中SimpleSession的transient 属性不能序列化
Shiro Session集群共享存入Redis中SimpleSession的transient 属性不能序列化
370 0
|
NoSQL Java Redis
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
这篇文章介绍了如何使用Spring Boot整合Apache Shiro框架进行后端开发,包括认证和授权流程,并使用Redis存储Token以及MD5加密用户密码。
310 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
|
JavaScript NoSQL Java
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
393 0
|
NoSQL Redis
shiro的session信息放redis反序列化异常解决
shiro的session信息放redis反序列化异常解决
439 0
|
NoSQL 安全 Linux
springboot+shiro+redis前后端分离实现认证(一)
springboot+shiro+redis前后端分离实现认证(一)
517 0
|
NoSQL Java 数据库
spring boot + shiro + redis 整合(完整)
spring boot + shiro + redis 整合(完整)
1331 0
|
缓存 NoSQL 安全
2021年你还不会Shiro?----10.使用redis实现Shiro的缓存
上一篇文章已经总结了使用ehCache来实现Shiro的缓存管理,步骤也很简单,引入依赖后,直接开启Realm的缓存管理器即可。如果使用Redis来实现缓存管理其实也是一样的,我们也是需要引入redis的依赖,然后开启缓存传入自定义的redis的缓存管理器就行。区别是我们需要为自定义的redis缓存管理器提供自定义的缓存管理类。这个缓存管理类中需要使用到redisTemplate模板,这个模板我们也是需要自己定义。
383 0
2021年你还不会Shiro?----10.使用redis实现Shiro的缓存
|
缓存 JSON NoSQL
Shiro使用Redis作为缓存
Shiro使用Redis作为缓存!
|
缓存 负载均衡 NoSQL
shiro 与 redis | 学习笔记
快速学习 shiro 与 redis
160 0
shiro 与 redis | 学习笔记