Servlet 3.1 フィーチャーの機能
Servlet 3.1 フィーチャーは、Servlet 3.1 仕様の完全なサポートを提供します。
新しい Servlet 3.1 の機能の説明は、Servlet 3.1 仕様に記載されているため、ここでは記載していません。ただし、Servlet 3.1 フィーチャーの追加の考慮事項を以下に示します。
非同期入出力
Servlet 3.1 フィーチャーの新機能では、ノンブロッキング読み取りが開始された場合、残りの要求存続期間にリソースで API を呼び出すことができないことが指定されています。このため、ブロッキング読み取りになる可能性があります。例えば、読み取りリスナーがリソースによって設定された後の POST 要求の場合、その後 getParameter() および getPart() API を呼び出すと、IllegalStateException が生じます。
非同期サーブレットで作業する場合、AsyncContext.setTimeout API でタイムアウトを設定することを考慮する必要があります。設定しないと、コンテナーのデフォルト値 (例えば、30 秒) が使用されます。非同期が ServletRequest を使用して開始するたびに、タイムアウトはリセットされます。StartAsync API が呼び出され、最後の非同期が開始された後のタイムアウト期間内に AsyncContext.complete API が呼び出されなかった場合、有効期限が切れます。Servlet-3.1 フィーチャーで提供されている非同期入出力サポートを使用する場合、非同期入出力も完了できるようするには、AsyncContext.setTimeout API を使用してタイムアウト値を設定します。完了は、環境やネットワーク速度などの他の外部要因に依存します。
アップグレードの処理
<webContainer upgradeReadTimeout="5000" />
<webContainer upgradeWriteTimeout="5000" />
要求が非同期サーブレットによって処理されている場合、Servlet 3.1 のアップグレード機能を使用して要求をアップグレードしてはなりません。
アップグレード用 Servlet 3.1 フィーチャーをサポートするアプリケーションでは、クライアントとアップグレードをホストするアプリケーションとの間でアップグレードされた要求での接続が開いたままである必要があります。アプリケーションがそのハンドラーや他のリソース (ReadListener や WriteListener など) からのアップグレード処理の完了時に WebConnection close() を開始しなかった場合、TCP 接続はサーバーが再始動されるまで開いたままになります。
Servlet 3.1 フィーチャーからの UpgradeHandler および ReadListener を使用した場合、ReadListener.onAllDataRead メソッドが呼び出されるのは、アップグレードされたアプリケーションをホストしているサーバーへの接続をクライアントが閉じた場合のみです。onReadListener.onAllDataRead の Javadoc では、現在の要求のすべてのデータが読み取られると呼び出される、と記載されています。 アップグレードの場合、アップグレードされたデータは、HTTP 要求本体のデータのように区切られていないため、サーバーはデータの末尾を認識できません。クライアント接続が閉じられたタイミング以外に、データの末尾を判別する方法はありません。
フォーム・ベース認証
認証に成功すると、クライアントは、元の要求のリソースにリダイレクトされます。Servlet 3.1 仕様では、リダイレクトされた要求の HTTP メソッドの予測可能性を向上させるために、コンテナーは 303 (SC_SEE_OTHER) 状況コードを使用してリダイレクトする必要がある (ただし、HTTP 1.0 ユーザー・エージェントとの相互運用性が必要な場合は例外で、302 状況コードを使用する必要がある) ということが規定されています。Servlet-3.1 フィーチャーは、HTTP 1.0 ユーザー・エージェントとの相互運用性を維持するため、常に 302 状況コードを使用します。セキュリティーのための Servlet 3.1 の構成について詳しくは、トピック『Servlet 3.1のための Liberty プロファイルの構成』を参照してください。
大きなポスト・データ
ServletRequest.getContentLengthLong() API を追加するには、Integer.MAX_VALUE より大きく、1 バイト配列やストリングで完全には対応できないポスト・データの受信をサポートする必要があります。
String getParamter(String name)
String[] getParameterValues()
Map<String,String> getParameterMap()
複数のパラメーターが含まれていて、それぞれを合わせると長さが Integer.MAX_VALUE より大きくなるポスト・データを送信することは可能です。 ただし、それぞれの個別のパラメーター名とパラメーター値の長さが Integer.MAX_VALUE 未満でなければなりません。
- 長さが Integer.MAX-VALUE 未満のチャンクでポスト・データを送信する必要があります。
- パラメーターやパートなど、Web コンテナーによって処理されるポスト・データは、処理の開始前に完全に読み取る必要があります。ポスト・データでは、大きいポスト・データのために大量のメモリー所要量が必要になることがあります。これは、Web コンテナー処理を成功させるために、最大でポスト・データの倍のサイズのメモリーが必要になることがあるためです。