Вызывать метод непосредственно перед истечением сеанса
У моего webapp есть пользователи, которые заходят в систему. Существует тайм-аут. До истечения срока действия сессии я хотел бы выполнить метод для очистки некоторых блокировок.
Я реализовал sessionListener
но как только я дошел до public void sessionDestroyed(HttpSessionEvent event)
сеанс уже ушел, и мне нужны некоторые данные из него, поэтому я хотел бы выполнить метод (который нуждается в сеансе и который сможет получить доступ к FacesConfig.getCurrentInstance()
) до истечения срока действия сеанса.
Как я могу это сделать? Есть идеи? Это мой прослушиватель сеансов:
- Получение контекста сервлетов, сеанса и запроса в внешнем контейнере POJO
- Как загрузить ресурс из файла jar, упакованного в военный файл?
- Показать JDBC ResultSet в HTML на странице JSP с использованием шаблонов MVC и DAO
- Как указать страницу ошибки по умолчанию в web.xml?
- Заполнение выпадающего списка HTML в JSP со значениями, полученными из базы данных в Servlet
public class MySessionListener implements HttpSessionListener { private static final Logger log = LoggerFactory.getLogger(MySessionListener.class); public MySessionListener() { } public void sessionCreated(HttpSessionEvent event) { log.debug("Current Session created : " + event.getSession().getId()+ " at "+ new Date()); } public void sessionDestroyed(HttpSessionEvent event) { // get the destroying session... HttpSession session = event.getSession(); prepareLogoutInfoAndLogoutActiveUser(session); log.debug("Current Session destroyed :" + session.getId()+ " Logging out user..."); /* * nobody can reach user data after this point because * session is invalidated already. * So, get the user data from session and save its * logout information before losing it. * User's redirection to the timeout page will be * handled by the SessionTimeoutFilter. */ // Only if needed } /** * Clean your logout operations. */ public void prepareLogoutInfoAndLogoutActiveUser(HttpSession httpSession) { UserBean user = FacesContext.getCurrentInstance().getApplication().evaluateExpressionGet(FacesContext.getCurrentInstance(), "#{user}", UserBean.class); LockBean lock = FacesContext.getCurrentInstance().getApplication().evaluateExpressionGet(FacesContext.getCurrentInstance(), "#{lock}", LockBean.class); lock.unlock(user.getUsername()); log.info("Unlocked examination for user: "+user.getUsername()); } }
Но я получаю NullPointerException
в FacesContext.getCurrentInstance().getApplication()
потому что либо getCurrentInstance
имеет значение null, либо getApplication
возвращает null
- Управление данными сеанса Webapp / streamом controllerа для нескольких вкладок
- Перенаправление на фактическую страницу, что они просматривали до входа в систему
- ContentCachingResponseWrapper создает пустую реакцию
- Какое сжатие (GZIP - самый популярный) фильтр сервлетов?
- Скрыть скрытые параметры с помощью response.sendRedirect ()
- Как я могу получить компонент Spring в фильтре сервлетов?
- Зависимость от Maven для API Servlet 3.0?
- Сервлет и фильтр
Вы можете добиться этого, выполнив HttpSessionBindingListener, вам нужно зарегистрировать сеанс, который содержит блокировку, вызвав registerSession
(строка «sessionBindingListener» не может быть изменена). Контейнер вызовет метод valueUnbound()
после истечения времени ожидания сеанса и до того, как сеанс будет уничтожен.
public class ObjectLock implements Serializable,HttpSessionBindingListener { public void valueBound(HttpSessionBindingEvent event) { log.info("valueBound:" + event.getName() + " session:" + event.getSession().getId() ); } public void registerSession() { FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put( "sessionBindingListener", this ); log.info( "registered sessionBindingListener" ); } public void valueUnbound(HttpSessionBindingEvent event) { log.info("valueUnBound:" + event.getName() + " session:" + event.getSession().getId() ); // add you unlock code here: clearLocksForSession( event.getSession().getId() ); } }
Еще одно элегантное решение:
Просто добавьте аннотацию @PreDestroy
к Session-Bean! Если сеанс будет уничтожен, он предварительно вызовет PreDestroy на всех SessionBeans, там вы можете выйти и все!
Хотя это в настоящее время не работает со многими ApplicationServers, кажется, это нечеткий сегмент спецификации JSF. Итак, переход с принятым ответом (HttpSessionBindingListener) будет необходим, пока @PreDestroy не будет работать на всех серверах.