0

这个 JSF1 代码让我困惑了好几个小时。基本设置是使用 Seam2 显示的此页面:

<h:form encType="multipart/form-data">
  <rich:dataTable value="#{results}">
    ...
  </rich:dataTable>

  <h:selectOneMenu value="#{contact.type}">
    <s:selectItems value="#{contactTypes}" var="t" label="#{t.label}" />
    <s:convertEntity />
    <a4j:support event="onchange" reRender="submitControls" />
  </h:selectOneMenu>

  <h:selectOneMenu value="#{template}">
    <s:selectItems value="#{allTemplates}" var="t" label="#{t.label}" />
    <s:convertEntity />
    <a4j:support event="onchange" reRender="submitControls" />
  </h:selectOneMenu>

  <a4j:outputPanel id="submitControls" layout="block">
    <a4j:outputPanel rendered="#{null != results and results.size gt 0 and ('ONE' == contact.type.label or template != null)}">
      <h:commandButton value="submit" action="#{manager.generate}" />
    </a4j:outputPanel>

    <h:outputText value="Search first" rendered="#{results == null or results.size == 0}" />
    <h:outputText value="Select template first" rendered="#{'ONE' == contact.type.label and template == null}" />
  </a4j:outputPanel>
</h:form>

显然,原始页面有点大。让我摸不着头脑的是,如果我不更改contact.type(将其保留为支持 bean 选择的默认值),则表单提交正常。如果我将类型切换ONE为此正确呈现“首先选择模板”文本而不是提交控件。通过选择另一种类型来恢复提交按钮会重新生成<input>BUT,而没有onclick第一次呈现表单时存在的处理程序。

现在单击<h:commandButton>向服务器发送请求但不会触发相关操作。但是,它现在恢复了 onclick 处理程序,并且第二次单击会触发正确的提交。

我不知道为什么会这样。有什么建议么?

编辑:将rendered属性移动到按钮会导致相同的行为(即使它确实有效,原始面板也包含更多共享相同条件的控件,因此它们确实起到了作用)

EDIT2:我刚刚测试过,只需重新添加在onclick提交按钮上呈现的“丢失”处理程序(通过萤火虫)即可使操作按预期工作。我开始怀疑 Richfaces 和该项目中也包含的 trinidad 库之间的不良交互(但未在此页面上使用)。

4

2 回答 2

1

这是防止篡改/黑客请求的保护措施。否则,黑客将能够调用他/她不允许调用的动作,只需相应地编辑发送的 HTTP 请求参数,从而调用未呈现的(例如,由于缺少“ADMIN”角色)命令按钮。

您需要确保rendered在处理表单提交的 HTTP 请求期间准备与显示表单的 HTTP 请求期间相同的模型(托管 bean 实例,其中所有属性负责保存属性后面的条件)。在 JSF2 中,这很容易通过将 bean 放置在视图范围而不是请求范围中来实现。只要您与同一个视图交互,视图范围就存在。在 JSF1 中,您需要获取像 Tomahawk's<t:saveState>或 RichFaces'这样的第 3 方框架标签<a4j:keepAlive>,以模拟 JSF2 视图范围。

<a4j:keepAlive beanName="results" />

顺便说一句,同样的故事也适用于disabled属性。

也可以看看:

于 2013-01-05T15:10:10.300 回答
0

我认为对于渲染属性和内部的任何内容,您必须注意它的评估在初始请求和提交时是相同的。它可能会在渲染阶段之前更改,但如果在应用程序调用期间它不一样,如果在此阶段按钮不会被渲染,它很可能会忽略该操作。

据我记得,这主要发生在我渲染的表达式使用实体属性之类的东西时,该属性将在应用请求值阶段已经更改。

于 2013-01-04T16:28:03.233 回答