浏览代码

新增session管理器,用于查看当前登录用户,踢出登录等操作

周浩 9 年之前
父节点
当前提交
f633459346

+ 10 - 0
hsweb-web-core/pom.xml

@@ -15,6 +15,16 @@
             <groupId>org.hsweb</groupId>
             <artifactId>hsweb-web-bean</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-redis</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.session</groupId>
+            <artifactId>spring-session-data-redis</artifactId>
+            <optional>true</optional>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-aop</artifactId>

+ 69 - 0
hsweb-web-core/src/main/java/org/hsweb/web/core/session/HttpSessionManager.java

@@ -0,0 +1,69 @@
+package org.hsweb.web.core.session;
+
+import org.hsweb.web.bean.po.user.User;
+
+import javax.servlet.http.HttpSession;
+import java.util.Set;
+
+public interface HttpSessionManager {
+
+    /**
+     * 根据登陆用户的ID 获取SessionId
+     *
+     * @param userId 登陆用户id
+     * @return session ID
+     */
+    String getSessionIdByUserId(String userId) ;
+
+    /**
+     * 根据用户ID从session中删除一个用户(下线)
+     *
+     * @param userId 要删除的用户ID
+     */
+    void removeUser(String userId) ;
+
+    /**
+     * 根据sessionId删除Session
+     *
+     * @param sessionId 要删除的sessionID
+     */
+    void removeSession(String sessionId) ;
+
+    /**
+     * 添加一个用户
+     *
+     * @param userId  用户ID
+     * @param session HttpSession
+     */
+    void addUser(String userId, HttpSession session) ;
+
+    Set<User> tryGetAllUser();
+
+    /**
+     * 获取当前登录的所有用户ID集合
+     *
+     * @return 当前登录用户ID
+     */
+    Set<String> getUserIdList() ;
+
+    /**
+     * 获取当前登录用户数量
+     *
+     * @return 登陆用户数量
+     */
+    int getUserTotal() ;
+
+    /**
+     * 获取所有sessionId集合
+     *
+     * @return sessionId集合
+     */
+    Set<String> getSessionIdList() ;
+
+    /**
+     * 根据用户ID 判断用户是否已经登陆
+     *
+     * @param userId 用户ID
+     */
+    boolean isLogin(String userId);
+}

+ 120 - 0
hsweb-web-core/src/main/java/org/hsweb/web/core/session/redis/RedisHttpSessionManager.java

