ServletContext
サーブレットコンテナ(Apache Tomcatなど)が起動すると、すべてのWebアプリケーションがデプロイおよびロードされます。Webアプリケーションがロードされると、サーブレットコンテナがServletContext
1回作成し、サーバーのメモリに保持します。Webアプリケーションのweb.xml
と付属のすべてweb-fragment.xml
のファイルが解析され、各され<servlet>
、<filter>
そして<listener>
見つかった(または注釈付きで、各クラス@WebServlet
、@WebFilter
および@WebListener
それぞれ)は一度インスタンス化だけでなく、サーバのメモリに保持されます。インスタンス化されたフィルタごとに、そのinit()
メソッドは新しいで呼び出されますFilterConfig
。
ときにServlet
持っている<servlet><load-on-startup>
か@WebServlet(loadOnStartup)
の値よりも大きい0
、そのinit()
方法は、また、新しいと起動時に呼び出されますServletConfig
。それらのサーブレットは、その値で指定されているのと同じ順序で初期化されます(1
is 1st、2
is 2ndなど)。同じ値が複数のサーブレットのために指定されている場合、それらのサーブレットの各々は、それらが現れるのと同じ順序でロードされるweb.xml
、web-fragment.xml
または@WebServlet
クラスローディング。「load-on-startup」値が存在しない場合、このinit()
メソッドは、HTTPリクエストが初めてそのサーブレットにヒットするたびに呼び出されます。
サーブレットコンテナが上記の初期化手順のすべてで終了するServletContextListener#contextInitialized()
と、が呼び出されます。
ダウンサーブレットコンテナの閉まりが、それはすべてのWebアプリケーションをアンロードすると、呼び出しdestroy()
の初期化サーブレットとフィルタ、およびすべてのすべての方法をServletContext
、Servlet
、Filter
およびListener
インスタンスがゴミ箱に移動されています。最後にServletContextListener#contextDestroyed()
が呼び出されます。
HttpServletRequestおよびHttpServletResponse
サーブレットコンテナは、特定のポート番号でHTTPリクエストをリッスンするWebサーバーに接続されます(通常、ポート8080は開発時に使用され、ポート80は本番環境で使用されます)。クライアント(Webブラウザ、または持つ例えば、ユーザ場合は、プログラムで使用してはURLConnection
)HTTPリクエストを送信し、サーブレットコンテナは、新規作成HttpServletRequest
とHttpServletResponse
オブジェクトと定義されているすべてのを介してそれらを通過しFilter
、最終的には、チェーン内およびServlet
インスタンスを。
filtersの場合、doFilter()
メソッドが呼び出されます。サーブレットコンテナのコードがを呼び出すchain.doFilter(request, response)
と、リクエストとレスポンスは次のフィルタに進みます。フィルタが残っていない場合は、サーブレットにヒットします。
サーブレットの場合、service()
メソッドが呼び出されます。デフォルトでは、このメソッドは、にdoXxx()
基づいて呼び出すメソッドの 1つを決定しますrequest.getMethod()
。決定されたメソッドがサーブレットにない場合、HTTP 405エラーが応答で返されます。
リクエストオブジェクトは、URL、ヘッダー、クエリ文字列、本文など、HTTPリクエストに関するすべての情報へのアクセスを提供します。応答オブジェクトは、HTTP応答を制御して送信する機能を提供します。たとえば、ヘッダーと本文を設定できます(通常、JSPファイルから生成されたHTMLコンテンツを使用)。HTTP応答がコミットされて終了すると、要求オブジェクトと応答オブジェクトの両方がリサイクルされ、再利用できるようになります。
HttpSession
クライアントが初めてwebappにHttpSession
アクセスしrequest.getSession()
たり、を介して初めてを取得したりすると、サーブレットコンテナは新しいHttpSession
オブジェクトを作成し、長い一意のID(これはで取得できますsession.getId()
)を生成して、サーバーのメモリ。サーブレットコンテナはまた、セットCookie
にSet-Cookie
したHTTPレスポンスのヘッダJSESSIONID
の名前とその値として一意のセッションIDとして。
HTTP Cookie仕様(適切なWebブラウザーとWebサーバーが順守する必要がある契約)に従って、クライアント(Webブラウザー)はCookie
、Cookieが有効である限り、ヘッダー内の後続のリクエストでこのCookieを送り返す必要があります(つまり、一意のIDは、有効期限が切れていないセッションを参照している必要があり、ドメインとパスは正しいです)。ブラウザーの組み込みHTTPトラフィックモニターを使用して、Cookieが有効であることを確認できます(Chrome / Firefox 23以降/ IE9以降ではF12を押し、[ ネット/ネットワーク ]タブを確認します)。サーブレットコンテナはCookie
、すべての着信HTTPリクエストのヘッダーで名前付きのCookieの存在を確認し、JSESSIONID
その値(セッションID)を使用しHttpSession
てサーバーのメモリから関連付けを取得します。
HttpSession
それはで指定された以上のタイムアウト値のために(すなわち要求で使用されていない)アイドル状態になっているまで生きて滞在<session-timeout>
の設定、web.xml
。タイムアウト値のデフォルトは30分です。そのため、クライアントが指定された時間よりも長い間Webアプリケーションにアクセスしない場合、サーブレットコンテナはセッションを破棄します。Cookieが指定されていても、以降のすべてのリクエストは同じセッションにアクセスできなくなります。サーブレットコンテナが新しいセッションを作成します。
クライアント側では、ブラウザインスタンスが実行されている限り、セッションCookieは存続します。そのため、クライアントがブラウザインスタンス(すべてのタブ/ウィンドウ)を閉じると、クライアント側でセッションが破棄されます。新しいブラウザインスタンスでは、セッションに関連付けられたCookieは存在しないため、送信されなくなります。これにより、まったくHttpSession
新しいセッションCookieが使用されて、まったく新しいものが作成されます。
手短に
ServletContext
長いWebアプリケーションの命と同じくらいのために命。すべてのセッションのすべてのリクエストで共有されます。
HttpSession
限り、クライアントが同じブラウザインスタンスを使用したWebアプリケーションと対話している、とのセッションはサーバー側でタイムアウトしていないとのために命。同じセッションのすべてのリクエストで共有されます。
HttpServletRequest
そしてHttpServletResponse
完全な応答(Webページ)が到着するまでサーブレットは、クライアントからのHTTPリクエストを受信した時点からのライブ。それはされていない他の場所で共有しました。
- すべて
Servlet
、Filter
およびListener
インスタンスは、Webアプリが存続している限り存続します。それらはすべてのセッションのすべてのリクエストで共有されます。
- 任意
attribute
に定義されていることServletContext
、HttpServletRequest
およびHttpSession
質問の生活の中で対象限り生き続けます。オブジェクト自体は、JSF、CDI、SpringなどのBean管理フレームワークの「スコープ」を表します。これらのフレームワークは、スコープがattribute
一致するBeanを、最も近い一致スコープとして格納します。
スレッドセーフ
そうは言っても、あなたの主要な懸念はおそらくスレッドの安全性です。これで、サーブレットとフィルターがすべてのリクエスト間で共有されることがわかります。これはJavaのいいところです。マルチスレッドであり、異なるスレッド(読み取り:HTTPリクエスト)が同じインスタンスを使用できます。さもなければ、再作成するにはコストがかかりすぎて、すべてのリクエストに対してそれらは高くinit()
なりdestroy()
ます。
また、あなたがすべきことを認識すべきである決してとして任意の要求またはセッションスコープのデータを割り当てていないインスタンスのサーブレットまたはフィルタの変数。他のセッションの他のすべてのリクエスト間で共有されます。それはスレッドセーフではありません!以下の例はこれを示しています:
public class ExampleServlet extends HttpServlet {
private Object thisIsNOTThreadSafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadSafe;
thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
}
}
以下も参照してください。