Ошибка StackOverflow при инициализации компонента JSF SessionScoped в HttpSessionListener - PullRequest
0 голосов
/ 01 ноября 2011

Продолжая мой предыдущий вопрос , я пытаюсь инициализировать JSF-компонент в рамках сеанса при первом запуске сеанса приложения, поэтому бин будет доступен пользователю независимо от того, к какой странице он обращается сначала в моем веб-приложении. Мой пользовательский слушатель:

public class MyHttpSessionListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        if (FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
                .get("mySessionBean") == null) {
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
                    .put("mySessionBean", new MySessionBean());
        }
    }
}

Однако это приводит к ошибке переполнения стека. Похоже, что метод put() в классе SessionMap пытается создать новый HttpSession, вызывая бесконечный цикл с моим слушателем. Как я могу инициализировать bean-объект JSF в области сеанса при первом запуске сеанса моего приложения, не сталкиваясь с этой проблемой?

Я использую JSF 2 с Spring 3, работаю в WebSphere 7.

Спасибо!

1 Ответ

2 голосов
/ 01 ноября 2011

На этом этапе сессия еще не полностью завершена. Только когда метод слушателя завершается, сеанс помещается в контекст и доступен request.getSession(), так как getSessionMap() JSF используется под прикрытием.

Вместо этого вы должны извлечь сеанс из аргумента event и использовать его метод setAttribute(). JSF просто ищет и сохраняет управляемые bean-объекты сессионной области и не будет создавать новый, если он уже есть.

public void sessionCreated(HttpSessionEvent event) {
    event.getSession().setAttribute("mySessionBean", new MySessionBean());
}

Обратите внимание, что я удалил лишнюю проверку нуля, так как в этот момент невозможно , что сессионный компонент уже существует.


Не связанный с конкретной проблемой, вы фактически никогда не должны полагаться на то, что FacesContext присутствует в реализации, которая не управляется JSF. Вполне возможно, что сеанс может быть создан во время не-JSF-запроса.

...