redis插件连接集群 shiro_shiro配置redis做缓存并且配置session共享实现集群

苏凯
2023-12-01

shiro和redis的maven依赖

org.apache.shiro

shiro-core

1.3.2

org.apache.shiro

shiro-web

1.3.2

org.apache.shiro

shiro-spring

1.3.2

org.apache.shiro

shiro-ehcache

1.3.2

redis.clients

jedis

2.9.0

org.springframework.data

spring-data-redis

1.8.7.RELEASE

本配置的前提是已经配置好redis,并且使用spring的redisTemplate进行配置

1、shiro的完整xml配置<?xml version="1.0" encoding="UTF-8"?>

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

/web/page/login.do = anon

/app/** = anon

/** = anon

redirect:/web/page/login.do

redirect:/web/page/unauthorized.do

主要是注意session管理和缓存管理的配置

主要是上面这几个配置,自定义了shiro的缓存管理myCacheManager和sessionDAO管理redisSessionDao

2、redis的完整xml配置<?xml version="1.0" encoding="UTF-8"?>

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

p:host-name="${redis.host}"

p:port="${redis.port}"

p:password="${redis.pass}"

p:pool-config-ref="poolConfig"/>

redis的参数#redis config

redis.host=127.0.0.1

redis.port=6379

redis.pass=123456

redis.maxTotal=2000

redis.maxIdle=50

redis.maxWaitMillis=15000

redis.lifo=true

redis.blockWhenExhausted=true

redis.testOnBorrow=false

redis.testOnReturn=false

redis.testWhileIdle=false

redis.timeBetweenEvictionRunsMillis=30000

3、相关shiro自定义类

MyCacheManager实现shiro的CacheManager缓存管理接口import java.io.Serializable;

import javax.annotation.Resource;

import org.apache.shiro.cache.Cache;

import org.apache.shiro.cache.CacheException;

import org.apache.shiro.cache.CacheManager;

import org.springframework.data.redis.core.RedisTemplate;

/**

*

* @author Administrator

*

*/

public class MyCacheManager implements CacheManager {

@Resource

private RedisTemplate redisTemplate;

@Override

public Cache getCache(String name) throws CacheException {

return new RedisCache(redisTemplate);

}

}

RedisCache实现shiro的Cache缓存接口import org.apache.shiro.cache.Cache;

import org.apache.shiro.cache.CacheException;

import org.springframework.data.redis.connection.RedisConnection;

import org.springframework.data.redis.core.RedisTemplate;

import constant.RedisConstant;

import redis.RedisUtils;

import redis.clients.jedis.Jedis;

import utils.SerializeUtils;

import java.io.Serializable;

import java.util.*;

import javax.annotation.Resource;

/**

* 用redis操作实现shiro缓存接口

* @author Administrator

*

* @param

* @param

*/

@SuppressWarnings({ "rawtypes", "unchecked" })

