2

RDBMS (MySQL) を Spark Framework ( http://sparkjava.com/で入手可能な Java マイクロ Web フレームワーク) のセッション ストアとして構成するにはどうすればよいですか?

これを尋ねる理由は、Spark が実行されている jetty を再起動する必要がある場合でも、ユーザー セッションを有効のままにしておきたいからです。

4

2 に答える 2

2

実際には、セッションをデータベースに保存するオプションがあります。私は Ebean ORM を使用していますが、純粋な SQL だけでなく、他の ORM でも実行できます。

User クラスと UserSession クラスがあるとします。

あなたがすべきことは、アクティブなセッションがあるかどうかを確認することです. すでに存在し、ユーザーがバインドされていない場合 — 認証に渡します。存在しない場合 — JSESSIONIDCookie が存在し、UserSession テーブルにレコードがあるかどうかを確認します。そのようなセッションがある場合は、ユーザーを取得し、新しいセッションを作成してユーザーをそれにバインドします。

以下の 2 つのクラス リストは、一目瞭然です。User.getAuthenticatedUser()誰かが認証済みユーザーの URI にアクセスしようとするたびに呼び出します。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();
    }
}
于 2015-12-25T18:56:12.833 に答える
1

spark セッション API は、サーブレット HttpSession オブジェクトのラッパーです。セッション ストレージ用にデータベースを構成するオプションはありません。セッションの保存方法は、サーブレット コンテナーによって異なります。

于 2015-03-22T22:12:16.537 に答える