Cosminexus V9 アプリケーションサーバ 機能解説 基本・開発編(Webコンテナ)
サーブレットを実装するときの注意事項を示します。
ServletResponseクラスのsetLocaleメソッドにLocale.JAPANESEを指定した場合,Content-TypeヘッダのcharsetはShift_JIS(シフトJIS)になります。
HttpServletRequestクラスのgetRequestURIメソッドでは,最適化されたURIが返されます。例えば,「xxx//yyy/zzz」は「xxx/yyy/zzz」に,「xxx/yyy/../zzz」は「xxx/zzz」のように変換されます。
WebサーバでPOSTデータの読み込みに失敗した場合,Webコンテナで動作するサーブレットでは,ServletRequestクラスの次に示すメソッドの呼び出し時にIllegalStateException例外が発生します。
また,Content-Typeがmultipart/form-dataのフォームデータを受信した場合は,上記のメソッドまたはHttpServletRequestクラスの次に示すメソッドの呼び出し時に,KDJE39336-E のメッセージの出力を伴うIllegalStateException例外が発生することがあります。この場合,受信したフォームデータのサイズが適切かどうかを確認し,適切なサイズのときはwebserver.connector.limit.max_post_form_dataの設定値を見直してください。
ServletContextAttributeListenerインタフェース,HttpSessionAttributeListenerインタフェース,およびServletRequestAttributeListenerでは,Webコンテナが内部で使用している属性の追加,削除,更新があった場合にもイベントが通知される場合があります。通知されたイベントの属性名を参照して,Webアプリケーションで使用している属性名以外の場合には無視するようにしてください。
Webアプリケーションに含まれるディレクトリにアクセスするときは,クエリ文字列およびPOSTデータがリダイレクト先リソースで取得できないことがあるため,クエリ文字列およびPOSTデータは付けないようにしてください。
ServletRequestインタフェースのgetRemoteHostメソッドは,リクエストを送信したクライアントのホスト名を返しますが,Webサーバがホスト名を解決できないか,解決しないように設定されている場合はIPアドレスを返します。
既定の設定ではWebサーバの設定がされていないため,IPアドレスを返します。ホスト名を取得する場合は,Webサーバの設定を変更する必要があります。ただし,設定を変更すると,ホスト名の解決のため,レスポンスが遅くなる場合があります。Webサーバの設定の変更方法については,マニュアル「HTTP Server」を参照してください。
1プロセス内で複数回実行してはならない処理をサーブレット中に記述する場合,サーブレットの実行とその処理が同期することがないようにしてください。特に,OTMとの通信を開始するための初期化処理の中には,インスタンスを削除しても終了しない常駐スレッドを生成するものがあります。例えば,TPBrokerの初期化関数であるORB.initメソッドは,呼び出されるたびにGC実行のための監視用常駐スレッドを生成し,このスレッドはプロセス終了まで消えません。そのため,1プロセス内でORB.initメソッドを必要以上に実行すると,不要なGC処理が増え,システム全体の性能が著しく低下するなどの悪影響があります。
このような事態を避けるため,プロセス中で1回だけ実行させたい処理をサーブレットに記述する場合には,その処理がプロセス中で実行済みかどうかをあらかじめ判定する必要があります。具体的には,ある処理が実行済みかどうかの状態を格納する条件フラグとしてstatic変数を任意のクラス中で用意します。static変数の値が「未実行」を意味するものである場合にだけ処理を実行し,値を「実行済み」を意味するものに変更することで,その処理の実行回数をプロセス中で1回だけに限定できます。ただし,次の2点に注意してください。
static org.omg.CORBA.ORB _orb=null; public static synchronized org.omg.CORBA.ORB getORB(String[] args, Properties props){ if(_orb==null){ _orb=org.omg.CORBA.ORB.init(args,props); } return _orb; } |
Webコンテナにゲートウェイ情報を通知し,welcomeファイルやFORM認証画面に正しくリダイレクトするゲートウェイ指定機能を使用できます。ゲートウェイ指定機能については,「4.10 Webコンテナへのゲートウェイ情報の通知」を参照してください。
ゲートウェイ指定機能を使用する場合,一部のサーブレットAPIの動作が変わります。ゲートウェイ指定機能使用時のサーブレットAPIの注意事項を,使用するメソッドごとに示します。
SSLアクセラレータや負荷分散器などのゲートウェイを使用した場合,次のサーブレットAPIの戻り値はクライアントのIPアドレスやホスト名ではなく,ゲートウェイのIPアドレスやホスト名になります。
Webコンテナは,Webアプリケーションの制御に必要な情報をjavax.servlet.ServletContextオブジェクトの属性に登録しています。WebアプリケーションでServletContextインタフェースのgetAttributeNamesメソッドによって取得する属性名には,Webコンテナによって登録された属性の名称も含まれます。
Webアプリケーション内でServletContextオブジェクトに属性を登録する時,次の文字列で開始するキー名称を使用しないでください。
また,ServletContextにはJava EEの仕様で定められた属性も追加されるため,これらと同じキー名称の属性を登録しないでください。
次に示すjavax.servlet.ServletRequestクラスのメソッドは,リクエストを送信したクライアント,または最後に通ったプロキシの情報を取得するためのメソッドですが,リバースプロキシを使用した環境では,取得する情報がリバースプロキシの情報となります。
javax.servlet.ServletResponseインタフェースのgetWriterメソッドを実行したあとに,resetメソッドを実行した場合,HTTPレスポンスのContent-Typeで指定する文字エンコーディングは,次に示すAPIのどれか(すべてjavax.servlet.ServletResponseインタフェース)を使用して,再度同じ文字エンコーディングを指定してください。
Servlet 2.4仕様以降では,これらのAPIを使用して文字エンコーディングを設定する場合は,getWriterメソッドを実行する前に呼び出す必要があります。ただし,getWriterメソッドを実行したあとにresetメソッドを実行した場合にかぎり,再度getWriterメソッドを呼び出すまではこれらのAPIで文字エンコーディングを設定できます。
javax.servlet.http.HttpSessionインタフェースのsetMaxInactiveIntervalメソッドの引数に0を指定した場合,セッションがタイムアウトになることはありません。
インプロセスHTTPサーバ機能を使用している場合に,javax.servlet.ServletRequestのgetReaderメソッドで得られるjava.io.BufferedReaderは,mark操作をサポートしていません。markSupportedメソッドではfalseが返されます。
javax.servlet.http.CookieのsetVersionメソッドの引数に1を指定した場合,Webサーバ連携機能使用時には,レスポンスにSet-Cookie2ヘッダが付加されますが,インプロセスHTTPサーバ機能使用時にはSet-Cookieヘッダが付加されます。
javax.servlet.ServletRequestのgetRequestDispatcherメソッドの引数に「/」ではじまらない相対パスを指定した場合,このサーブレットのサーブレットマッピングに指定したURLパターンからの相対パスになります。URLパターンが「/」で終わっている場合は,親のディレクトリからの相対パスになります。
例えば,サーブレットマッピングを"/a/b/"に指定したサーブレットから,"hello.html"を指定してgetRequestDispatcherメソッドを実行すると,"/a/hello.html"が得られます。
レスポンス送信時に使用されるサーブレットのバッファは,リクエスト処理スレッドごとに保持されます。javax.servlet.ServletResponseのsetBufferSizeメソッドを実行してバッファサイズを変更した場合,変更したバッファサイズは,同一J2EEサーバ上のほかのWebアプリケーションを含め,該当するスレッドが処理するすべてのリクエストに適用されます。javax.servlet.ServletResponseのsetBufferSizeメソッドを使用してバッファサイズを変更する場合は,(バッファサイズ)×(リクエスト処理スレッド数)分のメモリが確保されることを考慮した上で,メモリ使用量を見積もってください。
なお,一度確保されたバッファは,処理スレッドごとにWebアプリケーションからsetBufferSizeメソッドで更新されるまで有効となります。
サーブレットでは,javax.servlet.ServletResponseクラスのsetContentTypeメソッドで明示的にContent-Typeを設定していない場合,Content-Typeヘッダを作成しません。そのため,HTTPレスポンスの文字エンコーディングをContent-Typeヘッダの”charset=”フィールドから確認することはできません。
Servlet 2.4仕様以前に準拠したWebアプリケーションで,無効化されたjavax.servlet.http.HttpSessionオブジェクトのgetIdメソッドを呼び出した場合の動作がServlet仕様とアプリケーションサーバとで異なります。それぞれの動作を次に示します。
次の表に示すメソッドで取得した情報をレスポンスに出力する場合は,サニタイズする必要があります。
表6-13 取得した情報をサニタイズする必要があるメソッド
クラス名 | メソッド名 |
---|---|
javax.servlet.ServletRequest | getCharacterEncoding() |
getContentType() | |
getInputStream() | |
getParameter(java.lang.String name) | |
getParameterMap() | |
getParameterNames() | |
getParameterValues(java.lang.String name) | |
getProtocol() | |
getReader() | |
getServerName() | |
javax.servlet.http.HttpServletRequest | getCookies() |
getHeader(java.lang.String name) | |
getHeaderNames() | |
getHeaders(java.lang.String name) | |
getMethod() | |
getPathInfo() | |
getPathTranslated() | |
getQueryString() | |
getRequestedSessionId() | |
getRequestURI() | |
getRequestURL() | |
getServletPath() |
javax.servlet.ServletRequestクラスのgetLocaleメソッド,またはgetLocalesメソッドで取得できるjava.util.Localeオブジェクトは,HTTPリクエストのAccept-Languageヘッダの値から作成します。
Webコンテナでは,Accept-Languageヘッダの値のロケール(ISO言語コード,ISO国コード,またはバリアント)が英字以外を含むかどうかをチェックします。ロケールが英字以外を含む場合は,不正なロケールと判断して,不正なロケールごとにKDJE39546-Wのメッセージをメッセージログに出力して無視します。
不正なロケールを含むAccept-Languageヘッダを受信した場合は,getLocaleメソッド,またはgetLocalesメソッドは正しいロケールのjava.util.Localeオブジェクトだけを返します。Accept-Languageヘッダに指定されたロケールがすべて不正な場合は,Accept-Languageヘッダがないと見なしてサーバのデフォルトロケールを返します。
javax.servlet.http.HttpServletRequestインタフェースのgetServerNameメソッドの戻り値は,HTTP ServerやリバースプロキシなどでHostヘッダを書き換えた場合,HTTPクライアントが設定したHostヘッダの値と異なることがあります。
Servlet 2.4以前では,include先のサーブレットでのレスポンスヘッダの設定はすべて無視される仕様です。ただし,アプリケーションサーバでは,Servlet 2.4を使用した場合でも,getSessionでのレスポンスヘッダの設定は有効になります。
MIMEマッピングがない静的コンテンツの場合,Content-Typeは付与されません。
セッションIDの付加されたリクエストがWebコンテナに送信されたとき,HTTPセッションのアクセス時刻は現在時刻で更新されます。ただし,すでにセッションがタイムアウトしたり,無効化したりしている場合には該当しません。
HTTPセッションのアクセス時刻は次で使用されます。
HTTPリクエストにContent-Lengthヘッダが含まれていない場合,javax.servlet.ServletRequestのgetContentLength()メソッドの戻り値,およびjavax.servlet.http.HttpServletRequestのgetIntHeader()メソッドで引数に"Content-Length"を指定した場合の戻り値がServlet仕様とアプリケーションサーバとで異なります。それぞれの戻り値を次に示します。
All Rights Reserved. Copyright (C) 2012, 2015, Hitachi, Ltd.