我按照下面的文章处理ViewExpiredException -
JSF2中ViewExpiredException的优雅处理
它做它应该做的事。但我想有一些FacesMessage显示在视图上,如果用户被重定向到它由于ViewExpiredException。因此,我在使用nhh .handlenaviage()重定向之前添加了一个FacesMessage。但是它没有工作,原因是FacesMessage只存活了一个请求处理周期。
起初,我的解决方案是将消息保存在会话中,并在下一个周期的Restore View阶段之前检索它。
即使它工作,我开始寻找一些标准的解决方案,我遇到的第一件事是下面的文章-
在多个页面重定向中持久化并传递FacesMessages
但它没有工作。我认为这是因为phaselistener在ExceptionHandlers之前执行。所以,在这种情况下,它是无用的。我认为,如果异常处理代码在侦听器的afterPhase代码之前执行,那将是有用的。
然后我遇到了下面的线程-
在重定向后保留FacesMessage以在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未显示在子目录
有谁能帮我解决这个问题吗?我正在寻找一些JSF(如果不是标准的,那么一个好的)方法来处理这个问题。谢谢。
但我还是想听听你是如何处理这个问题的
但以下是我目前所做的-
我刚刚参加了文章中的类-坚持并通过多个页面重定向传递FacesMessages并将saveMessages()
和restoreMessages()
方法从MultiPageMessagesSupport
相位侦听器移动到实用程序类(作为静态方法)。在faces上下文中保存faces消息后,只需从页面侦听器调用这些方法,并从ViewExpiredExceptionHandler
调用这些方法(saveMessages()
方法)。