我正在使用阶段监听器来管理登录和会话范围等事情。在某些情况下,我想重定向。最明显的是当用户未登录并且他们试图访问受保护的页面时。
目前,我的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之前使我的过滤器发生的。
由于 - 理查德
答案 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();
表示viewRoot
为null
。如果在该点之前调用FacesContext#responseComplete()
,则可能会发生这种情况,而ExternalContext#rediect()
则隐含地执行此操作。在Mojarra 2.1之后,添加了viewRoot
上的空检查,修复了这个错误。
所以,升级到至少Mojarra 2.1。它目前已经是2.1.4。
关于你(无关)的说明:
我可以使用的一个选项是使用Servlet过滤器来完成这项工作。它还将涵盖非JSF请求。在这种情况下,我不知道有多少JSF可用(以及我实际需要多少),并且我不清楚我是如何在ConversationPropagationFilter之后和PrettyFilter之前使我的过滤器发生的。 < / p>
JSF将托管bean和许多其他信息存储为HttpSession
和ServletContext
的属性,所有这些都可以在Filter
中找到。所以这应该是可行的。至于过滤器调用顺序;这只能由<filter-mapping>
中的web.xml
订单控制。