2

編集:新しい調査結果を反映するためにタイトルを編集しました。2 番目のポートレットがどのタイプのポートレットであるかは関係ありません。以下の一般的な動作を参照してください。

  1. ページに Struts2 ポートレット A があり、そのデフォルトの「インデックス」アクションは pageA1 です。
  2. A1 のリンクをクリックして、ページ A2 に移動します。
  3. ページを更新すると、ポートレット A にはまだ pageA2 が表示されます。
  4. ページには他のポートレットがあります。任意のポートレット B を選択し、B1 のリンクをクリックします。
  5. ポートレット B は B2 に移動します。一方、Liferay は、Struts2 ポートレット A を含む、ページ上の他のポートレットを更新します。
  6. ポートレット A の更新後に期待される結果は pageA2 ですが、表示されるページは pageA1 です。

症状:

渡されたパラメーターを表示するために、struts アクションにログを追加しました。通常のナビゲーション中 (つまり、struts2 ポートレット A を単独で使用しているだけです)、パラメーター struts.portlet.action および struts.portlet.mode が表示されます。ただし、別のポートレット B のレンダリング/アクション フェーズが原因で struts2 ポートレット A で自動更新が発生した場合、それらのパラメーターは struts2 に渡されないように見えるため、ポートレット A はデフォルトで、ページではなくそのインデックス pageA1 に戻ります。更新前に表示されます (pageA2)。

これは、struts2 によって検出された struts.portlet.action パラメータがないため、デフォルト アクションを呼び出すということですか (この場合、「index」->pageA1 に設定します)。


古い詳細

Struts2 フレームワークを使用する 2 つのポートレットを持つプロジェクトをセットアップしています。両方のポートレットは実際には非常によく似ていますが、それらのコードは異なるパッケージに存在し、struts.xml では、それらのアクションは独自の名前空間を持つ個別のモジュールで定義されています。ただし、それらは 1 つのプロジェクトの一部であり、1 つの WAR ファイルにまとめてパッケージ化されています。

WAR を Liferay にデプロイし、両方のポートレットを 1 つのページに追加します。2 つのポートレットを使用すると、次の動作が発生します。

  1. ポートレット A のリンクをクリックします。
  2. ポートレット A が画面 A2 にロードされます。
  3. ポートレット B のリンクをクリックします。
  4. ポートレット B が画面 B2 にロードされます。
  5. ただし、副作用として、ポートレット A が更新され、表示される画面は (画面 A2 ではなく) その「インデックス」ページになります。

これは予期された動作ですか? または、この特定のセットアップを 1 つのポータル ページで機能させるために他にすべきことはありますか?

編集: 私がクリックしているリンクはrenderURLです(s:urlタグを使用して生成されます)。両方のポートレットの 2 ページ目にはフォームが含まれていますが、これが重要かどうかはわかりません。

簡単なロギングを追加したところ、ページが更新されるたびに両方のポートレットが 2 回レンダリングされていることがわかりました。それは自然な行動ではないと思います。

これが私の struts.xml です。

<package name="portletA" extends="struts-portlet-default" namespace="/portletA">

    <action name="index" class="my.a.DisplayFirstPageAction">
        <result name="success">/pageA1.jsp</result>
    </action>

    <action name="displayForm" class="my.a.DisplaySecondPageAction">
        <result name="input">/pageA2.jsp</result>
    </action>
</package>
<package name="portletB" extends="struts-portlet-default" namespace="/portletB">

    <action name="index" class="my.b.DisplayFirstPageAction">
        <result name="success">/pageB1.jsp</result>
    </action>

    <action name="displayForm" class="my.b.DisplaySecondPageAction">
        <result name="input">/pageB2.jsp</result>
    </action>
</package>

両方のポートレットの pageA1.jsp には、Struts アクション「displayForm」を呼び出すリンクがあります。FirstPageAction の execute メソッドは SUCCESS を返し、SecondPageAction の execute メソッドは INPUT を返します。

2番目のアクションで「成功」の結果がないためかもしれないと思いました(ページにフォームがあるため、execute()メソッドは「入力」を返します)。ただし、result=success タグを追加しても役に立ちません。

よく考えてみると、B2 のレンダリング中に A1 のリンクをクリックすると、B2 のレンダリング/実行アクションが呼び出されるはずですが、代わりに B1 のレンダリング/実行アクションが呼び出されるようです。

4

1 に答える 1

1

http://www.liferay.com/documentation/liferay-portal/6.0/development/-/ai/understanding-the-two-phases-of-portlet-execution、具体的には次の段落を確認してください。

ポートレットの仕様では、ポートレットのすべてのリクエストに対して 2 つのフェーズが定義されており、アクションが実行されているとき (繰り返されるべきではない) と、コンテンツが生成されている (レンダリングされている) ときをポータルが区別できるようになっています。

  • アクション フェーズ: アクション フェーズは、一度に 1 つのポートレットに対してのみ呼び出すことができ、通常はポートレットとのユーザー対話の結果です。このフェーズでは、ポートレットのステータスを変更できます。たとえば、ポートレットのユーザー設定を変更できます。また、データベースへの挿入や変更、または繰り返してはならない操作は、このフェーズで実行することをお勧めします。
  • レンダリング フェーズ: レンダリング フェーズは、アクション フェーズ (存在する場合も存在しない場合もある) の後に、ページ内のすべてのポートレットに対して常に呼び出されます。これには、アクション フェーズも実行したポートレットが含まれます。ページ内のポートレットのレンダリング フェーズが実行される順序は、ポートレットの仕様によって保証されていないことに注意してください。Liferay には、liferay-portlet.xml の要素 render-weight による仕様への拡張があります。レンダリング ウェイトが高いポートレットは、値が低いポートレットより先にレンダリングされます。

[...]

ポートレットで生成できる URL には、次の 3 つのタイプがあります。

  • renderURL : これは、これまで使用してきた URL のタイプです。レンダリング フェーズのみを使用してポートレットを呼び出します。
  • actionURL : このタイプの URL は、ページ内のすべてのポートレットをレンダリングする前にアクション フェーズを実行する必要があることをポートレットに伝えます。
  • resourceURL : このタイプの URL は、画像、XML、JSON、またはその他のタイプのリソースを取得するために使用できます。画像やその他のメディアタイプを動的に生成するためによく使用されます。サーバーに AJAX リクエストを行うことも非常に便利です。この URL タイプと他の 2 つの URL タイプとの主な違いは、応答として送信されるデータをポートレットが完全に制御できることです。

したがって、 renderURL の代わりに actionURL を使用しページA2 に移動していると思います。

于 2012-04-18T10:39:06.337 に答える