Shiro教程(七)Shiro Session共享配置以及实现

JSON 2016-08-26 01:31:33 31752

shiro demo下载

Shiro + SSM(框架) + Freemarker(jsp)讲解的权限控制Demo,还不赶快去下载?




Shiro  我们通过重写AbstractSessionDAO ,来实现 Session  共享。再重写 Session  的时候(其实也不算重写),因为和HttpSession 没有任何实现或者继承关系。

首先 Shiro   Session  配置讲解。

Session  的每个回话的ID 生成器,我们用JavaUuidSessionIdGenerator UUID 规则)。

<!-- 会话Session ID生成器 -->
<bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>

Session  的创建、获取、删除

<!-- session 创建、删除、查询 -->
<bean id="jedisShiroSessionRepository" class="com.sojson.core.shiro.cache.JedisShiroSessionRepository" >
	 <property name="jedisManager" ref="jedisManager"/>
</bean>

Session  的监听生命周期

<!-- custom shiro session listener -->
<bean id="customShiroSessionDAO" class="com.sojson.core.shiro.CustomShiroSessionDAO">
    <property name="shiroSessionRepository" ref="jedisShiroSessionRepository"/>
    <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
</bean>

Session  定时管理器(有效期)

<!-- 会话验证调度器 -->
<bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler">
     <property name="interval" value="${session.validate.timespan}"/><!--检测时间间距,默认是60分钟-->
     <property name="sessionManager" ref="sessionManager"/>
</bean>

Session   cookie  模版配置

<!-- 会话Cookie模板 -->
<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
	<!--cookie的name,我故意取名叫xxxxbaidu -->
    <constructor-arg value="v_v-s-baidu"/>
    <property name="httpOnly" value="true"/>
    <!--cookie的有效时间 -->
    <property name="maxAge" value="-1"/>
    <!-- 配置存储Session Cookie的domain为 一级域名 -->
    <property name="domain" value=".itboy.net"/>
</bean>

Session  Manager 配置

<!-- Session Manager -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
	<!-- 相隔多久检查一次session的有效性   -->
 	<property name="sessionValidationInterval" value="1800000"/>  
 	 <!-- session 有效时间为半小时 (毫秒单位)-->  
<property name="globalSessionTimeout" value="1800000"/>
   <property name="sessionDAO" ref="customShiroSessionDAO"/>
   <!-- session 监听,可以多个。 -->
   <property name="sessionListeners">
       <list>
           <ref bean="customSessionListener"/>
       </list>
   </property>
   <!-- 间隔多少时间检查,不配置是60分钟 -->	
  <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
  <!-- 是否开启 检测,默认开启 -->
  <property name="sessionValidationSchedulerEnabled" value="true"/>
   <!-- 是否删除无效的,默认也是开启 -->
  <property name="deleteInvalidSessions" value="true"/>
	<!-- 会话Cookie模板 -->
   <property name="sessionIdCookie" ref="sessionIdCookie"/>
</bean>

Session  的创建、删除、查询 ,ShiroSessionRepository 接口定义。

package com.sojson.core.shiro.session;

import org.apache.shiro.session.Session;

import java.io.Serializable;
import java.util.Collection;

/**
 * custom shiro session manager interface
 *
 * @author zhoubaicheng
 */
public interface ShiroSessionRepository {

	/**
	 * 存储Session
	 * @param session
	 */
    void saveSession(Session session);
    /**
     * 删除session
     * @param sessionId
     */
    void deleteSession(Serializable sessionId);
    /**
     * 获取session
     * @param sessionId
     * @return
     */
    Session getSession(Serializable sessionId);
    /**
     * 获取所有sessoin
     * @return
     */
    Collection<Session> getAllSessions();
}

Session  的创建、删除、查询实现。com.sojson.core.shiro.cache.JedisShiroSessionRepository

package com.sojson.core.shiro.cache;

import java.io.Serializable;
import java.util.Collection;

import org.apache.log4j.Logger;
import org.apache.shiro.session.Session;

import com.sojson.common.utils.SerializeUtil;
import com.sojson.core.shiro.session.ShiroSessionRepository;
/**
 * Session 管理
 * @author sojson.com
 *
 */
@SuppressWarnings("unchecked")
public class JedisShiroSessionRepository implements ShiroSessionRepository {
	private static Logger logger = Logger.getLogger(JedisShiroSessionRepository.class);
    public static final String REDIS_SHIRO_SESSION = "sojson-shiro-session:";
    //这里有个小BUG,因为Redis使用序列化后,Key反序列化回来发现前面有一段乱码,解决的办法是存储缓存不序列化
    public static final String REDIS_SHIRO_ALL = "*sojson-shiro-session:*";
    private static final int SESSION_VAL_TIME_SPAN = 18000;
    private static final int DB_INDEX = 1;

    private JedisManager jedisManager;

    @Override
    public void saveSession(Session session) {
        if (session == null || session.getId() == null)
            throw new NullPointerException("session is empty");
        try {
            byte[] key = SerializeUtil.serialize(buildRedisSessionKey(session.getId()));
            byte[] value = SerializeUtil.serialize(session);
            long sessionTimeOut = session.getTimeout() / 1000;
            Long expireTime = sessionTimeOut + SESSION_VAL_TIME_SPAN + (5 * 60);
            getJedisManager().saveValueByKey(DB_INDEX, key, value, expireTime.intValue());
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("save session error");
        }
    }

