为什么jsf生命周期会在重定向页面后调用应用程序后跳过渲染响应?

时间:2014-07-03 07:26:31

标签: jsf jsf-2 navigation facescontext

我有两个场景
我有两个在bean中具有逻辑的动作 我的按钮

<h:commandButton  value="Submit" action="#{bean.test}" />
<h:commandButton  value="Submit" action="#{bean.testOne}" />

这是两个commnadButtons,bean中有逻辑

public void test() {
    log.info("I m in test");
}

public void testOne() {
    log.info("I m in testOne");
    try {
        FacesContext.getCurrentInstance()
            .addMessage("", new FacesMessage("Record Saved successfully."));
        FacesContext
                .getCurrentInstance()
                .getExternalContext()
                .redirect(
                        FacesContext.getCurrentInstance()
                            .getExternalContext().getRequestContextPath()
                                + "/cycle/page");

    } catch (IOException e) {
        log.error(e.getMessage());
    }
}

当我要点击第一个按钮(测试动作)时,jsf生命周期进入每个阶段,如
恢复视图
应用请求值
过程验证
更新模型
调用应用程序
渲染响应
但是当我点击testOne按钮时jsf生命周期跳过渲染响应后调用应用程序如恢复视图
应用请求值
进程验证
更新模型
调用应用程序
恢复视图
渲染响应

用简单的语言当我通过facesContext导航页面时jsf跳过那个阶段 但为什么会这样呢?我没有遇到问题。

1 个答案:

答案 0 :(得分:3)

根据JSF文档,这就是 INVOKE_APPLICATION 阶段的作用:

  

在此阶段,JavaServer Faces实现处理任何应用程序级事件,例如提交表单或链接到另一个页面。

     

此时,如果应用程序需要重定向到其他Web应用程序资源或生成不包含任何JavaServer Faces组件的响应,则可以调用FacesContext.responseComplete方法。

     

如果正在处理的视图是从先前请求的状态信息重建的,并且组件触发了事件,则会将这些事件广播给感兴趣的听众。

     

最后,JavaServer Faces实现将控制转移到渲染响应阶段。

您正在做的是在此阶段调用FacesContext#getCurrentInstance#getExternalContext#redirect,执行重定向。此方法触发FacesContext#getCurrentInstance#responseComplete,结束JSF生命周期。重定向是在JSF视图中执行的,因此在此之后开始新的循环。

除此之外,与具体问题无关,如果要重定向到内部JSF视图,请不要执行此类重定向。只需在操作方法中返回导航案例+ ?faces-redirect=true(即/cycle/page?faces-redirect=true)。仅当您要访问外部URL时才使用外部上下文。

另见: