package com.ots.framework.shiro.web.session;
|
import com.ots.common.constant.ShiroConstants;
|
import com.ots.common.utils.StringUtils;
|
import com.ots.common.utils.bean.BeanUtils;
|
import com.ots.common.utils.spring.SpringUtils;
|
import com.ots.project.monitor.online.domain.OnlineSession;
|
import com.ots.project.monitor.online.domain.UserOnline;
|
import com.ots.project.monitor.online.service.UserOnlineServiceImpl;
|
import org.apache.commons.lang3.time.DateUtils;
|
import org.apache.shiro.session.ExpiredSessionException;
|
import org.apache.shiro.session.InvalidSessionException;
|
import org.apache.shiro.session.Session;
|
import org.apache.shiro.session.mgt.DefaultSessionKey;
|
import org.apache.shiro.session.mgt.SessionKey;
|
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import java.util.ArrayList;
|
import java.util.Collection;
|
import java.util.Date;
|
import java.util.List;
|
|
public class OnlineWebSessionManager extends DefaultWebSessionManager {
|
private static final Logger log = LoggerFactory.getLogger(OnlineWebSessionManager.class);
|
@Override
|
public void setAttribute(SessionKey sessionKey, Object attributeKey, Object value) throws InvalidSessionException {
|
super.setAttribute(sessionKey, attributeKey, value);
|
if (value != null && needMarkAttributeChanged(attributeKey)) {
|
OnlineSession session = getOnlineSession(sessionKey);
|
session.markAttributeChanged();
|
}
|
}
|
private boolean needMarkAttributeChanged(Object attributeKey) {
|
if (attributeKey == null) {
|
return false;
|
}
|
String attributeKeyStr = attributeKey.toString();
|
|
if (attributeKeyStr.startsWith("org.springframework")) {
|
return false;
|
}
|
if (attributeKeyStr.startsWith("javax.servlet")) {
|
return false;
|
}
|
if (attributeKeyStr.equals(ShiroConstants.CURRENT_USERNAME)) {
|
return false;
|
}
|
return true;
|
}
|
@Override
|
public Object removeAttribute(SessionKey sessionKey, Object attributeKey) throws InvalidSessionException {
|
Object removed = super.removeAttribute(sessionKey, attributeKey);
|
if (removed != null) {
|
OnlineSession s = getOnlineSession(sessionKey);
|
s.markAttributeChanged();
|
}
|
return removed;
|
}
|
public OnlineSession getOnlineSession(SessionKey sessionKey) {
|
OnlineSession session = null;
|
Object obj = doGetSession(sessionKey);
|
if (StringUtils.isNotNull(obj)) {
|
session = new OnlineSession();
|
BeanUtils.copyBeanProp(session, obj);
|
}
|
return session;
|
}
|
|
@Override
|
public void validateSessions() {
|
if (log.isInfoEnabled()) {
|
log.info("invalidation sessions...");
|
}
|
int invalidCount = 0;
|
int timeout = (int) this.getGlobalSessionTimeout();
|
Date expiredDate = DateUtils.addMilliseconds(new Date(), 0 - timeout);
|
UserOnlineServiceImpl userOnlineService = SpringUtils.getBean(UserOnlineServiceImpl.class);
|
List<UserOnline> userOnlineList = userOnlineService.selectOnlineByExpired(expiredDate);
|
|
List<String> needOfflineIdList = new ArrayList<String>();
|
for (UserOnline userOnline : userOnlineList) {
|
try {
|
SessionKey key = new DefaultSessionKey(userOnline.getSessionId());
|
Session session = retrieveSession(key);
|
if (session != null) {
|
throw new InvalidSessionException();
|
}
|
} catch (InvalidSessionException e) {
|
if (log.isDebugEnabled()) {
|
boolean expired = (e instanceof ExpiredSessionException);
|
String msg = "Invalidated session with id [" + userOnline.getSessionId() + "]"
|
+ (expired ? " (expired)" : " (stopped)");
|
log.debug(msg);
|
}
|
invalidCount++;
|
needOfflineIdList.add(userOnline.getSessionId());
|
}
|
}
|
if (needOfflineIdList.size() > 0) {
|
try {
|
userOnlineService.batchDeleteOnline(needOfflineIdList);
|
} catch (Exception e) {
|
log.error("batch delete db session error.", e);
|
}
|
}
|
if (log.isInfoEnabled()) {
|
String msg = "Finished invalidation session.";
|
if (invalidCount > 0) {
|
msg += " [" + invalidCount + "] sessions were stopped.";
|
} else {
|
msg += " No sessions were stopped.";
|
}
|
log.info(msg);
|
}
|
}
|
@Override
|
protected Collection<Session> getActiveSessions() {
|
throw new UnsupportedOperationException("getActiveSessions method not supported");
|
}
|
}
|