我有3页:
main.xhtml
agreement.xhtml
generated.xhtml
agreement.xhtml
需要两个参数才能正确加载:serviceId
和site
。因此,普通的网址如下所示:/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}
具有以下方法:public String generateMethod(){
.......
return "generated";
}
我需要在单击时执行
generateMethod()
方法,并在完成后将用户重定向到generated.xhtml
页面。发生的是,单击页面浏览器会将用户发送到/app/agreement.xhtml
,并且由于未发送参数site
和serviceId
,它崩溃了。我尝试使
generateMethod()
返回"generated?faces-redirect=true"
,但还是没有。有任何想法吗? 最佳答案
造成您具体问题的原因是,默认情况下,JSF <h:form>
提交给当前请求URL,而没有任何查询字符串。仔细查看生成的HTML输出,您将看到
<form action="/app/agreement.xhtml" ...>
因此,您需要明确地自己包括那些请求参数。有几种解决方法。如果您没有发送重定向,则可以将它们作为隐藏输入添加到JSF表单中。
<h:form>
<input type="hidden" name="site" value="#{param.site}" />
<input type="hidden" name="site" value="#{param.serviceId}" />
...
</h:form>
只有这些参数不会重新出现在浏览器地址栏中的URL中。如果仅在同一页面上使用ajax,这不是问题。
<h:inputHidden>
不适合使用,因为当表单上发生转换或验证错误时,它会困惑地丢失其值。为了使它们重新出现在URL中,您需要
<f:viewParam>
和includeViewParams
。为了使includeViewParams
正常工作,您需要在和源页面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>
现在,您可以发送包含 View 参数的重定向,如下所示:
public String generateMethod() {
// ...
return "generated?faces-redirect=true&includeViewParams=true";
}
请注意,bean应该是
@ViewScoped
,以便在打开带有表单的页面和提交表单之间以及验证错误时保持这些参数有效。否则,当坚持使用@RequestScoped
bean时,应在命令组件中将它们保留为<f:param>
:<h:commandButton ...>
<f:param name="site" value="#{generated.site}" />
<f:param name="serviceId" value="#{generated.serviceId}" />
</h:commandButton>
无法在输入组件中为
<f:ajax>
设置它们,那么您的bean应该实际上是@ViewScoped
。另外,如果您碰巧已经使用了JSF实用程序库OmniFaces,那么也可以按照以下方式用
<h:form>
替换<o:form>
(另请参见showcase example):<o:form includeRequestParams="true">
基本上就是全部。这将生成一个包含当前查询字符串的
<form action>
。<form action="/app/agreement.xhtml?site=US&serviceId=AABBCC" ...>
然后,这些请求参数仅在表单提交的请求参数映射中可用。您不需要其他元数据/ viewparams,也不需要发送重定向,并且可以根据需要将bean保留为
@RequestScoped
。public String generateMethod() {
// ...
return "generated";
}
或者,如果您使用的是“Pretty URL”库(例如PrettyFaces或FacesViews),或者是自己开发的某种东西,并且打算提交与浏览器地址栏中显示的URL完全相同的URL,则可以改用
useRequestURI
。<o:form useRequestURI="true">
也可以看看: