首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在JSF表单提交上保留GET请求查询字符串参数

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

Stack Overflow用户
提问于 2013-07-19 05:26:45
回答 2查看 24.2K关注 0票数 22

我有3页:

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

agreement.xhtml需要两个参数才能正确加载:serviceIdsite。所以,一个普通的url看起来是这样的:/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,因为它没有发送参数siteserviceId,所以它崩溃了。

我尝试让generateMethod()返回一个"generated?faces-redirect=true",但仍然没有结果。有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-19 19:59:38

您的具体问题是因为JSF在默认情况下提交给当前的请求<h:form>,而没有任何查询字符串。仔细查看生成的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>

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

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>

基本上就是这样。这将生成一个包含当前查询字符串的<form action>

<form action="/app/agreement.xhtml?site=US&serviceId=AABBCC" ...>

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

public String generateMethod() {
    // ...

    return "generated";
}

另请参阅:

票数 39
EN

Stack Overflow用户

发布于 2013-07-19 07:16:11

你的generateMethod必须返回

return "generated?site=US&amp;serviceId=AABBCC&amp;faces-redirect=true";

您甚至可以用&替换&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>
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17734230

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档