shiro redis session共享

有个后端项目需要添加一台服务器做均衡。框架用到了springMvc,shiro作为登录和权限控制,发现用spring-session做session有点问题,具体不在描 参考作者忘记了-.-!

   1.application.xml  shiro配置

	<bean id="collectionRedisSessionDao" class="com.fh.dao.CollectionRedisSessionDao"></bean>
	
	<!-- session管理器 -->  
    <bean id="sessionManager"  
        class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">  
        <!-- 超时时间 -->  
        <property name="globalSessionTimeout" value="7200000" />  
        <!-- session存储的实现 -->  
        <property name="sessionDAO" ref="collectionRedisSessionDao"></property> 
        <!-- sessionIdCookie的实现,用于重写覆盖容器默认的JSESSIONID  -->  
        <property name="sessionIdCookie" ref="sharesession" /> 
        <!-- 定时检查失效的session -->  
        <property name="sessionValidationSchedulerEnabled" value="true" />  
    </bean>  
    
	 <bean id="sharesession" class="org.apache.shiro.web.servlet.SimpleCookie">
        <!-- cookie的name,对应的默认是 JSESSIONID -->
        <constructor-arg name="name" value="SHAREJSESSIONID"/>
        <!-- jsessionId的path为 / 用于多个系统共享jsessionId -->
        <property name="path" value="/"/>
    </bean>
	<!-- ================ Shiro start ================ -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
			<property name="realm" ref="ShiroRealm" />
			<property name="sessionManager" ref="sessionManager"></property>
     </bean>
<!-- 項目自定义的Realm -->
	    <bean id="ShiroRealm" class="com.fh.interceptor.shiro.ShiroRealm" ></bean>
		
		<!-- Shiro Filter -->
		<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
			<property name="securityManager" ref="securityManager" />
			
			<property name="loginUrl" value="/" />
			
			<property name="successUrl" value="/main/index" />
			
			<property name="unauthorizedUrl" value="/login_toLogin" />
			
			<property name="filterChainDefinitions">
				<value>
				/static/login/** 			= anon
				/static/** 			        = anon
				/plugins/** 			    = anon
				/static/js/** 				= anon
				/uploadFiles/uploadImgs/** 	= anon
				/upload/** 	                = anon
	           	/code.do 					= anon
	           	/login_login	 			= anon
	           	/app**/** 					= anon
	           	/weixin/** 					= anon
	           	/**							= authc
				</value>
			</property>
		</bean>


2.web.xml

<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>
			org.springframework.web.filter.DelegatingFilterProxy
		</filter-class>
    <init-param>
      <param-name>targetFilterLifecycle</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

3.java代码

import java.io.Serializable;  
import java.util.Collection;  
import java.util.Collections;  
import java.util.concurrent.TimeUnit;  
  
import javax.annotation.PostConstruct;  
  
import org.apache.shiro.session.Session;  
import org.apache.shiro.session.UnknownSessionException;  
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;  
import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.beans.factory.annotation.Value;  
import org.springframework.context.annotation.Lazy;  
import org.springframework.data.redis.core.RedisTemplate;  
import org.springframework.stereotype.Component;


  
@SuppressWarnings({"rawtypes","unchecked"})  
@Component("collectionRedisSessionDao")  
@Lazy(false)  
public class CollectionRedisSessionDao extends AbstractSessionDAO {  
    private static Logger logger = LoggerFactory.getLogger(CollectionRedisSessionDao.class);  
    @Autowired  
    private RedisTemplate redisTemplate;  
   // @Value("${redis.key.prefix}")  
    private String redisPrefixKey="redisPrefixKey";  
    /** 
     * The Redis key prefix for the sessions 
     */  
    private String keyPrefix = "shiro_redis_session:";  
    private String getKey(String originalKey) {  
        return redisPrefixKey + keyPrefix+originalKey;  
    }  
    @PostConstruct  
    public void init(){  
        logger.info("注入催收的序列/反序列类");  
        CollectionSerializer<Serializable> collectionSerializer=CollectionSerializer.getInstance();  
        redisTemplate.setDefaultSerializer(collectionSerializer);  
        //redisTemplate默认采用的其实是valueSerializer,就算是采用其他ops也一样,这是一个坑。  
        redisTemplate.setValueSerializer(collectionSerializer);  
    }  
      
    @Override  
    public void update(Session session) throws UnknownSessionException {  
        logger.debug("更新seesion,id=[{}]", session.getId().toString());  
        try {  
            redisTemplate.opsForValue().set(getKey(session.getId().toString()), session,30,TimeUnit.MINUTES);  
        } catch (Exception e) {  
            logger.error(e.getMessage(),e);  
        }  
    }  
  
    @Override  
    public void delete(Session session) {  
        logger.debug("删除seesion,id=[{}]", session.getId().toString());  
        try {  
            String key=getKey(session.getId().toString());  
            redisTemplate.delete(key);  
        } catch (Exception e) {  
            logger.error(e.getMessage(),e);  
        }  
  
    }  
  
    @Override  
    public Collection<Session> getActiveSessions() {  
        logger.info("获取存活的session");  
        return Collections.emptySet();  
    }  
  
    @Override  
    protected Serializable doCreate(Session session) {  
        Serializable sessionId = generateSessionId(session);  
        assignSessionId(session, sessionId);  
        logger.debug("创建seesion,id=[{}]", session.getId().toString());  
        try {  
            redisTemplate.opsForValue().set(getKey(session.getId().toString()), session,30,TimeUnit.MINUTES);  
        } catch (Exception e) {  
            logger.error(e.getMessage(),e);  
        }  
        return sessionId;  
    }  
  
    @Override  
    protected Session doReadSession(Serializable sessionId) {  
  
        logger.debug("获取seesion,id=[{}]", sessionId.toString());  
        Session readSession = null;  
        try {  
            readSession=(Session) redisTemplate.opsForValue().get(getKey(sessionId.toString()));  
        } catch (Exception e) {  
            logger.error(e.getMessage());  
        }  
        return readSession;  
    }  
      
      
} 

import org.apache.commons.lang3.SerializationUtils;  
import java.io.Serializable;  
import org.springframework.data.redis.serializer.RedisSerializer;  
import org.springframework.data.redis.serializer.SerializationException;  

public class CollectionSerializer<T extends Serializable> implements RedisSerializer<T>{  
    private CollectionSerializer(){}  
    public static volatile CollectionSerializer<Serializable> collectionSerializer=null;  
    public static CollectionSerializer<Serializable> getInstance(){  
        if(collectionSerializer==null){  
            synchronized (CollectionSerializer.class) {  
                if(collectionSerializer==null){  
                    collectionSerializer=new CollectionSerializer<>();  
                }  
            }  
        }  
        return collectionSerializer;  
    }  
    @Override  
    public byte[] serialize(T t) throws SerializationException {  
        return SerializationUtils.serialize(t);  
    }  
  
    @Override  
    public T deserialize(byte[] bytes) throws SerializationException {  
        return SerializationUtils.deserialize(bytes);  
    }  
  
  
}  






  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值