|
@@ -0,0 +1,117 @@
|
|
|
|
|
+package net.mingsoft.config;
|
|
|
|
|
+
|
|
|
|
|
+import cn.hutool.core.util.ObjUtil;
|
|
|
|
|
+import cn.hutool.core.util.ReflectUtil;
|
|
|
|
|
+import net.mingsoft.base.biz.IBaseBiz;
|
|
|
|
|
+import org.apache.commons.lang3.SerializationUtils;
|
|
|
|
|
+import org.apache.shiro.session.Session;
|
|
|
|
|
+import org.apache.shiro.session.mgt.SimpleSession;
|
|
|
|
|
+import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
|
|
|
|
|
+
|
|
|
|
|
+import java.io.Serializable;
|
|
|
|
|
+import java.util.Collection;
|
|
|
|
|
+import java.util.Date;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
+import java.util.concurrent.ConcurrentMap;
|
|
|
|
|
+import java.util.stream.Stream;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 把登录的会话保存起来
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author hx
|
|
|
|
|
+ * @date 2025-10-31
|
|
|
|
|
+ */
|
|
|
|
|
+public class DbSessionDAO extends MemorySessionDAO {
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 随便一个能操作数据库的dao
|
|
|
|
|
+ */
|
|
|
|
|
+ private IBaseBiz<?> dao;
|
|
|
|
|
+
|
|
|
|
|
+ public DbSessionDAO(IBaseBiz<?> dao) {
|
|
|
|
|
+ super();
|
|
|
|
|
+ this.dao = dao;
|
|
|
|
|
+ ConcurrentMap<Serializable, Session> sessions = new ConcurrentHashMap<>() {
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Session putIfAbsent(Serializable key, Session value) {
|
|
|
|
|
+ saveOrUpdate(key.toString(), (SimpleSession) value);
|
|
|
|
|
+ return super.putIfAbsent(key, value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Session get(Object key) {
|
|
|
|
|
+ Session session = super.get(key);
|
|
|
|
|
+ if (session == null) {
|
|
|
|
|
+ // 内存查不到就从数据库里找
|
|
|
|
|
+ session = query(key.toString());
|
|
|
|
|
+ if (session != null) {
|
|
|
|
|
+ // 如果数据库里有,那也保存一份到内存
|
|
|
|
|
+ put((Serializable) key, session);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return session;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Session remove(Object key) {
|
|
|
|
|
+ delete(key.toString());
|
|
|
|
|
+ return super.remove(key);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Collection<Session> values() {
|
|
|
|
|
+ return all().map(row -> (Session) row).toList();
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ ReflectUtil.setFieldValue(this, "sessions", sessions);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 保存或修改
|
|
|
|
|
+ */
|
|
|
|
|
+ public void saveOrUpdate(String key, SimpleSession value) {
|
|
|
|
|
+ byte[] session = serialize(value);
|
|
|
|
|
+ Date time = new Date(value.getLastAccessTime().getTime() + value.getTimeout());
|
|
|
|
|
+ if (query(key) == null) {
|
|
|
|
|
+ dao.update("INSERT INTO login_session (id, session,time) VALUES (?,?,?)", key, session, time);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ dao.update("UPDATE login_session SET session =?,time=? WHERE id=?", session, time, key);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 查单个
|
|
|
|
|
+ */
|
|
|
|
|
+ private SimpleSession query(String key) {
|
|
|
|
|
+ return dao.queryForList("select * from login_session where id=?", key)
|
|
|
|
|
+ .stream()
|
|
|
|
|
+ .map(DbSessionDAO::deserialize)
|
|
|
|
|
+ .findFirst()
|
|
|
|
|
+ .orElse(null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 查所有
|
|
|
|
|
+ */
|
|
|
|
|
+ private Stream<SimpleSession> all() {
|
|
|
|
|
+ return dao.queryForList("select * from login_session")
|
|
|
|
|
+ .stream()
|
|
|
|
|
+ .map(DbSessionDAO::deserialize);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 删除
|
|
|
|
|
+ */
|
|
|
|
|
+ private void delete(String key) {
|
|
|
|
|
+ dao.update("delete from login_session where id=?", key);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static byte[] serialize(SimpleSession value) {
|
|
|
|
|
+ return ObjUtil.serialize(value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static SimpleSession deserialize(Map<String, Object> map) {
|
|
|
|
|
+ return SerializationUtils.deserialize((byte[]) map.get("session"));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|