从f:phaselistener重定向后不显示flash消息

时间:2013-02-06 16:09:33

标签: jsf-2 phaselistener flash-scope

我有一个问题,就是了解flash在jsf生命周期中是如何工作的。

我正在尝试通过正常的get请求重定向到阶段侦听器的不同页面,同时添加一条flash消息(当然我设置了flah.keepmessage)以显示在新页面上。但是这条消息没有显示出来。我知道有些事情是错误的,如果有人能帮助实施更好的方法(请不要过滤器),我将不胜感激。

phaseredirect1.html

    <h:body>
    <f:view>
        <f:phaseListener binding="#{testphase.testPL}"/>
        <div>Testing Phases Redirect 1</div>
    </f:view>
    </h:body>

TestPhaseRedirect.java

   @SessionScoped
   @ManagedBean(name="testphase")
   public class TestPhaseRedirect {
   private PhaseListener testPL;

   @PostConstruct
   private void initializeVar(){
    testPL = new PhaseListener() {
        @Override
        public void afterPhase(PhaseEvent event) {
        }
        @Override
        public void beforePhase(PhaseEvent event) {
            getFacesContext().addMessage(null, new FacesMessage("Faces Message: redirecting to page 2..."));
            getExternalContext().getFlash().setKeepMessages(true);
            ConfigurableNavigationHandler nav = (ConfigurableNavigationHandler)getFacesContext().getApplication().getNavigationHandler();
            nav.performNavigation("redirect-to-page2");
            getFacesContext().responseComplete();
            return;
        }
        @Override
        public PhaseId getPhaseId() {
            return PhaseId.RENDER_RESPONSE;
        }
    };
}    
public PhaseListener getTestPL() {
    return testPL;
}
}

phaseredirect2.html

    <h:body>
    <f:view>
        <div style="width:400px;">
            <p:messages autoUpdate="true" closable="true"/>
            <p>Testing Phases Redirect 2</p>
            <p> Did it display the message? </p>
        </div>
    </f:view>
    </h:body>

面临配置

    <navigation-case>
        <from-outcome>redirect-to-page2</from-outcome>
        <to-view-id>/phaseredirect2.html</to-view-id>
        <redirect />
    </navigation-case>

请指正。 非常感谢你。

1 个答案:

答案 0 :(得分:1)

在渲染响应阶段,创建闪存范围为时已晚。您需要在调用应用程序阶段最迟执行此操作。基本上,这个问题与<f:event type="preRenderView">中的问题具有相同的理由,如以下相关问题中已经回答的那样:

在您的特定情况下,您需要一个虚拟视图参数,以便触发调用操作阶段,然后使用<f:event type="postInvokeAction">(在您自己创建自定义事件或根据abovelinked上的答案安装OmniFaces之后)题):

<f:metadata>
    <f:viewParam name="dummy" />
    <f:event type="postInvokeAction" listener="#{bean.init}" />
</f:metadata>

public void init() {
    FacesContext context = FacesContext.getCurrentInstance();
    context.addMessage(null, new FacesMessage("Faces Message: redirecting to page 2..."));
    context.getExternalContext().getFlash().setKeepMessages(true);
    ConfigurableNavigationHandler nav = (ConfigurableNavigationHandler)  context.getApplication().getNavigationHandler();
    nav.performNavigation("redirect-to-page2");
}

或者如果你选择了OmniFaces

public void init() {
    Messages.addFlashGlobalInfo("Faces Message: redirecting to page 2...");
    Faces.navigate("redirect-to-page2");
}