@@ -0,0 +1,120 @@
+package org.hsweb.web.core.session.redis;
+
+import org.hsweb.web.bean.po.user.User;
+import org.hsweb.web.core.session.HttpSessionManager;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.session.ExpiringSession;
+import org.springframework.session.data.redis.RedisOperationsSessionRepository;
+
+import javax.servlet.http.HttpSession;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Created by zhouhao on 16-5-27.
+ */
+public class RedisHttpSessionManager implements HttpSessionManager {
+
+    private RedisTemplate sessionRedisTemplate;
+
+    private RedisOperationsSessionRepository redisOperationsSessionRepository;
+
+    @Override
+    public Set<User> tryGetAllUser() {
+        return (Set<User>) sessionRedisTemplate.execute((RedisCallback<Set<User>>) connection -> {
+            Set<byte[]> keys = connection.keys("spring:session:sessions:*".getBytes());
+            return keys.stream().map(key -> {
+                String sessionId = new String(key).split("[:]")[3];
+                ExpiringSession expiringSession = redisOperationsSessionRepository.getSession(sessionId);
+                return (User) expiringSession.getAttribute("user");
+            }).filter(user -> user != null).collect(Collectors.toSet());
+        });
+    }
+
+    @Override
+    public String getSessionIdByUserId(String userId) {
+        return (String) sessionRedisTemplate.execute((RedisCallback<String>) connection -> {
+            String key = "http.session.user:" + userId;
+            byte[] sessionId = connection.get(key.getBytes());
+            if (sessionId == null) return null;
+            return new String(sessionId);
+        });
+    }
+
+    @Override
+    public void removeUser(String userId) {
+        sessionRedisTemplate.execute((RedisCallback) connection -> {
+            String key = "http.session.user:" + userId;
+            String sessionId = getSessionIdByUserId(userId);
+            removeSession(sessionId);
+            return connection.del(key.getBytes());
+        });
+    }
+
+    @Override
+    public void removeSession(String sessionId) {
+        sessionRedisTemplate.execute((RedisCallback) connection ->
+                        connection.del(("spring:session:sessions:" + sessionId).getBytes())
+        );
+    }
+
+    @Override
+    public void addUser(String userId, HttpSession session) {
+        removeUser(userId);
+        sessionRedisTemplate.execute((RedisCallback) connection -> {
+            String key = "http.session.user:" + userId;
+            String value = session.getId();
+            connection.set(key.getBytes(), value.getBytes());
+            return null;
+        });
+    }
+
+    @Override
+    public Set<String> getUserIdList() {
+        return (Set<String>) sessionRedisTemplate.execute((RedisCallback<Set<String>>) connection -> {
+            Set<byte[]> keys = connection.keys("http.session.user:*".getBytes());
+            return keys.stream().map(key -> {
+                String sessionId = "spring:session:sessions:" + new String(connection.get(key));
+                String userId = new String(key).split("[:]")[1];
+                if (!connection.exists(sessionId.getBytes())) {
+                    removeUser(userId);
+                    return null;
+                }
+                return userId;
+            }).filter(key -> key != null).collect(Collectors.toSet());
+        });
+    }
+
+    @Override
+    public int getUserTotal() {
+        return getUserIdList().size();
+    }
+
+    @Override
+    public Set<String> getSessionIdList() {
+        Set<String> strings = (Set) sessionRedisTemplate.execute((RedisCallback<Set<String>>) connection -> {
+            Set<byte[]> keys = connection.keys("http.session.user:*".getBytes());
+            return keys.stream().map(key -> {
+                String sessionId = new String(connection.get(key));
+                return sessionId;
+            }).collect(Collectors.toSet());
+        });
+        return strings;
+    }
+
+    @Override
+    public boolean isLogin(String userId) {
+        return (Boolean) sessionRedisTemplate.execute((RedisCallback) connection ->
+                        connection.exists(("http.session.user:" + userId).getBytes())
+        );
+    }
+
+    public void setRedisOperationsSessionRepository(RedisOperationsSessionRepository redisOperationsSessionRepository) {
+        this.redisOperationsSessionRepository = redisOperationsSessionRepository;
+    }
+
+    public void setSessionRedisTemplate(RedisTemplate sessionRedisTemplate) {
+        this.sessionRedisTemplate = sessionRedisTemplate;
+    }
+}

+ 32 - 0
hsweb-web-core/src/main/java/org/hsweb/web/core/session/redis/RedisHttpSessionManagerConfiguration.java

@@ -0,0 +1,32 @@
+package org.hsweb.web.core.session.redis;
+
+import org.hsweb.web.core.session.HttpSessionManager;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.session.data.redis.RedisOperationsSessionRepository;
+
+import javax.annotation.Resource;
+
+/**
+ * Created by zhouhao on 16-5-27.
+ */
+@Configuration
+@ConditionalOnBean(value = RedisOperationsSessionRepository.class, name = "sessionRedisTemplate")
+@Order(Ordered.HIGHEST_PRECEDENCE)
+public class RedisHttpSessionManagerConfiguration {
+
+    @Resource(name = "sessionRedisTemplate")
+    RedisTemplate sessionRedisTemplate;
+
+    @Bean
+    public HttpSessionManager sessionListener(RedisOperationsSessionRepository repository) {
+        RedisHttpSessionManager redisHttpSessionManager = new RedisHttpSessionManager();
+        redisHttpSessionManager.setSessionRedisTemplate(sessionRedisTemplate);
+        redisHttpSessionManager.setRedisOperationsSessionRepository(repository);
+        return redisHttpSessionManager;
+    }
+}

+ 100 - 0
hsweb-web-core/src/main/java/org/hsweb/web/core/session/siample/SimpleHttpSessionManager.java

