JSF2 Отправка перенаправления из фазы просмотра перед восстановлением - исключение NullPointerException в com.sun.faces? - PullRequest
2 голосов
/ 11 ноября 2011

Я использую фазовый приемник для управления такими вещами, как вход в систему и область разговора. В некоторых ситуациях я хочу перенаправить. Наиболее очевидным является случай, когда пользователь не вошел в систему и пытается получить доступ к защищенной странице.

В настоящее время мой PhaseListener работает после представления восстановления. Это иногда слишком поздно. Когда пользователь выходит из системы, страница удаляется и перенаправляется обратно на страницу входа. Это удаление страницы вызывает некоторые события AJAX в IceFaces - только я уничтожил сессию, поэтому бины не имеют состояния. Это вызывает исключения во время представления восстановления, которое, по-видимому, обращается к компоненту поддержки через EL на странице.

Если я перевожу свой слушатель фазы в представление «Перед восстановлением» и попытаюсь перенаправить с использованием ExternalContext, я получаю исключение NullPointerException.

java.lang.NullPointerException
com.sun.faces.lifecycle.RestoreViewPhase.notifyAfter(RestoreViewPhase.java:301)
com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:114)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:67)
com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:118)

Одним из вариантов, который я мог бы использовать, было бы использование фильтра Servlet для этой работы. Он также будет охватывать запросы не из JSF. Я не знаю, сколько JSF будет доступно (и сколько мне на самом деле нужно) в этом случае, и не сразу понятно, как я могу заставить свой фильтр произойти после таких вещей, как ConversationPropagationFilter и перед PrettyFilter.

Спасибо - Ричард

1 Ответ

2 голосов
/ 11 ноября 2011
java.lang.NullPointerException
  com.sun.faces.lifecycle.RestoreViewPhase.notifyAfter(RestoreViewPhase.java:301)

Это старая ошибка , которая уже исправлена ​​в Mojarra 2.1. Источник RestoreViewPhase#notifyAfter() метода, например, Мохарры 2.0.2, говорит следующее:

299  private void notifyAfter(FacesContext context, Lifecycle lifecycle) {
300      UIViewRoot viewRoot = context.getViewRoot();
301      MethodExpression afterPhase = viewRoot.getAfterPhaseListener();

, что означает, что viewRoot равно null. Это может произойти, если FacesContext#responseComplete() был вызван до этой точки, что, в свою очередь, неявно выполняется ExternalContext#rediect(). После Mojarra 2.1 добавлена ​​нулевая проверка на viewRoot, которая исправляет эту ошибку.

Итак, обновите версию хотя бы до Мохарры 2.1. В настоящее время он уже на 2.1.4.


Относительно вашей (не связанной) заметки:

Одним из вариантов, который я мог бы использовать, было бы использование фильтра Servlet для этой работы. Он также будет охватывать запросы не из JSF. Я не знаю, сколько JSF будет доступно (и сколько мне на самом деле нужно) в этом случае, и не сразу понятно, как я могу заставить свой фильтр произойти после таких вещей, как ConversationPropagationFilter и перед PrettyFilter.

JSF хранит управляемые bean-компоненты и много другой информации в виде атрибутов HttpSession и ServletContext, которые доступны в Filter. Так что это должно быть выполнимо. Что касается порядка вызова фильтра; это просто управляется порядком <filter-mapping> в web.xml.

...