f:带有POST请求和重定向的viewParam

时间:2014-01-07 17:30:28

标签: jsf jsf-2 mojarra

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 。在这个页面上,我有一个commandLink来触发POST请求:

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

这很有效。我可以看到声明:你好休伯特!!!

问题:

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

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

有人可以解释一下为什么好吗?

1 个答案:

答案 0 :(得分:2)

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

<强>重定向

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

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

当客户收到此回复后,它会再次发出请求。这次从 Location 标头向URI请求URI。

问题示例说明

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

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

包含Param名称,但它位于邮件正文中。

当客户端收到代码302和位置时,它会像往常一样。创建GET请求:

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

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

解决方案1: (基于LaurentG suggstion)

可以使用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
...

这就是我们所需要的。