    @Override
    public void deleteSession(Serializable id) {
        if (id == null) {
            throw new NullPointerException("session id is empty");
        }
        try {
            getJedisManager().deleteByKey(DB_INDEX,
                    SerializeUtil.serialize(buildRedisSessionKey(id)));
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("delete session error");
        }
    }

   
	@Override
    public Session getSession(Serializable id) {
        if (id == null)
            throw new NullPointerException("session id is empty");
        Session session = null;
        try {
            byte[] value = getJedisManager().getValueByKey(DB_INDEX, SerializeUtil
                    .serialize(buildRedisSessionKey(id)));
            session = SerializeUtil.deserialize(value, Session.class);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("get session error");
        }
        return session;
    }

    @Override
    public Collection<Session> getAllSessions() {
    	Collection<Session> sessions = null;
		try {
			sessions = getJedisManager().AllSession(DB_INDEX,REDIS_SHIRO_SESSION);
		} catch (Exception e) {
			logger.error("获取全部session异常");
			e.printStackTrace();
		}
       
        return sessions;
    }

    private String buildRedisSessionKey(Serializable sessionId) {
        return REDIS_SHIRO_SESSION + sessionId;
    }

    public JedisManager getJedisManager() {
        return jedisManager;
    }

    public void setJedisManager(JedisManager jedisManager) {
        this.jedisManager = jedisManager;
    }
}

CustomShiroSessionDAO的继承实现

package com.sojson.core.shiro;

import java.io.Serializable;
import java.util.Collection;

import org.apache.log4j.Logger;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;

import com.sojson.core.shiro.session.ShiroSessionRepository;

public class CustomShiroSessionDAO extends AbstractSessionDAO{ 
	
	private static Logger logger = Logger.getLogger(CustomShiroSessionDAO.class);
	
    private ShiroSessionRepository shiroSessionRepository;  
  
    public ShiroSessionRepository getShiroSessionRepository() {  
        return shiroSessionRepository;  
    }  
  
    public void setShiroSessionRepository(  
            ShiroSessionRepository shiroSessionRepository) {  
        this.shiroSessionRepository = shiroSessionRepository;  
    }  
  
    @Override  
    public void update(Session session) throws UnknownSessionException {  
        getShiroSessionRepository().saveSession(session);  
    }  
  
    @Override  
    public void delete(Session session) {  
        if (session == null) {  
        	logger.error( 
                    "session can not be null,delete failed");  
            return;  
        }  
        Serializable id = session.getId();  
        if (id != null)  
            getShiroSessionRepository().deleteSession(id);  
    }  
  
    @Override  
    public Collection<Session> getActiveSessions() {  
        return getShiroSessionRepository().getAllSessions();  
    }  
  
    @Override  
    protected Serializable doCreate(Session session) {  
        Serializable sessionId = this.generateSessionId(session);  
        this.assignSessionId(session, sessionId);  
        getShiroSessionRepository().saveSession(session);  
        return sessionId;  
    }  
  
    @Override  
    protected Session doReadSession(Serializable sessionId) {  
        return getShiroSessionRepository().getSession(sessionId);  
    } }

这样基本就OK了, Redis  配置请看前面的博客。因为我们是使用同一个 Redis  ,所以 Session  是共享的。

有什么问题加群详细交流。


版权所属:SO JSON在线解析

原文地址:https://www.sojson.com/blog/137.html

转载时必须以链接形式注明原始出处及本声明。

本文主题:

如果本文对你有帮助,那么请你赞助我,让我更有激情的写下去,帮助更多的人。

关于作者
一个低调而闷骚的男人。
相关文章
Shiro教程(四)Shiro + Redis配置
Shiro教程(六)Shiro整体的配置文件
Shiro教程(十)Shiro 权限动态加载与配置精细讲解
Shiro教程Shiro 配置文件详细解释,Shiro自定义Filter配置
Shiro教程(五)Shiro + Redis实现
Shiro教程(三)Shiro web.xml中Filter配置配置注意事项
Shiro教程(十一)Shiro 控制并发登录人数限制实现,登录踢出实现
Shiro教程(八)Shiro Freemarker标签的使用。
Shiro 通过配置Cookie 解决多个二级域名的单点登录问题。
Shiro教程(九)Shiro JSP标签的使用。
最新文章
文件上传漏洞与防御 4475
前端构建工具选型指南:Webpack、Vite、Rollup、esbuild 深度对比 1541
物联网时代2026年时序数据库选型指南 1283
SaaS行业面临AI挑战:从“无限复用”到“灵活适应” 1411
神经网络:从构造到模型训练全链路解析 1196
一文吃透 Redis 核心存储结构:ziplist、listpack 与哈希表扩容 / 并发查询 1674
Linux sudo提权完整指南:从基础用法到生产级安全配置 780
XSS 和 CSRF 的本质区别及开发防御全解析 846
JVM垃圾回收(GC)全维度解析:从原理到调优实战 846
Linux动静态库与ELF加载全解析:从实操制作到底层原理 1000
最热文章
免费天气API,天气JSON API,不限次数获取十五天的天气预报 784545
最新MyEclipse8.5注册码,有效期到2020年 (已经更新) 711819
苹果电脑Mac怎么恢复出厂系统?苹果系统怎么重装系统? 680083
Jackson 时间格式化,时间注解 @JsonFormat 用法、时差问题说明 562703
我为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比 512663
Elasticsearch教程(四) elasticsearch head 插件安装和使用 484864
Jackson 美化输出JSON,优雅的输出JSON数据,格式化输出JSON数据... ... 303091
Java 信任所有SSL证书,HTTPS请求抛错,忽略证书请求完美解决 247490
Elasticsearch教程(一),全程直播(小白级别) 233169
谈谈斐讯路由器劫持,你用斐讯路由器,你需要知道的事情 228412
支付扫码

所有赞助/开支都讲公开明细,用于网站维护:赞助名单查看

查看我的收藏

正在加载... ...