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

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

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自定义Filter配置
Shiro教程(十)Shiro 权限动态加载与配置精细讲解
Shiro教程(五)Shiro + Redis实现
Shiro教程(三)Shiro web.xml中Filter配置配置注意事项
Shiro教程(八)Shiro Freemarker标签的使用。
Shiro教程(十一)Shiro 控制并发登录人数限制实现,登录踢出实现
Shiro 通过配置Cookie 解决多个二级域名的单点登录问题。
Shiro教程(九)Shiro JSP标签的使用。
最新文章
Java赋值运算符 13
XML内部实体和外部实体 163
Java面向对象编程概念 143
PHP回显语句 91
Linux—文件树 116
C语言while循环和do while循环 131
Python元组剖析 200
MySQL触发器教程 314
sql使用布尔运算符和关系运算符 258
C语言的变量和常量 296
最热文章
最新MyEclipse8.5注册码,有效期到2020年 (已经更新) 682034
苹果电脑Mac怎么恢复出厂系统?苹果系统怎么重装系统? 674719
免费天气API,全国天气 JSON API接口,可以获取五天的天气预报 602129
免费天气API,天气JSON API,不限次数获取十五天的天气预报 577167
Jackson 时间格式化,时间注解 @JsonFormat 用法、时差问题说明 552926
我为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比 509353
Elasticsearch教程(四) elasticsearch head 插件安装和使用 480007
Jackson 美化输出JSON,优雅的输出JSON数据,格式化输出JSON数据... ... 264571
Java 信任所有SSL证书,HTTPS请求抛错,忽略证书请求完美解决 244254
Elasticsearch教程(一),全程直播(小白级别) 225569
支付扫码

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

查看我的收藏

正在加载... ...