在MoFarra中工作时,在MyFaces中重定向后不显示Flash消息

时间:2014-08-07 09:21:06

标签: jsf messages myfaces omnifaces flash-scope

我有自己的ExceptionHandlerWrapper来管理ViewExpiredException和其他错误。

想法是捕获错误,添加一些错误消息并重定向(使用重定向,而不是导航)到索引页面,将显示错误消息。

    fc.getExternalContext().getFlash().setKeepMessages(true);
    Messages.addFlashError(null, "my message");
    Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
    flash.put("foo", "hello");
    fc.getExternalContext().redirect("index.xhtml");

但是,不存储闪存消息(但闪存范围中存在foo)。

这是在mojarra工作,但我移动到myfaces 2.2.4并且它停止了工作。任何的想法?  (也使用omnifaces 1.8.1) 感谢。

2 个答案:

答案 0 :(得分:4)

我查看了MyFaces来源,看来他们明确需要Flash#setRedirect()之上的额外Flash#setKeepMessages()来电。尽管Javadoc对此并不是很清楚,但我希望调用setRedirect(true)只是Flash属性所必需的,而不是Flash消息,它有自己的setKeepMessages(true)调用。

所以,基本上,你应该这样做:

fc.getExternalContext().getFlash().setKeepMessages(true);
Messages.addFlashError(null, "my message");
Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
flash.put("foo", "hello");
fc.getExternalContext().getFlash().setRedirect(true); // <-- Add this.
fc.getExternalContext().redirect("index.xhtml");

但是,因为您已经在使用JSF实用程序库OmniFaces,它在使用Messages#addFlashXxx()方法时已隐式调用setKeepMessages(true),并且还隐式调用setRedirect(true)当你使用Faces#redirect()方法时,你可以使用下面的内容与上面的内容完全相同&#34; mess&#34;:

Messages.addFlashGlobalError("my message");
Faces.setFlashAttribute("foo", "hello");
Faces.redirect("index.xhtml");

无需自定义阶段监听器。

答案 1 :(得分:0)

我已经使用PhaseListener临时解决了这个问题。我不喜欢它,但它现在有效

我所做的是,每当我添加一条flash消息时,我也会把它放在flash范围内:

     Messages.addFlash(null, new FacesMessage(severity, summary, detail));

    context.getExternalContext().getFlash().put("messages", context.getMessageList());

然后我在phaseListener中恢复它们

public void beforePhase(final PhaseEvent event) {
    FacesContext facesContext = event.getFacesContext();

    if (PhaseId.RENDER_RESPONSE.equals(event.getPhaseId())) {
        if (!facesContext.getResponseComplete()) {
            this.restoreMessages(facesContext);
        }
    }
}
private int restoreMessages(final FacesContext facesContext) {
    final Object flash = facesContext.getExternalContext().getFlash().get("messages");
    if (flash != null) {
        List<FacesMessage> messages = (List<FacesMessage>) flash;


        int restoredCount = messages.size();
        for (Object element : messages) {
            facesContext.addMessage(null, (FacesMessage) element);
        }
        return restoredCount;
    }
    return 0;
}