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

标签 jsf jsf-2 navigation 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>
    
    @RequestScoped bean #{agreement}具有以下方法:
    public String generateMethod(){
        .......
        return "generated";
    }
    

    我需要在单击时执行generateMethod()方法,并在完成后将用户重定向到generated.xhtml页面。发生的是,单击页面浏览器会将用户发送到/app/agreement.xhtml,并且由于未发送参数siteserviceId,它崩溃了。

    我尝试使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">
    

    也可以看看:
  • What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
  • How to navigate in JSF? How to make URL reflect current page (and not previous one)
  • 关于jsf - 在JSF表单上保留GET请求查询字符串参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17734230/

    相关文章:

    jsf - java.lang.IllegalArgumentException : javax. 面.lifecycle.ClientWindowFactory

    javascript - 使用 jquery 在点击导航项和滚动 div 时添加类

    javascript - 如何使用 jQuery 在键盘上为 Div 列表启用箭头导航

    multithreading - 在与托管 bean 分开运行的线程中访问 OmniFaces PushContext 实例

    javascript - 如何从 javascript 函数中调用 javabean 方法?

    java - JSF 中的值转换究竟发生在什么时候?

    java - PrimeFaces:在 Javascript 中获取当前列的排序顺序

    jsf-2 - PrimeFaces 语言环境不起作用

    jsf-2 - JSF 2 : h:link and getrowdata

    java - 替换底部导航中的 fragment