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

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

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

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

本文主题:

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

相关文章
HttpClient 多次请求session保持同一个Session
JSON压缩算法 JSON.hpack ,JSON压缩实现
Druid数据库配置详细介绍。网上一团糟。
Shiro + EHCache 缓存的使用。
单个项目多个二级域名简单实现思路
Java 实现多个二级域名访问同一个Tomcat(系统)。
N多系统单点登录,实现、解决方案。四种解决方案
Elasticsearch教程(一),全程直播(小白级别)
Elasticsearch教程(二),IK分词器安装
Elasticsearch教程(三),IK分词器安装 (极速版)
最新文章
ICP怎么操作取消备案,企业、个人怎么自己申请取消备案? 17
Javascript 加密/压缩后运行不了,JavaScript报错排查讲解 41
JavaScript 不可逆加密问题排查之方案一(闭包优化) 45
Java爬虫,Jsoup 爬取大众点评、美团商家信息电话号码解决方案 243
分解质因数 JavaScript 计算方式,及分解质因数讲解 8
湖南腾众4s店服务怎么样?进来看看你就知道了 29
SEO 之 SpringMVC redirect 301,301和302区别详细讲解 82
网站如何设置404页面、500等错误页面,有什么漏洞?怎么预防? 101
Java 文字转图片输出,Java 输出透明背景图片,Java文字转图片防爬虫 153
HttpClient获取访问域名的真实ip,HttpClient请求获取目标IP地址 298
最热文章
免费天气API,全国天气 JSON API接口,可以获取五天的天气预报 175183
Elasticsearch教程(四) elasticsearch head 插件安装和使用 138300
我为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比 117968
Elasticsearch教程(六) elasticsearch Client创建 81987
Elasticsearch教程(一),全程直播(小白级别) 77090
Elasticsearch教程(二),IK分词器安装 77059
Elasticsearch教程(八) elasticsearch delete 删除数据(Java) 76748
苹果电脑Mac怎么恢复出厂系统?苹果系统怎么重装系统? 75165
Elasticsearch教程(五) elasticsearch Mapping的创建 69395
Elasticsearch教程(三),IK分词器安装 (极速版) 58149

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

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

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

支付扫码

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

正在加载... ...