在JSF表单上保留GET请求查询字符串参数 [英] Retaining GET request query string parameters on JSF form submit

查看:139
本文介绍了在JSF表单上保留GET请求查询字符串参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有3页:

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

agreement.xhtml需要两个参数才能正确加载:serviceIdsite.因此,普通的网址如下所示:/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,并且由于未发送参数siteserviceId,因此崩溃.

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 <h:form>提交给当前请求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,这不是问题. <h:inputHidden>不太适合,因为当表单上发生转换或验证错误时,它会迷惑地丢失其值.

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中,您需要<f:viewParam>includeViewParams.为了使includeViewParams正常工作,您需要在源页面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时,应在命令组件中将它们保留为<f:param>:

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>

无法在输入组件中为<f:ajax>设置它们,因此您的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 includeRequestParams="true">

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

That's basically all. This will generate a <form action> with current query string included.

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

然后,这些请求参数仅在表单提交的请求参数映射中可用.您不需要其他元数据/viewparams,也不需要发送重定向,并且可以根据需要将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";
}

或者,如果您使用的是"Pretty URL"库(例如PrettyFaces或FacesViews),或者是自己开发的某种东西,并且打算提交与浏览器地址栏中显示的网址完全相同的URL,则可以使用useRequestURI代替

Or, if you're using an "pretty URL" library such as PrettyFaces or FacesViews or perhaps something homegrown and intend to submit to exactly the same URL as appears in the browser's address bar, then you could use useRequestURI instead.

<o:form useRequestURI="true">

另请参见:

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