3

我有两个场景
我有两个动作,它们在 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 会跳过该阶段。
但是为什么会这样呢?我没有得到问题。

4

1 回答 1

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 时才使用外部上下文。

也可以看看:

于 2014-07-03T10:10:22.270 回答