在 JSF 表单提交上保留 GET 请求查询字符串参数 [英] Retaining GET request query string parameters on JSF form submit
问题描述
我有 3 页:
main.xhtml
agreement.xhtml
generated.xhtml
agreement.xhtml
需要两个参数才能正确加载:serviceId
和 site
.所以,一个普通的 url 看起来像这样:/app/agreement.xhtml?site=US&serviceId=AABBCC
.
The agreement.xhtml
needs two parameters to load correctly: serviceId
and site
. So, a normal url looks like this: /app/agreement.xhtml?site=US&serviceId=AABBCC
.
我在 agreement.xhtml
<h:form>
<h:commandButton value="Generate License File" action="#{agreement.generateMethod}" />
</h:form>
@RequestScoped
bean #{agreement}
有这个方法:
The @RequestScoped
bean #{agreement}
has this method:
public String generateMethod(){
.......
return "generated";
}
我需要在点击时执行 generateMethod()
方法,完成后,用户被重定向到 generated.xhtml
页面.发生的事情是,在点击时,页面浏览器将用户发送到 /app/agreement.xhtml
并且,因为它没有发送参数 site
和 serviceId
,它崩溃了.
I need that, on click, the generateMethod()
method is executed, and after it's done, the user is redirected to the generated.xhtml
page. What's happening is that, on click, the page browser sends the user to /app/agreement.xhtml
and, since it's not sending the parameters site
and serviceId
, it crashes.
我尝试让 generateMethod()
返回一个 "generated?faces-redirect=true"
,但仍然没有.有什么想法吗?
I tried making the generateMethod()
return a "generated?faces-redirect=true"
, but still nothing. Any ideas?
推荐答案
你的具体问题是因为一个 JSF
默认提交到当前请求 URL 没有任何查询字符串.仔细查看生成的 HTML 输出,您会看到
Your concrete problem is caused because a JSF <h:form>
submits by default to the current request URL without any query string. Look closer at the generated HTML output, you'll see
<form action="/app/agreement.xhtml" ...>
因此,您需要自己明确包含这些请求参数.有几种方法可以解决这个问题.如果您没有发送重定向,那么您可以将它们作为隐藏输入添加到 JSF 表单中.
You'd thus explicitly need to include those request parameters yourself. There are several ways to solve this. If you weren't sending a redirect, then you could just add them as hidden inputs to the JSF form.
<h:form>
<input type="hidden" name="site" value="#{param.site}" />
<input type="hidden" name="site" value="#{param.serviceId}" />
...
</h:form>
只是,这些参数不会再次出现在浏览器地址栏中的 URL 中.如果您仅在同一页面上使用 ajax,这不是问题.
顺便说一下不合适,因为当表单上发生转换或验证错误时,它会令人困惑地丢失其值.
Only, those parameters won't reappear in URL in browser's address bar. This isn't a problem if you're only using using ajax on the same page. The <h:inputHidden>
is by the way not suitable as it will confusingly lose its value when a conversion or validation error occurs on the form.
为了让它们重新出现在 URL 中,您需要
和 includeViewParams
.为了使 includeViewParams
工作,您需要在 both 源页面 agreement.xhtml
...
In order to get them to reappear in URL, you need <f:viewParam>
and includeViewParams
. In order to get includeViewParams
to work, you need to declare the following in both the source page agreement.xhtml
...
<f:metadata>
<f:viewParam name="site" value="#{agreement.site}" />
<f:viewParam name="serviceId" value="#{agreement.serviceId}" />
</f:metadata>
... 和目标页面generated.xhtml
:
<f:metadata>
<f:viewParam name="site" value="#{generated.site}" />
<f:viewParam name="serviceId" value="#{generated.serviceId}" />
</f:metadata>
现在您可以发送包含视图参数的重定向,如下所示:
Now you can send a redirect including the view parameters as follows:
public String generateMethod() {
// ...
return "generated?faces-redirect=true&includeViewParams=true";
}
请注意 bean 应该是 @ViewScoped
以便在打开带有表单的页面和提交表单之间保持这些参数有效,以及验证错误.否则,当坚持使用 @RequestScoped
bean 时,您应该在命令组件中将它们保留为
:
Do note that the bean should be @ViewScoped
in order to keep those parameters alive between opening the page with the form and submitting the form, also on validation errors. Otherwise, when sticking to a @RequestScoped
bean, you should be retaining them as <f:param>
in the command components:
<h:commandButton ...>
<f:param name="site" value="#{generated.site}" />
<f:param name="serviceId" value="#{generated.serviceId}" />
</h:commandButton>
没有办法在输入组件内部为
设置它们,那么你的 bean 应该是 @ViewScoped
.
There's no way to set them for <f:ajax>
inside input components, your bean should then really be @ViewScoped
.
或者,如果您碰巧已经使用 JSF 实用程序库 OmniFaces,那么您也可以只替换 <h:form>
由 <o:form>
如下(另见 展示示例):
Alternatively, if you happen to use JSF utility library OmniFaces already, then you could also just replace the <h:form>
by <o:form>
as follows (see also showcase example):
<o:form>
基本上就是这样.这将生成包含当前查询字符串的 .
That's basically all. This will generate a <form action>
with current query string included.
<form action="/app/agreement.xhtml?site=US&serviceId=AABBCC" ...>
然后这些请求参数仅在表单提交的请求参数映射中可用.您不需要额外的元数据/视图参数,也不需要发送重定向,如果需要,您的 bean 可以保持 @RequestScoped
.
Those request parameters are then just available in the request parameter map of the form submit. You don't need additional metadata/viewparams and you also don't need to send a redirect and your bean can be kept @RequestScoped
, if necessary.
public String generateMethod() {
// ...
return "generated";
}
另见:
- 什么可以<f:metadata>,<f:viewParam>和 <f:viewAction>用于?
- 如何在 JSF 中导航?如何使 URL 反映当前页面(而不是前一个页面)
这篇关于在 JSF 表单提交上保留 GET 请求查询字符串参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!