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>
有人可以解释一下为什么好吗?
答案 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&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("&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
...
这就是我们所需要的。