0
点赞
收藏
分享

微信扫一扫

Shiro中的session学习,在线用户显示、用户下线

慕犹清 2022-04-22 阅读 62
java后端

一、代码示例

import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;

import java.util.Collection;

public class UserOnlineService {
    
    @Autowired
    private SessionDAO sessionDAO;

    /**
     *  获取在线用户
     * @param pagerVO
     * @return
     */
    public List<UserOnlineVO> listData() {
        List<UserOnlineVO> list = new ArrayList<>();
        Collection<Session> sessions = sessionDAO.getActiveSessions();
        for (Session session : sessions) {
            UserOnlineVO userOnlineVO = new UserOnlineVO();
            UserVO userVO;
            SimplePrincipalCollection principalCollection;
            if(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY )== null){
                continue;
            }else {
                principalCollection = (SimplePrincipalCollection) session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
                userVO = (UserVO) principalCollection.getPrimaryPrincipal();
                userOnlineVO.setUserName(userVO.getUserName());
                userOnlineVO.setUserId(userVO.getUserId());
            }
            userOnlineVO.setHost(session.getHost());
            userOnlineVO.setSessionId((String) session.getId());
            userOnlineVO.setStartAccessTime(session.getStartTimestamp());
            userOnlineVO.setLastAccessTime(session.getLastAccessTime());
            list.add(userOnlineVO);
        }
        return list;
    }

    /**
     *  让登录用户下线
     * @param sessionId
     * @return
     */
    public Boolean delete(String sessionId) {
        Session session = sessionDAO.readSession(sessionId);
        sessionDAO.delete(session);
        return true;
    }
}

二、代码解析

1、SessionDAO

SessionDAO是用于session持久化的。里面有五个接口:create、readSession、update、delete、getActiveSession

这几个接口看字面意思就清楚了

create:插入新的Session。

readSession:获取session。

update:更新Session;如果更新session最后访问时间、停止会话、设置超时时间、设置移除时间等会调用这个接口。

delete:删除session;如果会话过期、会话停止会调用这个接口。

getActiveSession:获取所有的session

2、SimplePrincipalCollection principalCollection

PrincipalCollection是一个身份集合,因为我们可以在Shiro中同时配置多个Realm,所以呢身份信息可能就有多个;因此其提供了PrincipalCollection用于聚合这些身份信息。

注意:getPrimaryPrincipal,有多个Principal,返回第一个(内部用Map存储的,所以可以认为返回任意一个)

SimplePrincipalCollection 会合并多个Principal为一个PrincipalCollection

3、DefaultSubjectContext.PRINCIPALS_SESSION_KEY

用户登录成功,shiro会将用户名放到session的attribute中,key为DefaultSubjectContext.PRINCIPALS_SESSION_KEY,定义在org.apache.shiro.subject.support.DefaultSubjectContext;

所以就可以通过这个session里面的key找到登录的用户,再将用户的相关信息提取出来,同时也可以找到session的ip地址等等。至于ip地址转化这个,可以用网上收费接口,阿里云一大堆

三、补充

经过一位博友@will_isme的咨询,才发现这边博文没有告知SessionDAO需要注册的问题,所以在这补充一下。先前我是采用了xml的形式,所以可以直接用了sessionDAO这个bean

<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
	<property name="sessionDAO" ref="sessionDAO" />
</bean>

<bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO"/>

如果是不使用xml的形式,只需要编写一个类,继承org.apache.shiro.web.session.mgt.DefaultWebSessionManager,再调用

举报

相关推荐

0 条评论