【问题标题】:How do you use JSF implicit redirection with POST parameters如何使用带有 POST 参数的 JSF 隐式重定向
【发布时间】:2012-12-12 19:08:38
【问题描述】:

在我的 JSF 应用程序中,我有两个页面,list.jsfdetails.jsf,每个页面都有自己的具有视图范围的控制器。在list.jsf 我有一个<h:commandLink> 调用一个动作并传递一个参数:

<h:commandLink value="details" action="#{listBean.goToDetails}" >
   <f:param  name="id" value="#{listBean.object.pk}"/></h:commandLink>

这是bean方法:

@ManagedBean
@ViewScoped
public class ListBean {
    public String goToDetails() {
        // some code
        return "details?faces-redirect=true";
    }
}

我这样读取第二个 bean 中的参数:

Map<String, String> params = FacesContext.getCurrentInstance()
                .getExternalContext().getRequestParameterMap();
        this.setIdParam(params.get("id"));

当我运行这段代码时,参数没有传递给第二个 bean 实例。 但是,当我将导航更改为forward(没有faces-redirect=true)时,参数已传递,我可以在details.jsf 中看到详细信息,但URL 与当前页面不匹配。

所以我想做的是使用带有 POST 参数(f:param)的“jsf 隐式重定向”(不是转发)。

【问题讨论】:

  • 很好奇; goToDetails 中的“一些代码”由什么组成?从方法的名称和您描述的用例来看,很难想象它可能会做什么。如果它确实在做一些有用的事情,eljunior 的答案是最好的(但用简单的结果替换语句),否则 arjan tijms 的答案更好。

标签: jsf post parameters


【解决方案1】:

您不能使用 POST 重定向。

当您使用faces-redirect=true 时,您正在使用HTTP redirect,发生的情况是:服务器向浏览器发送带有重定向URL 的HTTP 302 响应,然后浏览器对该URL 执行GET 请求。

您可以做的是重定向到通过 GET 发送 id 参数的 URL,如下所示:

public void goToDetails(){
    // some code
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext()
    String id = object.getPk().toString();
    ec.redirect(ec.getRequestContextPath() + "/details.jsf?id=" + id);
}

您可能希望为这类事情创建一个 util 方法,例如 Faces#redirect()OmniFaces library

更新: 如 cmets 所述,也可以在返回字符串中添加 id:

public String goToDetails(){
    // some code
    String id = object.getPk().toString();
    return "details?faces-redirect=true&id=" + id;
}

【讨论】:

  • 我真的很抱歉投了反对票。您答案的第一部分非常好,但我觉得第二部分不是最佳的。你现在建议做一个 PRG,而这里只需要一个 get。即使需要 PRG,您也可以使用重定向指令 参数返回结果。例如 return "details.jsf?faces-redirect=true&id=" + id;但是如果你不需要PRG,直接链接就行了。这对性能更好,并且可以为直接链接添加书签、预先检查等。
  • @MikeBraun 我同意一个简单的链接要好得多,只是 OP 的代码中有一条评论说 // some code 在那里暗示有更多的东西。否则,我完全同意最好有链接。
  • 是的,你是对的。根据“某些代码”的作用,确实需要 PRG 模式,但是您可以使用带有参数的结果字符串,而不是以编程方式设置重定向。我很好奇什么是“一些代码”。对于从列表链接到详细信息视图,我觉得这也不需要,但当然只有 OP 知道这一点;)
  • 是的,我不知道您可以在返回字符串中添加 URL 参数。现在刚刚完成测试,并且学到了一些新东西! :) 谢谢
【解决方案2】:

如果list.jsf 后面的backing bean 不需要做任何处理(从示例中它看起来不像),您应该通过GET 请求直接链接到details.jsf

您可以为此使用&lt;h:link&gt; 标签,如下所示:

<h:link value="details" outcome="details.jsf" >
    <f:param  name="id" value="#{listBean.object.pk}"/>
</h:link>

在您的详细信息视图中,您可以声明该视图使用 GET 参数并将其直接绑定到该视图的支持 bean:

<f:metadata>
    <f:viewParam name="id" value="#{detailsBean.id}" />
</f:metadata>

此外,您可以直接验证和/或转换该参数,因此您的detailsBean 将获得正确类型的 Object 而不是基于字符串的 id。如果你需要在 GET 参数注入后在detailsBean 中做任何后处理,可以使用preRenderView 事件:

<f:metadata>
    <f:viewParam name="id" value="#{detailsBean.id}" />
    <f:event type="preRenderView" listener="#{detailsBean.preRenderView()}" />
</f:metadata>

工作示例:

另见:

【讨论】:

  • 这种方法确实更好,虽然 OP 的代码确实有注释暗示 action 方法中有更多代码。
  • 感谢您的回复,它非常有用,但在我的情况下,我必须使用带有操作的命令按钮。
  • @Achraf 你也知道为什么你需要一个命令按钮吗?如果你只想渲染一个按钮,那么你也可以使用 h:button。这将触发一个 get 请求,就像 h:link 一样。除了重定向之外,您的操作还做了哪些特别的事情? (只是好奇并帮助其他人选择哪种方法)。谢谢!
  • 感谢@MikeBraun 的干预。在我的情况下,该操作在重定向之前执行一些代码。说明:我有多个详细信息视图(details1.jsf、details2.jsf...)并且每个对象实例都必须与适当的视图相关联,因此在 goToDetails 方法中我必须执行一些逻辑来指定重定向目标
猜你喜欢
  • 2011-02-21
  • 1970-01-01
  • 2010-11-23
  • 1970-01-01
  • 2011-01-02
  • 2011-04-03
  • 1970-01-01
  • 2013-07-10
相关资源
最近更新 更多