ここでは、GlassFish3.1でServletの非同期処理の設定方法についてご紹介します。
■非同期処理って何?
Servletは通常、ブラウザからリクエストを受け付けたThreadでServletが処理をしてレスポンスをブラウザに返します。
コレが同期処理です。
同期処理で困るのが、Servletでの処理時間が長いと、ブラウザが待たされることです。
コレに対応するのが、非同期処理です。
非同期処理では、ブラウザがらリクエストを受け付けたThreadとは別のThreadで処理をすることができます。
非同期処理は、時間のかかる処理を行うのに使ったり、
Chatなど、レスポンスのタイミングをコントロールしたい時に使用します。
では、非同期処理の実装の仕方。
やることは2つです。
1. HttpServletRequest#startAsync()を使う。
2. web.xmlをServlet3.0対応にし、非同期処理を扱うすべてのルーティーン(FilterとServlet)で非同期処理を有効にする。
では、詳細を。
1. HttpServletRequest#startAsync()を使う。
filterやservletのリクエストを受け取るメソッドの中で、
AsyncContext asyncContext = request.startAsync();
を呼び出します。
それから、
asyncContext.start(Runnable);
で、非同期で処理したい内容を起動します。
例えば、↓みたいな感じです。
final AsyncContext asyncContext = request.startAsync();
asyncContext.start(new Runnable() {
@Override
publicvoid run() {
try {
//処理時間時間のかかる処理や待ち合わせ処理
//例えば、チャットの相手の文字入力を待つとか。
//・・・・
OutputStream out = asyncContext.getResponse().getOutputStream();
out.write("complete".getBytes());
asyncContext.complete();
} catch (Exception e) {
log.fatal("exception on wait", e);
}
}
});
asyncContext.start(new Runnable() {
@Override
publicvoid run() {
try {
//処理時間時間のかかる処理や待ち合わせ処理
//例えば、チャットの相手の文字入力を待つとか。
//・・・・
OutputStream out = asyncContext.getResponse().getOutputStream();
out.write("complete".getBytes());
asyncContext.complete();
} catch (Exception e) {
log.fatal("exception on wait", e);
}
}
});
2. web.xmlをServlet3.0対応にし、非同期処理を扱うすべてのルーティーン(FilterとServlet)で非同期処理を有効にする。
web.xmlをServlet3.0設定にします。
web.xmlのルートノードを、
<web-appversion="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
というように設定します。xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
さらに、filterタグやservletタグの中で、非同期処理をすることを宣言します。
例えば
<servlet>
<servlet-name>encodingfilter</servlet-name>
<servlet-class>net.ukiuni.EncodingFilter</servlet-class>
<async-supported>true</async-supported>
</servlet>
というようにasync-supportedタグを入れます。<servlet-name>encodingfilter</servlet-name>
<servlet-class>net.ukiuni.EncodingFilter</servlet-class>
<async-supported>true</async-supported>
</servlet>
この時に重要なのが、リクエストを受け付けるすべての処理(FilterやServlet)でasync-supportedタグを入れる必要がある、ということです。
Servletで処理をする前に、Filterでエンコーディングを設定したり、セキュリティーをかけてることがありますが、そのFilterにもasync-supportedタグを入れる必要があります。
これで、非同期処理ができるようになります。
■追記
あんまりGlassFishっぽくない、汎用的な説明になったので、GlassFishの情報を一つ。
GlassFishには、管理コンソールから「Cometを有効にする」設定ができますが、この設定をOnにしなくても、AsyncContextは使うことができます。
0 件のコメント:
コメントを投稿