Если пользователь закроет браузер без выхода из системы.
В частности, этот случай трудно и ненадежно обнаружить. Вы можете использовать событие beforeunload
в Javascript, но вы полностью зависите от того, поддерживает ли JS браузер и поддерживает ли этот браузер это нестандартное событие (например, Opera не поддерживает). Это также одна из основных причин, по которой я бы предложил выйти из системы ранее вошедшего в систему пользователя, а не предотвращать вход в систему. Это также более удобно и безопасно для случая, когда пользователь «забыл» выйти из системы с другого компьютера.
Самый простой способ - позволить User
иметь переменную static Map<User, HttpSession>
и позволить ему реализовать HttpSessionBindingListener
(и Object#equals()
и Object#hashCode()
). * * тысячу двадцать-один
public class User implements HttpSessionBindingListener {
// All logins.
private static Map<User, HttpSession> logins = new HashMap<User, HttpSession>();
// 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) {
request.getSession.setAttribute("user", user);
} else {
// Show error.
}
затем он вызовет valueBound()
, который удалит любого ранее вошедшего в систему пользователя с карты logins
и сделает сеанс недействительным.
Когда вы выходите из системы User
следующим образом:
request.getSession().removeAttribute("user");
или по истечении времени ожидания сеанса будет вызван valueUnbound()
, который удалит пользователя из карты logins
.