【问题标题】:Retain original GET request parameters across postbacks [duplicate]在回发中保留原始 GET 请求参数 [重复]
【发布时间】:2013-04-17 17:05:58
【问题描述】:

我有一个简单的页面,它与 @RequestScoped 支持 bean 相关联。我从传递参数“项目”的其他页面进入此页面。因此,当我进入正确的页面时,我的网址类似于 contextRoot/faces/jsf.xhtml?project=123

查看:

<f:metadata>
    <f:viewParam name="project" value="#{entityBean.projectId}" />
</f:metadata>       
...
<p:commandButton value="#{msg['button.add']}"
    actionListener="#{entityBean.addNewEntity((entityName),(entityDescritpion))}"
    ajax="true" update=":projectDetailForm"/>

支持 bean:

@Named("entityBean")
@RequestScoped
public class EntityBean implements Serializable{
    private String projectId;

    @PostConstruct
    public void init() {
        params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();

        for (Map.Entry<String, String> entry : params.entrySet()) {
            System.out.println(entry.getKey() + " / " + entry.getValue());
        }

        if (params.get("project") != null) {
            projectId = params.get("project");
        } else {
            HttpServletRequest request =
                (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
            String projectId = request.getParameter("project");
        }
    }

    //projectId getter and setter
    //public void addNewEntity(String name, String desc) {}
}

第一次打开页面时一切正常。 GET 参数已成功处理。但是,由于 bean 是请求范围的,它在请求结束时被销毁,并在后续回发时重新创建。在这些回发期间,GET 参数不再可用,即使它在浏览器地址栏中可见。我尝试了三种获取参数的方法 来自f:viewParamExternalContext 甚至来自ServletContext,但我无法获得这些参数。

我不想将@RequestScoped 更改为@SessionsScoped 并且我不能使用@ViewScoped,因为我正在使用CDI bean,我不想混合它们。

【问题讨论】:

  • 将 Bean 的范围从“请求”更改为“视图”。
  • @kshitij:不幸的是,OP 使用 CDI 而不是 JSF 来管理 bean。所以特定于 JSF 的视图范围不起作用。 OP还在问题的最后一句中明确提到了它。

标签: jsf jsf-2


【解决方案1】:

需要UICommand组件中的&lt;f:param&gt;为后续请求保留请求参数。例如

<p:commandButton ...>
    <f:param name="project" value="#{param.project}" />
</p:commandButton>

或者,您可以使用 JSF 实用程序库 OmniFaces&lt;o:form&gt;,它基本上扩展了 &lt;h:form&gt; 附加属性 includeViewParams,它使您能够保留通过 &lt;f:viewParam&gt; 注册的请求参数以供后续使用请求。

<o:form includeViewParams="true">
    ...
</o:form>

如果您有多个命令按钮/链接和 ajax 操作,这可能会更容易。

浏览器地址栏中的 URL 在您的情况下没有更改,因为您正在触发 ajax 请求。但是 actual URL,您可以在浏览器中通过右键单击生成的 HTML 输出的 &lt;form action&gt; 中看到 - View Source,默认情况下不包含当前的 GET 参数。


与具体问题无关,在 postconstruct 中手动收集参数,您基本上忽略了&lt;f:viewParam&gt; 的有用性和功能。我建议仔细阅读以下答案以了解如何正确使用它们:

【讨论】:

  • 为了解决这个问题,我使用了 Apache MyFaces CODI。它为 ViewAccessScoped 等 CDI 范围提供了非常有用的扩展。使用 JSF 2.0 和 Primefaces 工作得很好。
  • @AdrianX:也可以。它只会在 URL 中留下丑陋的 windowId 参数。请注意,它还将 JSF @ViewScoped 透明地连接到 CDI,以便您可以使用 @Named @ViewScoped
猜你喜欢
  • 2011-08-29
  • 1970-01-01
  • 2020-06-01
  • 2011-05-26
  • 2015-10-20
  • 2023-03-28
  • 2015-08-04
  • 2018-08-08
  • 1970-01-01
相关资源
最近更新 更多