DBに依存しないアプローチは、に変数を持たせて(andと)を実装User
することです。このようにして、予期しないクラッシュが発生した後もWebアプリが機能し、DB値が更新されない可能性があります(もちろん、Webアプリの起動時にDBをリセットするを作成することもできますが、それはますます多くの作業になります)。static Map<User, HttpSession>
HttpSessionBindingListener
Object#equals()
Object#hashCode()
ServletContextListener
は次のようにUser
なります。
public class User implements HttpSessionBindingListener {
// All logins.
private static Map<User, HttpSession> logins = new ConcurrentHashMap<>();
// Normal properties.
private Long id;
private String username;
// Etc.. Of course with public getters+setters.
@Override
public boolean equals(Object other) {
return (other instanceof User) && (id != null) ? id.equals(((User) other).id) : (other == this);
}
@Override
public int hashCode() {
return (id != null) ? (this.getClass().hashCode() + id.hashCode()) : super.hashCode();
}
@Override
public void valueBound(HttpSessionBindingEvent event) {
HttpSession session = logins.remove(this);
if (session != null) {
session.invalidate();
}
logins.put(this, event.getSession());
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
logins.remove(this);
}
}
次のようにログインするUser
と:
User user = userDAO.find(username, password);
if (user != null) {
sessionMap.put("user", user);
} else {
// Show error.
}
次に、を呼び出します。これにより、以前にログインしたユーザーがマップvalueBound()
から削除され、セッションが無効になります。logins
ログアウトするUser
と、次のようになります。
sessionMap.remove("user");
または、セッションがタイムアウトにvalueUnbound()
なると、が呼び出され、ユーザーがlogins
マップから削除されます。