Я не уверен. Кажется, это работает нормально для одного посетителя. Но некоторые вещи определенно не выглядят правильно в вашем HttpSessionListener
.
@ManagedBean
public class SessionEar implements HttpSessionListener {
Почему это @ManagedBean
? Нет смысла, убери это. В Java EE 6 вместо этого вы бы использовали @WebListener
.
BufferedWriter output = null;
Это определенно не должно быть переменной экземпляра. Это не потокобезопасно. Объявите это методом локально. Для каждой реализации HttpSessionListener
существует только один экземпляр в течение всего времени жизни приложения. При одновременном создании / удалении сеанса ваш output
будет перезаписан другим, когда он занят, и ваш файл будет поврежден.
public static long creationTime = 0;
public static int remTime = 0;
Они также не должны быть переменной экземпляра. Каждое новое создание сеанса будет переопределять его, и это будет отражено в презентации всех других пользователей. То есть это не потокобезопасно. Избавьтесь от них и используйте #{session.creationTime}
и #{session.maxInactiveInterval}
в EL, если вам нужно получить его там по какой-то причине. Или просто получите его прямо из экземпляра HttpSession
в HTTP-запросе.
if (hse.getSession().isNew()) {
Это всегда true внутри sessionCreated()
метода. Это не имеет никакого смысла. Удалить его.
JsfUtil.addErrorMessage(ex, "Cannot append session Info to File");
Я не знаю, что именно делает этот метод, но я просто хочу предупредить, что нет гарантии , что FacesContext
присутствует в потоке, когда собирается создать сеанс или уничтожен. Это может иметь место в запросе не-JSF. Или может не быть никаких средств для HTTP-запроса вообще. Таким образом, вы рискуете NPE, потому что FacesContext
равно null
тогда.
Тем не менее, я создал следующий тестовый фрагмент, и он отлично работает для меня. Бин @SessionScoped
неявно создает сеанс. Кнопка команды делает сеанс недействительным. Все методы вызываются как и ожидалось. Сколько раз вы также нажимаете кнопку на той же вкладке браузера, счетчик всегда равен 1.
<h:form>
<h:commandButton value="logout" action="#{bean.logout}" />
<h:outputText value="#{bean.sessionCount}" />
</h:form>
* * С тысячей сорок-девять
@ManagedBean
@SessionScoped
public class Bean implements Serializable {
public void logout() {
System.out.println("logout action invoked");
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
}
public int getSessionCount() {
System.out.println("session count getter invoked");
return SessionCounter.getCount();
}
}
и
@WebListener
public class SessionCounter implements HttpSessionListener {
private static int count;
@Override
public void sessionCreated(HttpSessionEvent event) {
System.out.println("session created: " + event.getSession().getId());
count++;
}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
System.out.println("session destroyed: " + event.getSession().getId());
count--;
}
public static int getCount() {
return count;
}
}
(обратите внимание, что в Java EE 5 необходимо зарегистрировать его как <listener>
в web.xml
обычным способом)
<listener>
<listener-class>com.example.SessionCounter</listener-class>
</listener>
Если приведенный выше пример работает для вас, то, скорее всего, ваша проблема лежит в другом месте. Возможно, вы вообще не зарегистрировали его как <listener>
в web.xml
, и вы просто вручную создаете новый экземпляр слушателя каждый раз в каком-либо методе входа в систему. Как бы то ни было, теперь у вас есть хотя бы минимальный стартовый пример для дальнейшего развития.