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

soゝso 2016-08-26 01:31:33 17060

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 Session共享配置以及实现
Shiro教程(四)Shiro + Redis配置
Shiro教程(六)Shiro整体的配置文件
Shiro教程Shiro 配置文件详细解释,Shiro自定义Filter配置
Shiro教程(三)Shiro web.xml中Filter配置配置注意事项
Shiro教程(十)Shiro 权限动态加载与配置精细讲解
Shiro教程(五)Shiro + Redis实现
Shiro教程(十一)Shiro 控制并发登录人数限制实现,登录踢出实现
Shiro教程(八)Shiro Freemarker标签的使用。
Websocket(一)~ Spring Websocket Session共享解决思路
最新文章
Macbook teamviewer 突破5分钟,苹果电脑重置 Mac 地址,100%解决限制 220
腾讯云代金券 10000 元/ 30000 代金券领取技巧 324
SEO 换友情链接的主意事项,友情链接断链、友情链接套路说明 229
Springboot + Mybatis,数据库多数据源配置项目Demo【源码下载】 1903
Mac mtr 安装并使用,mrt: command not found 299
Java 集成阿里云消息队列,日志消息存储 497
域名备案注意事项,网站域名ICP备案快速通过攻略【干货分享】 472
Springboot 集成Aliyun MQ消息队列,Aliyun 消息队列配置及代码实现 837
SpringBoot 集成Spring-data-redis,redis对象序列化存储 2029
天气API,全国天气 JSON API接口,可以获取十五天的天气预报 604
最热文章
Elasticsearch教程(四) elasticsearch head 插件安装和使用 126781
免费天气API,全国天气 JSON API接口,可以获取五天的天气预报 108004
Elasticsearch教程(六) elasticsearch Client创建 78810
Elasticsearch教程(八) elasticsearch delete 删除数据(Java) 74434
Elasticsearch教程(二),IK分词器安装 73217
Elasticsearch教程(一),全程直播(小白级别) 65782
Elasticsearch教程(五) elasticsearch Mapping的创建 61877
Elasticsearch教程(三),IK分词器安装 (极速版) 56361
Elasticsearch教程(七) elasticsearch Insert 插入数据(Java) 53539
Java 解析JSON,JSON-LIB jar包下载和使用。 48973

骚码加入我们 / 千人QQ群:259217951

入群需要5元,如果没有QQ钱包,可以先Alipay、微信,赞助然后加群主拉进。

二维码生成 来自 >> 二维码生成器

支付扫码

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

正在加载... ...