@@ -0,0 +1,100 @@
+package org.hsweb.web.core.session.siample;
+
+import org.hsweb.web.bean.po.user.User;
+import org.hsweb.web.core.session.HttpSessionManager;
+import org.hsweb.web.core.utils.WebUtil;
+
+import javax.servlet.http.HttpSession;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+/**
+ * Created by zhouhao on 16-5-27.
+ */
+public class SimpleHttpSessionManager implements HttpSessionManager {
+
+    /**
+     * httpSession存储器,sessionId:HttpSession
+     */
+    private static final Map<String, HttpSession> sessionStorage = new ConcurrentHashMap<>();
+
+    /**
+     * 用户ID与session管理存储器,userId:HttpSession
+     */
+    private static final Map<String, HttpSession> userSessionStorage = new ConcurrentHashMap<>();
+
+    @Override
+    public Set<User> tryGetAllUser() {
+        return userSessionStorage.values().stream().map(httpSession -> (User) httpSession.getAttribute("user"))
+                .filter(user -> user != null).collect(Collectors.toSet());
+    }
+
+    @Override
+    public String getSessionIdByUserId(String userId) {
+        HttpSession session = userSessionStorage.get(userId);
+        if (session != null) {
+            User user = WebUtil.getLoginUser(session);
+            if (user == null) {
+                userSessionStorage.remove(userId);
+                return null;
+            }
+            return user.getId();
+        }
+        return null;
+    }
+
+    @Override
+    public void removeUser(String userId) {
+        HttpSession session = userSessionStorage.get(userId);
+        if (session != null) {
+            try {
+                session.removeAttribute("user");
+            } catch (Exception e) {
+            } finally {
+                sessionStorage.remove(session.getId());
+                userSessionStorage.remove(userId);
+            }
+        }
+    }
+
+    @Override
+    public void removeSession(String sessionId) {
+        HttpSession session = sessionStorage.get(sessionId);
+        if (session != null) {
+            User user = WebUtil.getLoginUser(session);
+            if (user != null) {
+                userSessionStorage.remove(user.getId());
+            }
+            sessionStorage.remove(sessionId);
+        }
+    }
+
+    @Override
+    public void addUser(String userId, HttpSession session) {
+        sessionStorage.put(session.getId(), session);
+        removeUser(userId);//踢出已经登陆
+        userSessionStorage.put(userId, session);
+    }
+
+    @Override
+    public Set<String> getUserIdList() {
+        return userSessionStorage.keySet();
+    }
+
+    @Override
+    public int getUserTotal() {
+        return userSessionStorage.size();
+    }
+
+    @Override
+    public Set<String> getSessionIdList() {
+        return sessionStorage.keySet();
+    }
+
+    @Override
+    public boolean isLogin(String userId) {
+        return userSessionStorage.containsKey(userId);
+    }
+}

+ 40 - 0
hsweb-web-core/src/main/java/org/hsweb/web/core/session/siample/UserLoginOutListener.java

@@ -0,0 +1,40 @@
+package org.hsweb.web.core.session.siample;
+
+import org.hsweb.web.bean.po.user.User;
+import org.hsweb.web.core.session.HttpSessionManager;
+import org.hsweb.web.core.utils.WebUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+public class UserLoginOutListener implements HttpSessionListener {
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private HttpSessionManager httpSessionManager;
+
+    /* Session创建事件 */
+    public void sessionCreated(HttpSessionEvent se) {
+
+    }
+
+    /* Session失效事件 */
+    public void sessionDestroyed(HttpSessionEvent se) {
+        HttpSession session = se.getSession();
+        try {
+            User user = WebUtil.getLoginUser(session);
+            if (user != null) {
+                httpSessionManager.removeUser(user.getId());
+            }
+            httpSessionManager.removeSession(session.getId());
+        } catch (Exception e) {
+            logger.error("remove session or user error!", e);
+        }
+    }
+
+    public void setHttpSessionManager(HttpSessionManager httpSessionManager) {
+        this.httpSessionManager = httpSessionManager;
+    }
+}