3

我有自己的 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)谢谢。

4

2 回答 2

4

我查看了 MyFaces 源代码,似乎他们明确需要Flash#setRedirect()Flash#setKeepMessages(). 尽管 Javadoc 对此并不十分清楚,但我希望调用setRedirect(true)仅对 Flash 属性是必需的,而不是对于有自己setKeepMessages(true)调用的 Flash 消息。

因此,基本上,您应该执行以下操作:

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 实用程序库OmniFacessetKeepMessages(true) ,它在您使用方法时已经隐式调用,并且在您使用Messages#addFlashXxx()方法时也隐式调用,您可以摆脱与上述“混乱”完全相同的以下内容:setRedirect(true)Faces#redirect()

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

不需要自定义阶段侦听器。

于 2014-08-09T14:18:27.600 回答
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;
}
于 2014-08-07T10:01:24.050 回答