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 ハンドラーが復元され、2 回目のクリックで適切な送信がトリガーされるようになりました。

どうしてこうなるのか途方に暮れています。助言がありますか?

編集:rendered属性をボタンに移動すると、同じ動作になります (たとえそれが機能したとしても、元のパネルには同じ条件を共有するより多くのコントロールが含まれているため、目的を果たします)

onclickEDIT2:送信ボタンでレンダリングされる「失われた」ハンドラーを(firebugを介して)再追加するだけで、アクションが意図したとおりに機能することをテストしました。リッチフェイスと、このプロジェクトにも含まれているトリニダード ライブラリ (ただし、このページでは使用されていません) との間の不適切な相互作用が疑われ始めています。

4

2 に答える 2

1

これは、改ざん/ハッキングされたリクエストに対する保護手段です。それ以外の場合、ハッカーは、送信された HTTP 要求パラメーターを編集するだけで、レンダリングされていない (たとえば、「ADMIN」ロールがないため) コマンド ボタンが呼び出されるようにすることで、呼び出すことが許可されていないアクションを呼び出すことができます。

renderedフォーム送信を処理する HTTP リクエスト中に、フォームを表示する HTTP リクエスト中と同じモデル (属性の背後にある条件を保持するすべてのプロパティを持つマネージド Bean インスタンス) を準備する必要があります。JSF2 では、Bean をリクエスト スコープではなくビュー スコープに配置することで、これを簡単に実現できます。ビュー スコープは、同じビューを操作している限り存続します。JSF1 では、JSF2 ビュー スコープをシミュレートするために、 Tomahawk<t:saveState>や RichFacesなどのサード パーティ フレームワーク タグを取得する必要があります。<a4j:keepAlive>

<a4j:keepAlive beanName="results" />

disabledちなみに、同じ話が属性にも当てはまります。

以下も参照してください。

于 2013-01-05T15:10:10.300 に答える
0

レンダリングされた属性とその中のすべてについて、最初のリクエストと送信で同じ評価になるように注意する必要があると思います。レンダリングフェーズの直前に変更される可能性がありますが、アプリケーションの呼び出し中に同じでない場合、このフェーズでボタンがレンダリングされない場合は、アクションを無視する可能性があります。

私が覚えている限り、これは主に、レンダリングされた式が、リクエスト値の適用フェーズですでに変更されるエンティティ属性のようなものを使用しているときに発生しました。

于 2013-01-04T16:28:03.233 に答える