2

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

目前我的 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 之前使我的过滤器发生。

谢谢 - 理查德

4

1 回答 1

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

这是一个旧错误,已在 Mojarra 2.1 中修复。RestoreViewPhase#notifyAfter()例如 Mojarra 2.0.2的方法的来源如下:

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添加了一个 nullcheck on 来修复这个错误。

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


至于您的(不相关的)注释:

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

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

于 2011-11-11T19:00:44.153 回答