【问题标题】:f:viewParam with POST request and redirectf:viewParam 带有 POST 请求和重定向
【发布时间】:2014-01-25 12:22:55
【问题描述】:

Mojarra 2.1.26

我有一个非常简单的页面:

hello.xml:

<h:head></h:head>

<f:metadata>
    <f:viewParam name="name"></f:viewParam>
</f:metadata>

<h:body>
    <h1>Hello #{param.name} !!!</h1>
</h:body>

还有另一个页面index.html。在此页面上,我有一个触发 POST 请求的 commandLink:

<h:commandLink value="Go to hello page" action="/pages/hello.xhtml" >
    <f:param name="name" value="Hubert" />
</h:commandLink>

这行得通。我可以看到声明:Hello Hubert !!!

问题:

不幸的是,这不适用于重定向:

<h:commandLink value="Go to hello page" action="/pages/hello.xhtml?faces-redirect=true" >
    <f:param name="name" value="Hubert" />
</h:commandLink>

有人能解释一下为什么吗?

【问题讨论】:

  • 您是否尝试在您的操作参数中添加&amp;includeViewParams=true
  • @LaurentG,感谢您的提示。这帮助我解决了我的问题。

标签: jsf jsf-2 mojarra


【解决方案1】:

要回答这个问题,我们需要了解重定向的工作原理。

重定向

收到客户端 HTTP 请求。对此请求的响应已创建。它看起来总是一样的。返回代码 302,并设置标题 Location。例如:

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://stackoverflow.com
...

当客户端收到此响应时,它会执行另一个请求。这次从 Location 标头获取对 URI 的请求。

问题示例说明

h:commandLink 触发 POST 请求。创建响应。此响应包含来自操作的 URI:

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://localhost:8080/myapp/pages/hello.xhtml
...

包含参数名称,但它在消息正文中。

当客户端收到代码 302 和 Location 时,它会像往常一样执行相同的操作。创建 GET 请求:

GET /myapp/pages/hello.xhtml HTTP/1.1

简单的 POST 响应正文被忽略。没有理由从正文中获取内容并将其附加到 GET 请求。这就是问题示例无法正常工作的原因。

解决方案 1: (基于 LaurentG 的建议)

可以使用includeViewParams。但它仅包含来自元素 f:viewParam 的值。因此,在与 commandButton 相同的页面上,我们必须添加这样的元素:

<h:head></h:head>

<f:metadata>
    <f:viewParam name="name"></f:viewParam>
</f:metadata>

<h:body>
    <h:form>
        <h:commandLink value="Go to hello page" action="/pages/hello.xhtml?faces-redirect=true&amp;includeViewParams=true" >
            <f:param name="name" value="Hubert" />
        </h:commandLink>
    </h:form>
</h:body>

所以我们在页面 hello.xhtml 上有 f:viewParam 元素,并且这个页面重定向到页面 hello.xhtml

解决方案 2:

如果参数值来自控制器,那么我们可以使用 h:commandButton 从页面中删除元素 f:viewParam。技巧可以在动作方法中完成:

 <h:form>
        <h:commandLink value="Go to hello page" action="#{controller.action}" />
 </h:form>

和动作():

public String action() {

    String outcome = "/pages/hello?faces-redirect=true";

    try {
        outcome += String.format("&amp;name=%s", URLEncoder.encode(name, "UTF-8"));
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }


    return outcome;
}

解决方案 1 和 2 克里特斯响应:

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://localhost:8080/myapp/pages/hello.xhtml?name=Hubert
...

这就是我们需要的。

【讨论】:

  • 这行得通,但是使用您的建议我遇到了另一个问题。我有一个包含多个选择项的表。我将这些项目存储在带有元素、标志(已选择/未选择器)的地图中......当我调用该操作时,我会丢失地图状态。我的 bean 是视图状态,我放置了一个调试点,但从未命中,令我惊讶的是,日志写入了,所以我正在输入方法......我不知道发生了什么,但如果你需要“计算”的值f:param 值...失败!但如果你硬编码它就可以了。
猜你喜欢
  • 2016-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-30
相关资源
最近更新 更多