JSR-000315
先日ご紹介した Quality Community メーリングリストのメッセージにて、 Servlet 3.0 公開ドラフト仕様書、 JSR-000315 を参照する様アドバイスを受けたため、早速読んでみることにしました。
因みにこの Servlet 3.0 の仕様については、昨年出席した Webinar にて、そのテクノロジープレビューに関するプレゼンを聞き、中でも特に、「サーブレットの非同期処理」、について、とても興味が沸いたことがきっかけです。
早速以下のページにて、 "download" をクリックして、ドキュメントをダウンロードします。
![[写真]](http://www3.atword.jp/jacksparrow/files/2009/03/jsr000315_01.jpg)
次の画面で、 "agree" をチェックして、 "continue" をクリックします。
ダウンロードするには、ダウンロードしたいチェックボックスにチェックした後、 "Download Selected with Sun Download Manager" をクリックして、ダウンロードマネージャーを起動する為の jnlp ファイルを取得します。
取得した jnlp ファイルをダブルクリックすると、 javaws から、ダウンロードマネージャーと言うアプリケーションが起動されます。このアプリケーションを使って、ファイルのダウンロードを行うことになります。以下の画面が表示されたら、 "ACCEPT" をクリックします。
先ほどチェックボックスにチェックした、2つのドキュメントが、ウィンドウに表示されます。 "start" をクリックすると、ダウンロードが開始されます。
無事ダウンロード完了したので、 PDF ファイルを開いて習読開始! これ全部読むのは大変なので、指しあたっては今回利用した、「 Async Servlet 」の部分のみにフォーカスしました。物はついでと思い、翻訳などもしてみました。
2.3.3.3 Asynchronous processing※上記訳文は、あくまで私が、 Servlet 3.0 Specification を学習するために訳した、参考訳文です。間違っている箇所等あれば、是非コメントしてください。 (*`д´)b OK♪
->2.3.3.3 非同期処理
Some times a filter and/or servlet is unable to complete the processing of a request without waiting for a resource or event before generating a response. For example, a servlet may need to wait for an available JDBC connection, for a response from a remote web service, for a JMS message, or for an application event, before proceeding to generate a response. Waiting within the servlet is an inefficient operation as it is a blocking operation that consumes a thread and other limited resources. Frequently a slow resource such as a database may have many threads blocked waiting for access and can cause thread starvation and poor quality of service for an entire web container.
->フィルターもしくは、サーブレットは時々、レスポンスが生成される前の、リソース、又は、イベントを待つことなく、リクエスト処理を完了できない時があります。例えば、サーブレットは、レスポンス生成開始前に、利用可能な JDBC 接続、リモート Web サービスからのレスポンス、 JMS メッセージ、又は、アプリケーションイベントを待つ必要があります。サーブレットの待機は、スレッドの消費と、他の制限的なリソースが、操作をブロックすると言う、能率の悪い操作です。たびたび、データベースのような、時間を要するリソースは、アクセスを待機している沢山のブロックされたスレッドを持ち、それがスレッドの窮乏が原因となり得ると同時に、サービスの劣化によって、 Web コンテナー全体に対して影響を及ぼします。
Servlet 3.0 introduces the ability for asynchronous processing of requests so that the thread may return to the container and perform other tasks. When asynchronous processing begins on the request, another thread or callback may either generate the response and call complete or dispatch the request so that it may run in the context of the container using the AsyncContext.forward method. A typical sequence of events for asynchronous processing is:
->Servlet 3.0 は、スレッドをコンテナーに返却し、他のタスクを実行する、リクエストの非同期処理の為の、機能を導入します。リクエストに対し非同期処理が開始すると、他のスレッドもしくはコールバックが、レスポンスを生成し完了を呼び出す、もしくは AsyncContext.forward メソッドを使用してリクエストをディスパッチし、コンテナのコンテキストで実行するようにします。非同期処理による、標準的なイベントの順序については :
1. The request is received and passed via normal filters for authentication etc. to the servlet.
-> 1. リクエストが受信されて、認証など、標準のフィルター経由で、サーブレットへ渡される。
2. The servlet processes the request parameters and/or content to determine the nature of the request.
->2. サーブレットは、リクエストの性質を測定する為に、リクエストパラメーターあるいは、コンテンツを処理する。
3. The servlet issues requests for resources or data, for example, sends a remote web service request or joins a queue waiting for a JDBC connection.
->3. サーブレットは、リソース、もしくは、データ向けにリクエストを発行する。例えば、 sends a 遠隔の web サービスへのリクエストや、 JDBC 接続への待機している待ち行列に、接続を送信する。
4. The servlet returns without generating a response.
->4. サーブレットは、レスポンス生成なしに、返却する。
5. After some time, the requested resource becomes available, the thread handling that event continues processing either in the same thread or by dispatching to a resource in the container using the AsyncContext.
->5. しばらくした後で、リクエストされたリソースは、利用可能になり、スレッドの操作は、同一スレッド上、あるいは、非同期コンテキストを使用しているコンテナー上にあるリソースに、ディスパッチすることにより、イベント処理を継続する。
Java Enterprise Edition features such as a Web Application Environment (SRV14.2.2) and Propagation of Security Identity (SRV.14.3.1) are available only to threads executing the initial request or when the request is dispatched to the container via the AsyncContext.forward method. Java Enterprise Edition features may be available to other threads operating directly on the response object via the asyncContext.start(Runnable) method. The @WebServlet and @ServletFilter annotations described in Chapter 8 have attributes - asyncSupported that is a boolean with a default value of false and an asyncTimeout.
->Java Enterprise Edition 中の Web アプリケーション環境 (SRV 14.2.2) やセキュリティアイデンティティの伝播 (SRV 14.3.1) 等の機能は、最初のリクエストを実行しているスレッドにおいて、もしくは AsyncContext.forward を使用してリクエストがコンテナにディスパッチされた場合にのみ利用可能です。 Java エンタープライズ版は、レスポンスオブジェクトが、 asyncContext.start(Runnable) メソッドを経由している上で、直接他のスレッドの操作を利用可能である特徴があります。 false と asyncTimeout のデフォルト値を持つ、 boolean である属性 - asyncSupported を持っている、 @WebServlet と @ServletFilter の注釈は、 8 章に掲載されています。
When asyncSupported is set to true the application can start asynchronous processing in a separate thread by calling startAsync (see below) passing it a reference to the request and response objects and then exit from the container on the original thread. This means that the response will traverse (in reverse order) the same filters (or filter chain) that were traversed on the way in. This will be the filters' only shot at modifying the response (e.g., by adding response headers). The response isn't committed till complete (see below) is called on the AsyncContext.
->asyncSupported が、 true に設定された場合、アプリケーションは、 startAsync ( 以下を参照 ) を呼び出して、それを引き渡し、リクエストとレスポンスのオブジェクトを参照し、そして、元のスレッド上のコンテナーから抜け出すことによって、別々なスレッド上で、非同期処理を開始できます。これは、レスポンス (逆順序で) は、入り口で横断された、同一のフィルター ( 又はフィルターチェーン ) を、横断することを意味しています。これは単に、フィルターが、レスポンス修正 (e.g., レスポンスヘッダーに追加することによって ) を試行することです。コミットが完了していないレスポンス (以下参照) は、 AsyncContext 上で、呼び出されます。
Dispatching from a servlet that has asyncSupported=true to one where asyncSupported is set to false is allowed. In this case, the response will be committed when the service method of the servlet that does not support async is exited, and it is the container's responsibility to call complete on the AsyncContext, so that any interested AsycListener instances will be notified. The AsyncListener.complete notification should also be used by filters as a mechanism to clear up resources that it has been holding on to for the async task to complete.
->サーブレットからのディスパッチは、 asyncSupported が false に設定にされている、ひとつの場所で、 asyncSupported=true を持つことが出来ます。このケースでは、非同期がサポートされていない、サーブレットのサービスメソッドから抜けて、AsyncContext 上で、完了が呼び出されることは、コンテナーの義務であることから、通知される AsycListener のインスタンスを関係付けた場合、レスポンスはコミットされます。又、 AsyncListener.complete の通知は、完了されるべき非同期タスク向けに、保持しているリソースをクリーンアップする為の機構として、フィルターによって利用される必要があります。
Dispatching from a synchronous servlet to an asynchronous would be illegal. However the decision of throwing an IllegalStateException to the point when the application calls startAsync. This would allow a servlet to either function as a synchronous or an asynchronous servlet.
->同期しているサーブレットから非同期へのディスパッチは、制約違反です。どのような場合でも、アプリケーションが、 startAsync が呼び出されたときに、そのポイントに向けて、 IllegalStateException がスローされます。これは、サーブレットを、同期、非同期のどちらか一方の機能として、利用可能であると言うことです。
The async task that the application is waiting for could write directly to the response, on a different thread than the one that was used for the initial request. This thread knows nothing about any filters. If a filter wanted to manipulate the response in the new thread, it would have to wrap the response when it was processing the initial request "on the way in", and passed the wrapped response to the next filter in the chain, and eventually to the servlet. So if the response was wrapped (possibly multiple times, once per filter), and the application processes the request and write directly to the response, it is really writing to the response wrapper(s), i.e., any output added to the response will still be processed by the response wrapper(s). When an application reads from a request in a separate thread, and add output to the response, it really reads from the request wrapper(s), and writes to the response wrapper(s), so any input and/or output manipulation intended by the wrapper(s) will continue to occur.
->アプリケーションがレスポンスに対して、直接書き込みできるようになるまで、待機している非同期のタスクは、異なるスレッド上のうちのひとつで、初期リクエストに向けて、使用されます。このスレッドは、いくつかのフィルターについて、何も認識していません。もし、新しいスレッドにて、フィルターを操作したいのであれば、初期リクエストを処理している"処理途上"で、次のフィルターチェーンへラップされたレスポンスを、最終的にサーブレットへ渡している時に、レスポンスをラップしなければなりません。つまり、レスポンスがラップされ ( 場合により何度も ) 、アプリケーションが、リクエストを処理し、レスポンスを直接書き出した場合、それは実際に、 i.e. 等の出力が、レスポンスラッパーによって、レスポンスが処理されている間に追加されて、レスポンスラッパーへ書き込みます。個別のスレッドにて、アプリケーションが、リクエストを読込み、レスポンスへ出力を追記した場合、それは実際に、ラッパーが発生し続けることによる、入力もしくは、出力の操作を意図した、リクエストラッパーから読み込み、レスポンスラッパーへ書き出しをします。
Alternately if the application chooses to do so it can use the AsyncContext to forward the request from the new thread to a resource in the container. This would enable using content generation technologies like JSP within the scope of the container.
->もし、アプリケーションが、交互に実行することを選択した場合は、それは、新たなスレッドからの、コンテナー上のリソースを、リクエストへ転送するために、非同期コンテキストを使用できます。これは、コンテナーのスコープにある、 JSP のおうな、コンテンツ生成技術を使用可能であると言うことです。
asyncTimeout if specified will be the time before which the connection is closed.
->asyncTimeout が、指示するまでの経過時間によっては、接続は遮断されます。
In addition to the annotation attributes we will have the following methods / classes added
->注釈属性に加えて、以下に追加された methods / classes を持っています。
■ ServletRequest
■ public AsyncContext startAsync(ServletRequest req, ServletResponse res). This would ensure that the response isn't commited when the application exits out of the service method. This could be used to write to the response from the async thread. It can also be used to just notify that the response is not closed and committed. The AsyncContext returned from this can then be used for further async processing.
->public AsyncContext startAsync(ServletRequest req, ServletResponse res). これは、コミットされていないレスポンスを、アプリケーションが、サービスメソッドから抜け出る時に、保証します。これは、非同期スレッドからのレスポンスを、書き出す為に使用できました。それはまた、レスポンスがクローズとコミットの両方がされていないことを、すぐに通知するために、使用できます。ここから返却された、非同期コンテキストは、更に、非同期処理向けに使用されることが可能です。
■ public AsyncContext startAsync() is provided as a convenience that uses the original request and response objects for the async processing. Please note users of this method MUST flush the response if they are wrapped before calling this method to ensure that any data written to the wrapped response isn’t lost.
->public AsyncContext startAsync() は、非同期処理向けの、元のリクエストとレスポンスのオブジェクトを使用している、便利なものとして規定されています。ラップされたレスポンスを消失しないために、書き込まれたいくつかのデータを保障する為、このメソッドを呼び出す前にそれらをラップした場合、このメソッドは、レスポンスをフラッシュしなければならないことを、どうか覚えておいてください。
■ public AsyncContext getAsyncContext() - returns the AsyncContext if startAsync was called. It is illegal to call getAsyncContext without having if the request has not been put in asynchronous mode.
->public AsyncContext getAsyncContext() - startAsync が呼び出された場合、非同期を返却します。リクエストが非同期モードで put されていない場合に、何も持たずに、 getAsyncContext が呼び出されることは、違反です。
■ public boolean isAsyncSupported() - Returns true if the request supports async processing, and false otherwise. Async support will be disabled as soon as the request has passed a filter or servlet that does not support async processing (either via the designated annotation or declaratively).
->public boolean isAsyncSupported() - リクエストが非同期処理をサポートしている場合に true を、そうでなければ false を返却します。非同期のサポートは、非同期のサポートは、非同期処理をサポート ( 指定された注釈か、宣言のどちらか一方 ) していないリクエストが、フィルター、あるいはサーブレットに転送されると同時に、破棄されます。
■ public boolean isAsyncStarted() - Returns true if async processing has started on this request, and false otherwise
->public boolean isAsyncStarted() - 非同期処理が、リクエストを開始した場合は true を、そうでなければ false を返却します。
■ public void addAsyncListener(asyncListener, req, res) - registers a listener for notifications of timeout and complete. The request and response objects passed in to the method are the exact same ones that are available from the AsyncEvent when the AsyncListener is notified. The request and response could be wrapped or not.
->public void addAsyncListener(asyncListener, req, res) - タイムアウトと完了の通知によって、リスナーを登録します。リクエストとレスポンスのオブジェクトは、非同期リスナーが通知された場合、非同期イベントから利用可能である、的確な同一のメソッドに転送されます。リクエストとレスポンスが、ラップできるできないに関わらず。
■ public void addAsyncListener(asyncListener) - registers the given listener for notifications of timeout and complete. If startAsync(req, res) or startAsync() is called on the request, the exact same req and response objects are available from the AsyncEvent when the AsyncListener is notified. The request and response could be wrapped or not.
->public void addAsyncListener(asyncListener) - タイムアウトと完了の通知向けに与えられたリスナーを、登録します。 startAsync(req, res) 又は、 startAsync() が、リクエスト上で呼び出された場合、 非同期リスナーが通知された時に、的確な同一のリクエストとレスポンスオブジェクトが、非同期イベントから利用可能になります。リクエストとレスポンスが、ラップできるできないに関わらず。
■ public void setAsyncTimeout(long timeoutMilliseconds) - This is the timeout for the async processing to occur. Call to this method overrides the timeout set via the annotation attribute or deployment descriptor. If the timeout is not specified either via the call to the setAsyncTimeout or via the annotations / descriptors then a container default will be used.
->public void setAsyncTimeout(long timeoutMilliseconds) - これは、非同期処理が発生しているタイムアウトです。指定している注釈属性、又は、デプロイメントディスクリプターを設定しているタイムアウトをオーバーライドしたメソッドを呼び出します。タイムアウトが、指定している setAsyncTimeout を呼び出すか、指定している注釈 / ディスクリプターのどちらか一方を、指定していなければ、コンテナーのデフォルトが、使用されます。
■ AsyncContext - This class represents the execution context for the asynchronous operation that was started on the ServletRequest. The following methods are in the AsyncContext -
->AsyncContext - このクラスは、 ServletRequest 上で開始された、非同期操作向けのコンテキストの実行を表します。次のメソッド群は、 AsyncContext に存在します。 -
■ public ServletRequest getRequest() - returns the request that was used to initialize the AsyncContext by calling one of the startAsync methods.
->public ServletRequest getRequest() - startAsync メソッドのうちの1つを呼び出すことによって、 AsyncContext を初期化する為に、利用されるリクエストを返却します。
■ public ServletResponse getResponse() - returns the response that was used to initialize the AsyncContext by calling one of the startAsync methods.
->public ServletResponse getResponse() - startAsync メソッドのうちの1つを呼び出すことによって、 AsyncContext を初期化する為に、利用されるレスポンスを返却します。
■ public void forward(path) - forwards the request and response that were used to initialize the AsyncContext to the resource with the given path. The given path is interpreted as relative to the ServletContext that initialized this AsynContext.
->public void forward(path) - 与えられたパスにあるリソースによって、 AsyncContext を初期化する為に利用される、リクエストとレスポンスへ進みます。与えられたパスは、この AsynContext を初期化している ServletContext との相関として、正しく解釈されます。
■ public void forward() - Provided as a convenience to forward the request and response used to initialize the AsyncContext to the original URI of the request. A subsequent call to forward() after a AsyncContext.forward(path) or a RequestDispatcher.forwar(req, res) will dispatch to the target resource identified by the given path in the AsyncContext.forward(path) or the path used to acquire the RequestDispatcher.
->public void forward() - リクエストの元の URI によって、 AsyncContext を初期化を利用しているリクエストと、レスポンスへ進む為の、便利なものと規定しています。あるサブシーケンスは、 AsyncContext.forward(path) 又は、パスが RequestDispatcher を取得する為に利用されている上で、 AsyncContext.forward(path) 又は、 RequestDispatcher.forwar(req, res) が、与えられたパスによって、認識された対象のリソースへ、ディスパッチされた後で、 forward() を呼び出します。
■ public boolean hasOriginalRequestAndResponse() - Checks if this AsyncContext was initialized with the original request and response objects by calling ServletRequest.startAsync() , in which case it returns true, or if it was initialized with wrapped request and/or response objects using ServletRequest.startAsync(ServletRequest, ServletResponse), in which case it returns false. This information may be used by filters invoked in the outbound direction, after a request was put into asynchronous mode, to determine whether any request and/or response wrappers that they added during their inbound invocation need to be preserved for the duration of the asynchronous operation, or may be released.
->public boolean hasOriginalRequestAndResponse() - この AsyncContext が、 ServletRequest.startAsync() を呼び出し、元のリクエストとレスポンスのオブジェクトによって、初期化された場合、そのケースにおいては true を返却し、又一方で、 ServletRequest.startAsync(ServletRequest, ServletResponse) を利用している、ラップされたリクエスト、もしくはレスポンスのオブジェクトによって、初期化されている場合、そのケースにおいては false を返却すると言う、チェックを行います。この情報は、フィルターが、外部から呼び出された時に利用されます。リクエストが、非同期モードに設定された後で、リクエスト、もしくは、レスポンスが、それらの入力に対する起動が、非同期操作の持続によって、維持する、又は、開放されるために必要としている間、それらは追加された、ラッパーがあろうと無かろうと、決定します。
■ public void forward(ServletContext context, String path) - forwards the request and response used to initialize the AsyncContext to the resource with the given path in the given ServletContext.
->public void forward(ServletContext context, String path) - 与えられている、サーブレットコンテキスト上に、パスを与えられることによって、AsyncContext を初期化する為に利用される、リクエストとレスポンスを、リソースへ転送します。
■ For all the 3 variations of the forward methods defined above, the methods are equivalent in semantics to RequestDispatcher.forward(req, res) except that it returns immediately. Control of the request and response objects of this AsyncContext is handed off to the target resource and the response will close when the target resource of the dispatch has completed execution and a subsequent call to startAsync has not been made. 14 Java Servlet Specification • December 2008
-> 3 つ全ての転送メソッド上に定義されているメソッドは、 RequestDispatcher.forward(req, res) が、すぐさま返却すると言うことを除いては、動作は同等です。この、 AsyncContext のリクエストとレスポンスオブジェクトの制御は、処理対象のリソースへ手渡され、そしてレスポンスは、ディパッチされた対象のリソースが、実行を完了し、サブシーケンスが、 startAsync の呼び出しを完了していない場合は、クローズします。 14 Java Servlet 仕様 2008 年 12 月
■ public void start(Runnable r) - dispatches a container thread to run the specified Runnable in the ServletContext that initialized the AsyncContext. This method sets up the appropriate contextual information for the Runnable. Workmanager integration will happen once the API becomes available.
->public void start(Runnable r) - 初期化された AsyncContext 、サーブレットコンテキスト上で、特定の Runnable を実行する為に、コンテナースレッドをディスパッチします。このメソッドは、 Runnable へ、適切なコンテキスト上の情報を、セットアップします。ワークマネージャーの統合は、 API を利用可能にするために、一度だけ起きます。
■ public void complete() - If request.startAsync() then this method MUST be called to complete the async processing, that is, close the response. The complete method can be invoked by the container if the request is dispatched to a servlet that does not support async processing, or the target servlet to which the request is forwarded via the AsyncContext.forward does not do a subsequent call to startAsync. In this case, it is the container's responsibility to call complete() as soon as that servlet's service method is exited. An IllegalStateException MUST be thrown if startAsync was not called.
-> public void complete() - request.startAsync() が呼び出された場合、このメソッドは、レスポンスをクローズして、非同期処理を完了するために、呼び出されなければなりません。リクエストが、非同期処理をサポートしていないサーブレット、又は、リクエストが転送される、規定の AsyncContext.forward が、サブシーケンスにおいて、 startAsync を呼び出していない、対象のサーブレットによってディパッチされた場合、メソッドの完了は、コンテナーによって呼び出されます。このケースでは、サーブレットのサービスから抜け出ると同時に、 complete() を呼び出すと言うことが、コンテナーの義務となります。 startAsync が呼び出されなかった場合、 IllegalStateException がスローされなければなりません。
■ Async processing in JSP would not be supported by default as it is used for content generation and async processing would have to be done before the doing the content generation. It is upto the container how to handle this case. Once all the async activities are done, a dispatch to the JSP page using the AsyncContext.forward can be used for generating content.
->JSP での非同期処理は、コンテンツの生成に利用されることと、コンテンツを生成している以前に、非同期処理が完了しなければならないとして、デフォルトではサポートされていません。このケースを操作する方法は、コンテナー次第です。一度全ての非同期の活動は、完了され、コンテンツ生成の為に、利用可能な AsyncContext.forward を利用している、 JSP ページ向けにディスパッチされます。
■ Any attempt from the async task to write to the response or read from the request blocks for as long as the original thread was still holding on to the request/response objects. This locking semantics would only be enabled when asyncSupported attribute is set to true
->レスポンスの出力、又は、リクエストの読み出しの為の、非同期タスクの何回かは、 request/response オブジェクトを掴み続けている、元のスレッドと同じくらいの間、ブロックします。このロックの動作は、 asyncSupported 属性に、 true が設定された場合にのみ、利用可能です。
「(゚~゚o)ウゥーン、これを読む限りでは、非同期処理を行うサーブレットの実装に際しては、結構いろいろなことを post 乃至は get メソッドの中で、やらせる様に実装して行かなければならない様ですね。
以前私は、このブログにこの、 "Servlet3.0 Async specification" に従って、チャットサーブレットなるサンプルを作成しようとしていたのですが、中々上手く動かずに、断念した記憶があります。もう少しこの仕様について、熟知した上で、実装作業に取りかかる必要がありそうですね。
因に、かなり以前に私が書いたコードは以下のとおりです。
import java.io.IOException;これだと、まだ不十分と言うことだけは理解できました。
import java.util.ArrayList;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import javax.naming.Context;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.annotation.WebServlet;
/**
* @author Captain Jack Sparrow
*/
@WebServlet(urlPatterns = {"/AsyncWebApplication"}, asyncSupported = true)
public class ChatService extends HttpServlet {
/** Serial Ver */
private static final long serialVersionUID = 2825256419920406849L;
/**
* Processes requests for both HTTP GET and POST methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
AsyncContext aCtx;
try {
aCtx = request.startAsync();
if(request.getServletContext().getAttribute("message") == null) {
ArrayList<Object> messageList = new ArrayList<Object>();
request.getServletContext().setAttribute("message", messageList);
}
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.execute(new AsyncChatMessage(aCtx));
} catch(Exception ex) {
StackTraceElement[] stackTrace = ex.getStackTrace();
@SuppressWarnings("unchecked")
ArrayList<Object> messageList = (ArrayList)request.getServletContext().getAttribute("message");
messageList.add(ex.getLocalizedMessage());
final StringBuilder stackTraceBuffer = new StringBuilder();
for(int i=0; i<stackTrace.length; i++) {
stackTraceBuffer.append(stackTrace[i].getLineNumber()).append(" - ").append(stackTrace[i].getClassName());
messageList.add(stackTraceBuffer.toString());
request.getRequestDispatcher("/AsyncWebApplication/chat.jsp").forward(request, response);
}
} finally {
}
}
//
/**
* Handles the HTTP GET method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP POST method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}//
}
もう既に着手されている方も、いるのでは無いかと思うのですが、ご存知の方、いらっしゃったら、是非コメント宜しくお願いします。又、参考訳文についても、間違っている可能性もあるので、どなたかコメントして頂けると助かります。合わせて宜しくお願いします。
サン・マイクロシステムズ イベント情報
サン・マイクロシステムズ キャンペーン情報



Write a comment