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

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

问题描述

我有 3 页:

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

agreement.xhtml 需要两个参数才能正确加载:serviceIdsite.所以,一个普通的 url 看起来像这样:/app/agreement.xhtml?site=US&ser​​viceId=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 默认提交到当前请求 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";
}

另见:

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