public class RedisCache implements Cache {

private RedisTemplate redisTemplate;

private String keyPrefix = RedisConstant.SHIRO_REDIS_SESSION_PRE;

public RedisCache(RedisTemplate redisTemplate) {

super();

// TODO Auto-generated constructor stub

//构造函数传递redisTemplate过来

this.redisTemplate = redisTemplate;

}

public String getKeyPrefix() {

return keyPrefix;

}

public void setKeyPrefix(String keyPrefix) {

this.keyPrefix = keyPrefix;

}

/**

* 获得byte[]型的key

* @param key

* @return

*/

private byte[] getByteKey(Object key){

if(key instanceof String){

String preKey = this.keyPrefix + key;

return preKey.getBytes();

}else{

return SerializeUtils.serialize((Serializable) key);

}

}

private RedisConnection getRedisConnect() {

return redisTemplate.getConnectionFactory().getConnection();

}

@Override

public Object get(Object key) throws CacheException {

byte[] bytes = getByteKey(key);

byte[] value = getRedisConnect().get(bytes);

if(value == null){

return null;

}

return SerializeUtils.deserialize(value);

}

/**

* 将shiro的缓存保存到redis中

*/

@Override

public Object put(Object key, Object value) throws CacheException {

RedisConnection redisConnection = getRedisConnect();

redisConnection.set(getByteKey(key), SerializeUtils.serialize((Serializable)value));

byte[] bytes = redisConnection.get(getByteKey(key));

Object object = SerializeUtils.deserialize(bytes);

return object;

}

@Override

public Object remove(Object key) throws CacheException {

RedisConnection redisConnection = getRedisConnect();

byte[] bytes = redisConnection.get(getByteKey(key));

redisConnection.del(getByteKey(key));

return SerializeUtils.deserialize(bytes);

}

/**

* 清空所有缓存

*/

@Override

public void clear() throws CacheException {

RedisConnection redisConnection = getRedisConnect();

redisConnection.flushDb();

}

/**

* 缓存的个数

*/

@Override

public int size() {

RedisConnection redisConnection = getRedisConnect();

Long size = redisConnection.dbSize();

return size.intValue();

}

/**

* 获取所有的key

*/

@Override

public Set keys() {

RedisConnection redisConnection = getRedisConnect();

Set keys = redisConnection.keys(new String("*").getBytes());

Set set = new HashSet();

for (byte[] bs : keys) {

set.add(SerializeUtils.deserialize(bs));

}

return set;

}

/**

* 获取所有的value

*/

@Override

public Collection values() {

RedisConnection redisConnection = getRedisConnect();

Set keys = this.keys();

List values = new ArrayList();

for (Object key : keys) {

byte[] bytes = redisConnection.get(getByteKey(key));

values.add(SerializeUtils.deserialize(bytes));

}

return values;

}

}

RedisSessionDao实现shiro的AbstractSessionDAO 接口

import java.io.Serializable;

import java.util.Collection;

import java.util.HashSet;

import java.util.Set;

import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

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 org.springframework.data.redis.core.RedisTemplate;

public class RedisSessionDao extends AbstractSessionDAO {

private static Logger logger = LoggerFactory.getLogger(RedisSessionDao.class);

@Resource

private RedisTemplate redisTemplate;

/**

* The Redis key prefix for the sessions

*/

private String keyPrefix = constant.RedisConstant.SHIRO_REDIS_SESSION_PRE;

private String getKey(String key) {

return keyPrefix+key;

}

@Override

public void update(Session session) throws UnknownSessionException {

logger.debug("更新seesion,id=[{}]", session.getId().toString());

try {

redisTemplate.opsForValue().set(getKey(session.getId().toString()), session,30,TimeUnit.MINUTES);

} catch (Exception e) {

logger.error(e.getMessage(),e);

}

}

@Override

public void delete(Session session) {

logger.debug("删除seesion,id=[{}]", session.getId().toString());

try {

String key=getKey(session.getId().toString());

redisTemplate.delete(key);

} catch (Exception e) {

logger.error(e.getMessage(),e);

}

}

@Override

public Collection getActiveSessions() {

logger.info("获取存活的session");

Set sessions = new HashSet<>();

Set keys = redisTemplate.keys(getKey("*"));

if (keys != null && keys.size() > 0) {

for (String key : keys) {

Session s = (Session) redisTemplate.opsForValue().get(key);

sessions.add(s);

}

}

return sessions;

}

@Override

protected Serializable doCreate(Session session) {

Serializable sessionId = generateSessionId(session);

assignSessionId(session, sessionId);

logger.debug("创建seesion,id=[{}]", session.getId().toString());

try {

redisTemplate.opsForValue().set(getKey(session.getId().toString()), session,30,TimeUnit.MINUTES);

} catch (Exception e) {

logger.error(e.getMessage(),e);

}

return sessionId;

}

@Override

protected Session doReadSession(Serializable sessionId) {

logger.debug("获取seesion,id=[{}]", sessionId.toString());

Session readSession = null;

try {

readSession=(Session) redisTemplate.opsForValue().get(getKey(sessionId.toString()));

} catch (Exception e) {

logger.error(e.getMessage());

}

return readSession;

}

}

 类似资料: