Shiro教程(五)Shiro + Redis实现
Shiro + SSM(框架) + Freemarker(jsp)讲解的权限控制Demo,还不赶快去下载?
上一篇博客讲到了 Shiro + redis 的配置,其实没说完,但是在上篇说完不合适,所以在这里来细化说明, Shiro 首先是支持任何存储的和它来一起完成这个任务的,因为它提供了接口是交给我们来实现的。
要实现的接口:
1.org.apache.shiro.cache.CacheManager
(缓存管理)
2.org.apache.shiro.cache.Cache
(实现缓存存储)
3.org.apache.shiro.session.SessionListener
(Session监听)
缓存的配置:
<!-- 用户缓存 -->
<bean id="customShiroCacheManager" class="com.sojson.core.shiro.cache.impl.CustomShiroCacheManager">
<property name="shiroCacheManager" ref="jedisShiroCacheManager"/>
</bean>
<!-- shiro 缓存实现,对ShiroCacheManager,我是采用redis的实现 -->
<bean id="jedisShiroCacheManager" class="com.sojson.core.shiro.cache.impl.JedisShiroCacheManager">
<property name="jedisManager" ref="jedisManager"/>
</bean>
<!-- redis 的缓存 -->
<bean id="jedisManager" class="com.sojson.core.shiro.cache.JedisManager">
<property name="jedisPool" ref="jedisPool"/>
</bean>
首先是用户的缓存类。CustomShiroCacheManager.java
package com.sojson.core.shiro.cache.impl;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.util.Destroyable;
import com.sojson.core.shiro.cache.ShiroCacheManager;
/**
*
* 开发公司:sojson.com<br/>
* 版权:sojson.com<br/>
* <p>
*
* shiro Custom Cache
*
* <p>
*
* 区分 责任人 日期 说明<br/>
* 创建 周柏成 2016年4月29日 <br/>
* <p>
* *******
* <p>
* @author zhou-baicheng
* @email json@sojson.com
* @version 1.0,2016年4月29日 <br/>
*
*/
public class CustomShiroCacheManager implements CacheManager, Destroyable {
private ShiroCacheManager shiroCacheManager;
@Override
public <K, V> Cache<K, V> getCache(String name) throws CacheException {
return getShiroCacheManager().getCache(name);
}
@Override
public void destroy() throws Exception {
shiroCacheManager.destroy();
}
public ShiroCacheManager getShiroCacheManager() {
return shiroCacheManager;
}
public void setShiroCacheManager(ShiroCacheManager shiroCacheManager) {
this.shiroCacheManager = shiroCacheManager;
}
}
JRedis管理类JedisShiroCacheManager.java
package com.sojson.core.shiro.cache.impl;
import org.apache.shiro.cache.Cache;
import com.sojson.core.shiro.cache.JedisManager;
import com.sojson.core.shiro.cache.JedisShiroCache;
import com.sojson.core.shiro.cache.ShiroCacheManager;
/**
*
* 开发公司:itboy.net<br/>
* 版权:itboy.net<br/>
* <p>
*
* JRedis管理
*
* <p>
*
* 区分 责任人 日期 说明<br/>
* 创建 周柏成 2016年5月6日 <br/>
* <p>
* *******
* <p>
* @author zhou-baicheng
* @email i@itboy.net
* @version 1.0,2016年5月6日 <br/>
*
*/
public class JedisShiroCacheManager implements ShiroCacheManager {
private JedisManager jedisManager;
@Override
public <K, V> Cache<K, V> getCache(String name) {
return new JedisShiroCache<K, V>(name, getJedisManager());
}
@Override
public void destroy() {
//如果和其他系统,或者应用在一起就不能关闭
//getJedisManager().getJedis().shutdown();
}
public JedisManager getJedisManager() {
return jedisManager;
}
public void setJedisManager(JedisManager jedisManager) {
this.jedisManager = jedisManager;
}
}
Redis 操作类(工具类)JedisManager.java
package com.sojson.core.shiro.cache;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.apache.shiro.session.Session;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisConnectionException;
import com.sojson.common.utils.LoggerUtils;
import com.sojson.common.utils.SerializeUtil;
/**
*
* 开发公司:sojson.com<br/>
* 版权:sojson.com<br/>
* <p>
*
* Redis Manager Utils
*
* <p>
*
* 区分 责任人 日期 说明<br/>
* 创建 周柏成 2016年4月29日 <br/>
* <p>
* *******
* <p>
* @author zhou-baicheng
* @email json@sojson.com
* @version 1.0,2016年4月29日 <br/>
*
*/
public class JedisManager {
private JedisPool jedisPool;
public Jedis getJedis() {
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
} catch (Exception e) {
throw new JedisConnectionException(e);
}
return jedis;
}
public void returnResource(Jedis jedis, boolean isBroken) {
if (jedis == null)
return;
if (isBroken)
getJedisPool().returnBrokenResource(jedis);
else
getJedisPool().returnResource(jedis);
}
public byte[] getValueByKey(int dbIndex, byte[] key) throws Exception {
Jedis jedis = null;
byte[] result = null;
boolean isBroken = false;
try {
jedis = getJedis();
jedis.select(dbIndex);
result = jedis.get(key);
} catch (Exception e) {
isBroken = true;
throw e;
} finally {
returnResource(jedis, isBroken);
}
return result;
}
public void deleteByKey(int dbIndex, byte[] key) throws Exception {
Jedis jedis = null;
boolean isBroken = false;
try {
jedis = getJedis();
jedis.select(dbIndex);
Long result = jedis.del(key);
LoggerUtils.fmtDebug(getClass(), "删除Session结果:%s" , result);
} catch (Exception e) {
isBroken = true;
throw e;
} finally {
returnResource(jedis, isBroken);
}
}
public void saveValueByKey(int dbIndex, byte[] key, byte[] value, int expireTime)
throws Exception {
Jedis jedis = null;
boolean isBroken = false;
try {
jedis = getJedis();
jedis.select(dbIndex);
jedis.set(key, value);
if (expireTime > 0)
jedis.expire(key, expireTime);
} catch (Exception e) {
isBroken = true;
throw e;
} finally {
returnResource(jedis, isBroken);
}
}
public JedisPool getJedisPool() {
return jedisPool;
}
public void setJedisPool(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
/**
* 获取所有Session
* @param dbIndex
* @param redisShiroSession
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public Collection<Session> AllSession(int dbIndex, String redisShiroSession) throws Exception {
Jedis jedis = null;
boolean isBroken = false;
Set<Session> sessions = new HashSet<Session>();
try {
jedis = getJedis();
jedis.select(dbIndex);
Set<byte[]> byteKeys = jedis.keys((JedisShiroSessionRepository.REDIS_SHIRO_ALL).getBytes());
if (byteKeys != null && byteKeys.size() > 0) {
for (byte[] bs : byteKeys) {
Object obj = SerializeUtil.deserialize(jedis.get(bs),
Object.class);
if(obj instanceof Session){
sessions.add((Session)obj);
}
}
}
} catch (Exception e) {
isBroken = true;
throw e;
} finally {
returnResource(jedis, isBroken);
}
return sessions;
}
}
SessionListener
的实现。
package com.sojson.core.shiro.listenter;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.SessionListener;
import com.sojson.core.shiro.session.ShiroSessionRepository;
public class CustomSessionListener implements SessionListener {
private ShiroSessionRepository shiroSessionRepository;
/**
* 一个回话的生命周期开始
*/
@Override
public void onStart(Session session) {
//TODO
System.out.println("on start");
}
/**
* 一个回话的生命周期结束
*/
@Override
public void onStop(Session session) {
//TODO
System.out.println("on stop");
}
@Override
public void onExpiration(Session session) {
shiroSessionRepository.deleteSession(session.getId());
}
public ShiroSessionRepository getShiroSessionRepository() {
return shiroSessionRepository;
}
public void setShiroSessionRepository(ShiroSessionRepository shiroSessionRepository) {
this.shiroSessionRepository = shiroSessionRepository;
}
}
关于生命周期的问题。可以自己实现,可以做一些在线用户的相关操作,以及踢出等操作。
后面弄完后,我会把整个项目的代码提供出来。
版权所属:SO JSON在线解析
原文地址:https://www.sojson.com/blog/135.html
转载时必须以链接形式注明原始出处及本声明。
如果本文对你有帮助,那么请你赞助我,让我更有激情的写下去,帮助更多的人。