JSF2从还原前视图阶段发送重定向 - com.sun.faces中的NullPointerException?

时间:2011-11-11 18:20:17

标签: jsf-2 jboss7.x

我正在使用阶段监听器来管理登录和会话范围等事情。在某些情况下,我想重定向。最明显的是当用户未登录并且他们试图访问受保护的页面时。

目前,我的PhaseListener在还原视图后运行。这有时为时已晚。当用户注销时,页面被丢弃并被重定向回登录页面。该页面处理导致IceFaces中的一些AJAX事件 - 只有我已经破坏了会话,因此bean缺少状态。这会在还原视图期间导致异常,这似乎是通过页面中的EL访问辅助bean。

如果我将我的阶段监听器移动到还原视图之前并尝试使用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 个答案:

答案 0 :(得分:2)

java.lang.NullPointerException
  com.sun.faces.lifecycle.RestoreViewPhase.notifyAfter(RestoreViewPhase.java:301)

这是old bug已经在Mojarra 2.1中修复过。例如Mojarra 2.0.2的RestoreViewPhase#notifyAfter()方法的来源如下:

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

表示viewRootnull。如果在该点之前调用FacesContext#responseComplete(),则可能会发生这种情况,而ExternalContext#rediect()则隐含地执行此操作。在Mojarra 2.1之后,添加了viewRoot上的空检查,修复了这个错误。

所以,升级到至少Mojarra 2.1。它目前已经是2.1.4。


关于你(无关)的说明:

  

我可以使用的一个选项是使用Servlet过滤器来完成这项工作。它还将涵盖非JSF请求。在这种情况下,我不知道有多少JSF可用(以及我实际需要多少),并且我不清楚我是如何在ConversationPropagationFilter之后和PrettyFilter之前使我的过滤器发生的。 < / p>

JSF将托管bean和许多其他信息存储为HttpSessionServletContext的属性,所有这些都可以在Filter中找到。所以这应该是可行的。至于过滤器调用顺序;这只能由<filter-mapping>中的web.xml订单控制。