在JSF表单提交上保留GET请求查询字符串参数

Nac*_*321 17 navigation jsf jsf-2 http-request-parameters

我有3页:

  • main.xhtml
  • agreement.xhtml
  • generated.xhtml

agreement.xhtml需要两个参数正确加载:serviceIdsite.所以,正常的网址看起来像这样:/app/agreement.xhtml?site=US&serviceId=AABBCC.

我有这个按钮 agreement.xhtml

<h:form>
   <h:commandButton value="Generate License File" action="#{agreement.generateMethod}" />   
</h:form>
Run Code Online (Sandbox Code Playgroud)

@RequestScoped#{agreement}有这样的方法:

public String generateMethod(){
    .......
    return "generated";
}
Run Code Online (Sandbox Code Playgroud)

我需要,在点击时,generateMethod()方法被执行,完成后,用户被重定向到generated.xhtml页面.发生了什么事是,在点击,网页浏览器发送的用户/app/agreement.xhtml,而且由于它不发送参数siteserviceId,它崩溃.

我尝试过generateMethod()返回a "generated?faces-redirect=true",但仍然没有.有任何想法吗?

Bal*_*usC 32

您的具体问题是由于JSF <h:form>默认提交到当前请求URL而没有任何查询字符串.仔细观察生成的HTML输出,你会看到

<form action="/app/agreement.xhtml" ...>
Run Code Online (Sandbox Code Playgroud)

因此,您明确需要自己包含这些请求参数.有几种方法可以解决这个问题.如果您没有发送重定向,那么您可以将它们作为隐藏输入添加到JSF表单中.

<h:form>
    <input type="hidden" name="site" value="#{param.site}" />
    <input type="hidden" name="site" value="#{param.serviceId}" />
    ...
</h:form>
Run Code Online (Sandbox Code Playgroud)

只是,这些参数不会再出现在浏览器地址栏的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>
Run Code Online (Sandbox Code Playgroud)

... 目标页面generated.xhtml:

<f:metadata>
    <f:viewParam name="site" value="#{generated.site}" />
    <f:viewParam name="serviceId" value="#{generated.serviceId}" />
</f:metadata>
Run Code Online (Sandbox Code Playgroud)

现在您可以发送包含视图参数的重定向,如下所示:

public String generateMethod() {
    // ...

    return "generated?faces-redirect=true&includeViewParams=true";
}
Run Code Online (Sandbox Code Playgroud)

请注意,bean应该是@ViewScoped为了在打开带有表单的页面和提交表单之间保持这些参数,还有验证错误.否则,当坚持使用@RequestScopedbean时,您应该像<f:param>在命令组件中一样保留它们:

<h:commandButton ...>
    <f:param name="site" value="#{generated.site}" />
    <f:param name="serviceId" value="#{generated.serviceId}" />
</h:commandButton>
Run Code Online (Sandbox Code Playgroud)

没有办法为<f:ajax>内部输入组件设置它们,你的bean应该真的@ViewScoped.


或者,如果您恰好使用了JSF实用程序库OmniFaces,那么您也可以按如下方式替换<h:form>by <o:form>(另请参见showcase示例):

<o:form includeRequestParams="true">
Run Code Online (Sandbox Code Playgroud)

这基本上都是.这将生成<form action>包含当前查询字符串的内容.

<form action="/app/agreement.xhtml?site=US&serviceId=AABBCC" ...>
Run Code Online (Sandbox Code Playgroud)

然后,这些请求参数仅在表单提交的请求参数映射中可用.您不需要额外的元数据/ viewparams,也不需要发送重定向@RequestScoped,如果需要,可以保留bean .

public String generateMethod() {
    // ...

    return "generated";
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您使用的是"漂亮的URL"库,例如PrettyFaces或FacesViews,或者可能是本土的东西,并打算提交到浏览器地址栏中显示的完全相同的URL,那么您可以使用它useRequestURI.

<o:form useRequestURI="true">
Run Code Online (Sandbox Code Playgroud)

也可以看看:


And*_*ndy 5

generateMethod必须回来

return "generated?site=US&amp;serviceId=AABBCC&amp;faces-redirect=true";
Run Code Online (Sandbox Code Playgroud)

您甚至可以替换&amp;,&但在xhtml中将其转义.

generated.xhtml你可以在这里捕获<f:viewParam>像这样传递的参数

<f:metadata>
    <f:viewParam name="site" value="#{yourBean.site}"/><!--Make sure you have a setter-->
    <f:viewParam name="serviceId" value="#{yourBean.serviceId}"/><!--Make sure you have a setter-
</f:metadata>
<h:head>
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

21977 次

最近记录:

9 年,5 月 前