我按照以下文章来处理ViewExpiredException -
Dealing Gracefully with ViewExpiredException in JSF2
它做它应该做的事情。但是如果用户由于ViewExpiredException被重定向到它,我希望在视图上显示一些FacesMessage。所以,我在使用NH.handlenaviage()重定向之前添加了一个FacesMessage。但它没有用,原因是FacesMessage只存活了一个请求处理周期。
首先,我的解决方案是将消息保存在会话中,并在下一个周期的恢复视图阶段之前检索它。
即使它有效,我也开始寻找一些标准解决方案,而我遇到的第一件事就是以下文章 -
Persist and pass FacesMessages over multiple page redirects
但它没有用。我认为这是因为PhaseListeners在ExceptionHandlers之前执行。所以,在这种情况下,它是无用的。我认为如果在侦听器的afterPhase代码之前执行异常处理代码会很有用。
然后我遇到了以下帖子 -
Preserving FacesMessage after redirect for presentation through in JSF
以下就是我现在所拥有的 -
@Override
public void handle() throws FacesException {
Iterator<ExceptionQueuedEvent> i = this.getUnhandledExceptionQueuedEvents().iterator();
while (i.hasNext()) {
ExceptionQueuedEvent event = i.next();
ExceptionQueuedEventContext eventContext = (ExceptionQueuedEventContext) event.getSource();
Throwable throwable = eventContext.getException();
if (throwable instanceof ViewExpiredException) {
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.getExternalContext().getFlash().setKeepMessages(true);
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Your session expired!", null));
NavigationHandler nv = facesContext.getApplication().getNavigationHandler();
try {
facesContext.getViewRoot().setViewId("/login");
nv.handleNavigation(facesContext, null, "/login?faces-redirect=true");
facesContext.renderResponse();
} finally {
i.remove();
}
}
}
this.getWrapped().handle();
}
它解决了这个问题,但只针对同一目录中的视图。
以下是我对Flash范围进行一些研究后得到的结果 -
FacesMessage not displayed on page in subdirectory
有人可以帮我这个吗?我正在寻找一些处理这个问题的JSF(如果不是标准那么好)。
谢谢。
答案 0 :(得分:0)
虽然我仍然想知道你(将)如何解决这个问题。
但以下是我到目前为止所做的事情 -
我刚刚参加了文章中的课程 - Persist and pass FacesMessages over multiple page redirects
并将saveMessages()
和restoreMessages()
方法从MultiPageMessagesSupport
阶段侦听器移动到实用程序类(作为静态方法)。在面部上下文中保存faces消息后,只需从pase侦听器调用那些方法,并从saveMessages()
方法调用ViewExpiredExceptionHandler
方法。
这可以解决问题,但最好有一些标准解决方案。