简体   繁体   English

f:viewParam与POST请求并重定向

[英]f:viewParam with POST request and redirect

Mojarra 2.1.26 Mojarra 2.1.26

I have a very simple page: 我有一个非常简单的页面:

hello.xml: 的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>

And another page index.html . 还有另一个页面index.html On this page I have a commandLink which triggers POST request: 在此页面上,我有一个commandLink触发POST请求:

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

This works. 这可行。 I can see statement: Hello Hubert !!! 我可以看到以下声明:您好,休伯特!

Question: 题:

This unfortunately does not work with redirection: 不幸的是,这不适用于重定向:

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

Could someone explain me why please? 有人可以解释一下为什么吗?

To answer this question we need to know how redirect works. 要回答这个问题,我们需要知道重定向的工作原理。

Redirect 重定向

Client HTTP request is received. 收到客户端HTTP请求。 Reponse for this request is created. 创建对此请求的响应。 It always looks the same. 它总是看起来一样。 Code 302 is returned, and header Location is set. 返回代码302,并设置标头Location For example: 例如:

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

When client received this response then it does another request. 客户收到此响应后,它将发出另一个请求。 This time GET request to URI from Location header. 这次从Location标头向URI发出GET请求。

Question example explanation 问题示例说明

h:commandLink triggres POST request. h:commandLink触发POST请求。 Response is created. 响应已创建。 This response contains URI from action: 此响应包含动作的URI:

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

Param name is included, but it is in message body. 包含参数名称,但是它在消息正文中。

When client receives code 302 and Location it does the same as always. 当客户端收到代码302和位置时,它将照常执行操作。 Creates GET request: 创建GET请求:

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

Simply POST reponse body is ignored. 只是POST响应正文被忽略。 There is no reason to get content from body and attach it to GET request. 没有理由从正文中获取内容并将其附加到GET请求。 That's why example from question doesn't work properly. 这就是为什么问题示例无法正常工作。

Solution 1: (based on LaurentG suggstion) 解决方案1 ​​:( 基于LaurentG的建议)

includeViewParams can be used. 可以使用includeViewParams。 But it includes only values from elements f:viewParam . 但它仅包含来自元素f:viewParam的值。 So on the same page with commandButton we have to add such element: 因此,在与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>

So we have f:viewParam element on page hello.xhtml and this page that redirects to page hello.xhtml . 因此,我们F:在页面hello.xhtml viewParam元素,而这个页面重定向页面hello.xhtml。

Solution 2: 解决方案2:

If parameter value is from controller then we can remove element f:viewParam from page with h:commandButton . 如果参数值来自控制器,则可以使用h:commandButton从页面中删除元素f:viewParam Trick can be done inside action method: 可以在动作方法内完成技巧:

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

And action(): 和action():

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;
}

Solution 1 and 2 cretes response: 解决方案1和2的响应:

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

That's what we need. 那就是我们所需要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM