11

jspタグのライフサイクルを誤解しているように見えるため、コードにバグを導入しました。

バグが発生する前は、タグは次のように機能していました。タグに属性としてコレクションを渡すと、テーブルとして表示されます。コレクションは、コントローラーからJSPに渡されました。

バグ後:コレクションを設定する属性を削除しました。代わりに、タグでコレクションがnullかどうかを確認し、リクエストから名前で取得します(命名規則を使用)。

私が予期していなかったこと:コレクションが最初にタグに設定された後、その後の実行でnullになることはありません!それでも、TLDでは必須ではない属性として定義されていました。

タグが実行間で以前の値を保持しないことを期待していました。

4

6 に答える 6

12

あなたは自分で質問に答えました - それはプールされています。Java 実装で何を実装するかについては、タグのチュートリアルと、そこからリンクされた、呼び出しシーケンスを含むページを参照してください。

ATag t = new ATag();
t.setPageContext(...);
t.setParent(...);
t.setAttribute1(value1);
t.setAttribute2(value2);
t.doStartTag();
t.doEndTag();
t.release();

つまり、API の要求に従って、doEndTag() でタグ インスタンスを再初期化します。(Julien Kroneggによるコメントの時点で変更、ありがとう)

プーリングはおそらくコンテナーに依存することに注意してください。

于 2009-03-05T19:08:34.570 に答える
8

簡単な答え: 属性プロパティに自分で書き込むことは想定されていません。そうすることで、状態のクリーニングを自分の責任にすることができます。

より長い回答については、JSP 2.0 仕様で次のように規定されています (2-51 ページ)。

  • セッターは、タグの特定の出現の指定されたすべての属性に対して呼び出されます
  • 省略された属性に対してセッターは呼び出されませ(デフォルト値はそのまま残り、あなたの場合、内部状態の不正な値です)
  • タグ ハンドラは、指定された属性の同じセットを持つオカレンスでのみ再利用できます

これら 3 つの点が合わさると、属性プロパティが常に正しく初期化されると同時に、(コンストラクタまたはプロパティの宣言で定義された) デフォルト値が保持されることが保証されます。その代わりに、コンテナーのみが (セッターを呼び出すことによって) 属性プロパティを操作するという前提でのみ機能します。

完全を期すために:

  • release()タグ ハンドラの呼び出し間の内部状態をリセットするために使用しないでください。GC の前に呼び出されることが保証されているだけであり、長期的なリソースを解放するために使用する必要があります。
  • でインスタンス変数を初期化する場合はdoStartTag()、属性を上書きしないように注意してください。これは、セッターがこの時点でコンテナーによって既に呼び出されているためです。
  • doEndTag()例外が発生した場合にタグを再利用してはならないため、初期化に安全に使用できる必要があります (2-54 ページ [2] を参照)。
于 2010-05-18T11:55:17.003 に答える
3

JSP 1.2 仕様では、TryCatchFinally インターフェイスが追加されました。 http://docs.oracle.com/javaee/1.4/api/javax/servlet/jsp/tagext/TryCatchFinally.html

したがって、doStartTag() メソッドでリソースを割り当て、doFinally() メソッドでクリーンアップする必要があるようです。

于 2012-03-05T19:09:54.033 に答える
1

答えは次のとおりです。タグは魔法のプールランドにプールされ、実行間で再利用されます。タグ仕様には次のように書かれています:

「指定されていない属性/プロパティは設定しないでください (setter メソッドを使用して)。」

于 2009-03-05T18:57:29.620 に答える
0

Tomcat 6 を観察すると、release() はコンテナーがシャットダウンしているときにのみ呼び出されることが示唆されています。タグ ハンドラー インスタンス メンバーは、doEndTag() でインスタンスの状態をクリアする必要があります。APIドキュメントから:

「このインスタンスに関連付けられているすべてのインスタンスの状態をリセットする必要があります。」

TagSupport.doEndTag()を参照してください。

于 2009-06-05T20:55:53.417 に答える