3

私はサーブレットと JSP をいじっていましたが、少し混乱しています。

  1. リクエストをJSPにディスパッチするサーブレット(コントローラー)を作成しました

  2. サーブレットで setAttribute() メソッドを使用して、リクエスト オブジェクトにいくつかの属性を設定しました。

  3. JSP 内のリクエスト オブジェクトのパラメータと属性に問題なくアクセスできます


  4. ここで、 session.setAttribute("test", request)を使用して、リクエスト オブジェクトをセッション オブジェクトの属性として保存しました。

  5. 2 番目の JSP を作成しました (最初の JSP からの
    移動は、特定のボタンをクリックしたときに Javascript を介して行われます。window.location 関数を使用し
    、2 番目の JSP のアドレスを値として指定します)。

  6. 2 番目の JSP で、セッション オブジェクトから要求オブジェクトを取得すると、取得した要求オブジェクトの
    すべての属性から null 値が取得されます。
  7. 取得したリクエスト オブジェクトのパラメータにアクセスできますが、
    request.getParameter() メソッドを使用して最初の JSP でパラメータを少なくとも 1 回取得した場合にのみアクセスできます
    。それ以外の場合は、2 番目の JSP で null を返します。

私はこのことに本当に慣れておらず、この動作について混乱しています。パラメータがそのまま残っているのに、リクエストオブジェクトの属性が「消去」されたのはなぜですか(最初のJSPでパラメータにアクセスした限り。IMOが意味をなさないため、さらに当惑します)

説明をいただければ幸いです。よろしくお願いします。

4

2 に答える 2

3

これは単なる知識に基づく推測ですが、問題は、選択したコンテナ内のリクエストオブジェクトがそのパラメータについて怠惰になる可能性があることだと思います。パラメータをリクエストすると、外部コンテキストに到達し、必要なデータをプルします。同時にそれをキャッシュします。

それにもかかわらず、奇妙な振る舞いの理由はそれほど重要ではありません。この問題は、セッションにリクエストを保存しないことで解決する必要があります。リクエストオブジェクトは、現在のリクエストへのハンドルであり、データストア自体ではありません。属性がthreadlocalsに格納される可能性があることはわかっているので、その下にあるメカニズムを使用している可能性があります。リクエストをいかなる種類のアーカイブとしても機能させる契約はまったくありません。例:セキュリティプリンシパルにそのような保存されたリクエストを要求した場合、どういう意味ですか?「セッションの現在のプリンシパル」という意味ですか?「リクエストが作成された時点のプリンシパル」という意味ですか?

編集:

純粋な好奇心から、Tomcatの実装を覗いてみたところ(どのコンテナーを使用しているかわかりません)、それが私の主張をサポートしていることがわかりました。ほとんどのデータが遅延収集されるだけでなく、リクエストオブジェクトがリサイクルされます。したがって、セッションに保存してから使用しようとすると、他の人のリクエストを使用していることに気付く場合があります。

于 2013-02-05T23:22:35.623 に答える
2

Java EE 5には4 つのスコープがあります。Java EE 6Java EE 7の両方に5 つのスコープがあります。最も使用されるのは次のとおりです。

  • リクエストの範囲
  • セッション スコープ
  • アプリケーション スコープ(Web コンテキスト)

適切な属性を設定することにより、上記のすべてのスコープに一部のデータを格納できます。

以下は、リクエスト スコープに関するServletRequest.setAttribute(String, Object)メソッドに関連する Java EE API ドキュメントからの引用です。

void setAttribute(java.lang.String name,
                  java.lang.Object o)

このリクエストに属性を格納します。属性はリクエスト間でリセットされます。このメソッドは、ほとんどの場合、RequestDispatcher と組み合わせて使用​​されます。
...

したがって、新しいリクエストごとに、リクエストで設定した以前の属性は失われます。リクエストに属性を設定したら、リクエストを目的のページに転送する必要があります。リダイレクトすると、これはまったく新しいリクエストになるため、以前に設定した属性は失われます。(それでもリダイレクトを使用したい場合は、これを読んでください: Servlet Redirection to same page with error message )

HttpSession (セッション スコープ内) で設定されたこれらの属性は、セッションが存続する限り存続し、もちろん、セッションが属するユーザーのみが使用できます。

コンテキスト属性に関しては、Web アプリケーション全体 ( application スコープ) およびすべてのユーザーが利用できるように意図されており、さらに Web アプリケーションが存続している限り存続します。


結論として、以前にセッションで属性を設定した場合、セッションが存続している限り、同じユーザーがその属性を使用できます。

これがあなたを助けることを願っています。

PS
たぶん、この記事も役に立つでしょう: Java EE 6 スコープがユーザー インタラクションに与える影響
この記事では、スコープ設定のために注釈を使用する唯一のことですが、アイデアは理解できるでしょう。

于 2013-02-05T23:07:35.150 に答える