【问题标题】:Spark micro framework - save sessions in database?Spark微框架 - 在数据库中保存会话?
【发布时间】:2015-12-26 02:56:12
【问题描述】:

如何将 RDBMS (MySQL) 配置为 Spark 框架(http://sparkjava.com/ 提供的 Java 微型 Web 框架)的会话存储?

我问这个的原因是,如果 Spark 运行的码头必须重新启动,我希望用户会话保持有效。

【问题讨论】:

    标签: java database session spark-java


    【解决方案1】:

    实际上有一个选项可以将会话存储在数据库中。我使用 Ebean ORM,但您可以使用任何其他 ORM 以及纯 SQL 来完成。

    假设我们有 User 类和 UserSession 类。

    您应该检查是否存在活动会话。如果它已经存在并且没有用户绑定 - 我们传递到身份验证。如果它不存在——我们检查JSESSIONID cookie 是否存在并且在 UserSession 表中有记录。如果有这样的会话,我们检索用户,创建新会话并将用户绑定到它。

    下面的两个类列表非常不言自明。每次有人尝试访问经过身份验证的用户的 URI 时,请致电 User.getAuthenticatedUser()。在成功登录尝试时调用User.addAuthenticatedUser(req, user)

    用户类别:

    @Data
    @Entity
    @Table(name = "users")
    public class User {
        private static final String USER_SESSION_ID = "sessionId";
    
        @Id
        Long id;
    
        String login;
        String password;
        String email;
    
        Integer role;
    
        public static User authUser(User user) {
            return Ebean.find(User.class).where()
                    .eq("login", user.login)
                    .eq("password", user.password)
                    .findUnique();
        }
    
        public static void addAuthenticatedUser(Request req, User u) {
            Session session = req.session();
            Ebean.save(new UserSession(u, session.id()));
            req.session().attribute(USER_SESSION_ID, u);
        }
    
        public static User getAuthenticatedUser(Request req, Response res) {
            User user = null;
            Session session = req.session(false);
            if (session == null) {
                UserSession userSession = UserSession.getSession(req.cookies().get("JSESSIONID"));
                if (userSession != null) {
                    user = userSession.getUser();
                    userSession.delete();
                    addAuthenticatedUser(req, user);
                }
            } else {
                user = session.attribute(USER_SESSION_ID);
            }
    
            // Redirect to login form
            if (user == null) {
                res.redirect("/login");
                halt();
            }
            return user;
        }
    }
    

    UserSession 类:

    @Data
    @Entity
    @Table(name = "sessions")
    public class UserSession {
    
        @ManyToOne(fetch = EAGER)
        @JoinColumn(name = "uid")
        private User user;
        private String session;
        private Timestamp taken;
    
        public UserSession(User u, String sessionId) {
            user = u;
            session = sessionId;
            taken = new Timestamp(System.currentTimeMillis());
        }
    
        public static UserSession getSession(String session) {
            return Ebean.find(UserSession.class).where().eq("session", session).findUnique();
        }
    
        public void delete() {
            SqlUpdate deleteQuery = Ebean.createSqlUpdate("DELETE FROM sessions WHERE uid = :uid AND session = :session");
            deleteQuery.setParameter("uid", user.id);
            deleteQuery.setParameter("session", session);
            deleteQuery.execute();
        }
    }
    

    【讨论】:

      【解决方案2】:

      spark session API 是 servlet HttpSession 对象的包装器。没有为会话存储配置数据库的选项。会话的存储方式取决于 servlet 容器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-06-10
        • 1970-01-01
        • 2014-05-27
        • 2012-08-19
        • 1970-01-01
        • 1970-01-01
        • 2012-02-28
        相关资源
        最近更新 更多