一、代码示例
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,再调用