8.2.1 サーブレットおよびJSP実装時共通の注意事項
アプリケーションサーバ上で動作するアプリケーションのプログラムとして,サーブレットおよびJSPを実装するときの共通の注意事項を示します。
- 〈この項の構成〉
-
-
(18) javax.servlet.ServletRequestオブジェクトのjavax.servlet.error.exception属性について
-
(21) javax.servlet.ServletRequestインタフェースのgetServerNameメソッドおよびgetServerPortメソッドの戻り値について
-
(22) javax.servlet.ServletExceptionクラスのコンストラクタで指定した根本原因の例外の取得について
-
(23) javax.servlet.ServletOutputStreamオブジェクトに対するflushメソッドの実行についての注意
-
(25) javax.servlet.http.HttpServletRequestインタフェースのgetRequestURIメソッドおよびgetRequestURLメソッドの戻り値について
-
(31) javax.servlet.http.HttpServletResponseインタフェースのcontainsHeaderメソッドについて
(1) Webアプリケーションの動作の前提となるJ2EEアプリケーションのバージョン
Webアプリケーションの動作の前提となるJ2EEアプリケーションが準拠するJ2EE仕様のバージョンについて,Webアプリケーションのバージョンごとに次の表に示します。
J2EEアプリケーションが準拠するJ2EE仕様のバージョン |
Webアプリケーションに対応するServlet仕様 |
|||||
---|---|---|---|---|---|---|
3.1 |
3.0 |
2.5 |
2.4 |
2.3 |
2.2 |
|
Java EE 7 |
○ |
○ |
○ |
○ |
○ |
○ |
Java EE 6 |
× |
○ |
○ |
○ |
○ |
○ |
Java EE 5 |
× |
× |
○ |
○ |
○ |
○ |
J2EE1.4 |
× |
× |
× |
○ |
○ |
○ |
J2EE1.3 |
× |
× |
× |
△ |
○ |
○ |
J2EE1.2 |
× |
× |
× |
△ |
△ |
○ |
(2) Webアプリケーションのサポート範囲
Webアプリケーションのバージョンは,web.xmlに記述するServlet仕様のバージョン情報で識別されます。上位のバージョンのWebアプリケーションは下位のバージョンの機能を使用できます。下位のバージョンのWebアプリケーションは上位のバージョンの機能を使用できません。
Webアプリケーションのバージョンごとに,使用できる機能範囲を次の表に示します。
Webアプリケーションのバージョン |
Servlet |
JSP |
タグライブラリ※ |
|||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
3.1 |
3.0 |
2.5 |
2.4 |
2.3 |
2.2 |
2.3 |
2.2 |
2.1 |
2.0 |
1.2 |
1.1 |
2.1 |
2.0 |
1.2 |
1.1 |
|
3.1 |
○ |
○ |
○ |
○ |
○ |
○ |
〇 |
〇 |
○ |
○ |
○ |
○ |
○ |
○ |
○ |
○ |
3.0 |
○ |
○ |
○ |
○ |
○ |
○ |
× |
〇 |
○ |
○ |
○ |
○ |
○ |
○ |
○ |
○ |
2.5 |
× |
× |
○ |
○ |
○ |
○ |
× |
× |
○ |
○ |
○ |
○ |
○ |
○ |
○ |
○ |
2.4 |
× |
× |
× |
○ |
○ |
○ |
× |
× |
× |
○ |
○ |
○ |
× |
○ |
○ |
○ |
2.3 |
× |
× |
× |
× |
○ |
○ |
× |
× |
× |
× |
○ |
○ |
× |
× |
○ |
○ |
2.2 |
× |
× |
× |
× |
× |
○ |
× |
× |
× |
× |
× |
○ |
× |
× |
× |
○ |
なお,下位のバージョンのWebアプリケーションから上位のバージョンの機能を使用した場合,エラーが発生することがあります。発生するエラーについてバージョンごとに次に示します。
仕様 |
使用する機能 |
エラー時の処理 |
---|---|---|
Servlet 3.0/3.1 |
新規APIの呼び出し |
Servlet 3.0/3.1仕様で追加されたAPIを使用したかどうかはチェックされません。呼び出した場合の動作は保証されないため呼び出さないよう注意してください。 |
新規アノテーションの使用 |
アノテーションを使用してエラーとなった場合の処理については,マニュアル「アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)」の「16. アノテーションの使用」を参照してください。 |
Servlet 2.2仕様,Servlet 2.3仕様,Servlet 2.4仕様およびServlet 2.5仕様から,Servlet 3.0仕様にWebアプリケーションのバージョンアップする場合の作業,および注意事項については,「8.2.10 既存のWebアプリケーションをServlet 3.0仕様にバージョンアップする場合の留意点」を参照してください。
仕様 |
使用する機能 |
エラー時の処理 |
---|---|---|
Servlet 2.5 |
新規APIの呼び出し |
Servlet 2.5仕様で追加されたAPIを使用したかどうかはチェックされません。呼び出した場合の動作は保証されないため呼び出さないよう注意してください。 |
新規アノテーションの使用 |
アノテーションを使用してエラーとなった場合の処理については,マニュアル「アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)」の「16. アノテーションの使用」を参照してください。 |
|
JSP 2.1 |
新規ディレクティブの属性※1 |
サーブレットログにKDJE39145-Eのメッセージ,メッセージログにKDJE39186-Eのメッセージがそれぞれ出力され※2,トランスレーションエラーとなります。 |
TLD 2.1 |
Webアプリケーション開始時に次に示すTLDファイルが存在した場合,メッセージログにKDJE39293-Wのメッセージが出力され,処理されません。
Webアプリケーション開始時にこれら以外のTLDファイルが存在した場合は,JSPコンパイル時にメッセージログにKDJE39293-Wのメッセージが出力され,処理されません。 アプリケーションへの初回アクセス時などにJSPコンパイルが発生した場合は,サーブレットログにKDJE39145-Eのメッセージ,メッセージログにKDJE39186-Eのメッセージがそれぞれ出力され※2,トランスレーションエラーとなります。 |
|
ELの追加機能 |
|
Servlet 2.2仕様,Servlet 2.3仕様およびServlet 2.4仕様から,Servlet 2.5仕様にWebアプリケーションのバージョンアップする場合の作業,および注意事項については,「8.2.11 既存のWebアプリケーションをServlet 2.5仕様にバージョンアップする場合の留意点」を参照してください。
仕様 |
使用する機能 |
エラー時の処理 |
---|---|---|
Servlet 2.4 |
新規APIの呼び出し |
Servlet 2.4仕様で追加されたAPIを使用したかどうかはチェックされません。呼び出した場合の動作は保証されないため呼び出さないよう注意してください。 |
新規リスナ登録 |
Webアプリケーションの開始時にKDJE39297-Wのメッセージがメッセージログに出力され,そのリスナ定義は無視されます。 |
|
JSP 2.0 |
新規ディレクティブ新規スタンダードアクション※1 |
サーブレットログにKDJE39145-Eのメッセージ,メッセージログにKDJE39186-Eのメッセージがそれぞれ出力され※2,トランスレーションエラーとなります。 |
タグファイル |
|
|
TLD 2.0 |
次に示すTLDファイルは,Webアプリケーション開始時にチェックされます。該当する場合,メッセージログにKDJE39293-Wのメッセージが出力され,無視されます。
これら以外のTLDファイルは,JSPコンパイル時にチェックされます。初回アクセス時など,JSPファイルのコンパイル時は,サーブレットログにKDJE 39145-Eのメッセージ,メッセージログにKDJE39186-Eのメッセージがそれぞれ出力され※2,トランスレーションエラーとなります。 |
|
シンプル・タグ・ハンドラ |
サーブレットログにKDJE39145-Eのメッセージを,メッセージログにKDJE39186-Eのメッセージがそれぞれ出力され※2,トランスレーションエラーとなります。 |
Servlet 2.2仕様およびServlet 2.3仕様から,Servlet 2.4仕様にWebアプリケーションのバージョンアップする場合の作業,および注意事項については,「8.2.13 既存のWebアプリケーションをServlet 2.4仕様にバージョンアップする場合の留意点」を参照してください。
なお,Servlet 2.2仕様に対応するWebアプリケーションからServlet 2.3の機能を使用しても,アプリケーションのインポート時にServlet 2.3仕様に準拠したWebアプリケーションに書き換えられるため,正常に処理され,エラーは通知されません。
(3) トランザクションとJDBCコネクション利用時の注意
サーブレット,JSPでトランザクションを利用する場合,該当するサービスメソッドでJDBCコネクションを取得し,該当するサービスメソッドが終了する前に解放してください。トランザクションが開始しているサーブレットおよびJSPでは,次に示すJDBCコネクションの使用はサポートされません。
-
サーブレット,JSPのサービスメソッドが生成したスレッド上のJDBCコネクションを使用する。
-
サーブレット,JSPのサービスメソッドから呼び出した別のサーブレット,JSPのサービスメソッドでJDBCコネクションを使用する。
-
サーブレット,JSPのサービスメソッドのinitメソッドで取得したJDBCコネクションを使用する。
-
インスタンス変数に格納されたJDBCコネクションを使用する。※
- 注※
-
SingleThreadModelのサーブレットおよびJSPを使用した場合は,インスタンス変数にJDBCコネクションを格納できます。
(4) パッケージ名の指定に関する注意
不正なパッケージ名が指定されたクラスをサーブレットおよびJSPで使用した場合,ブラウザからアクセスしたときにステータスコード500のエラーになります。例えば,作成したクラスファイルを正しく配置して,ブラウザからアクセスしても,パッケージ名の宣言に不正があった場合は,該当クラスが見つかりません。この場合,ステータスコード500のエラーが返されます。
(5) Cookie利用時の注意
-
日本語などの2バイトコードを含むCookieは使用しないでください。使用した場合,サーブレットおよびJSPで利用しているHTTPセッションが失われる場合があります。
-
Cookieでセッション管理をする場合,ホスト名によるURLでアクセスしたサーブレットまたはJSPで生成されたセッションは,ホスト名の代わりにIPアドレスを指定したURLでアクセスしたサーブレットまたはJSPに引き継がれません(逆も同様です)。
(6) 特別な意味を持つ入力値の表示に関する注意
フォームなどで「<」や「>」などの特別な意味を持つ文字の入力値をそのまま表示した場合,悪意のあるユーザが<SCRIPT>,<OBJECT>,<APPLET>,<EMBED>のスクリプトなどを実行できるタグを使用して,重大なセキュリティ上の問題を引き起こすおそれがあります。アプリケーション開発者は,ユーザから入力されたデータに対して必ず検査をする処理を追加して,特別な意味を持つ文字を排除する必要があります。
(7) コミット後のエラーページの表示に関する注意
サーブレットまたはJSPでレスポンスがコミットされたあとは,例外などのエラーが発生したとしても,次に示すエラーページはブラウザに表示されません。
-
web.xmlで指定したエラーページ
-
JSPのpageディレクティブのerrorPage属性で指定したエラーページ
-
Webコンテナサーバが出力するデフォルトのエラーページ
レスポンスのコミットは,ユーザがServletResponseクラスのflushBufferメソッドなどを明示的に呼び出してコミットする場合以外にも,レスポンスのバッファが満杯になって自動的にWebコンテナがコミットすることがあります。
サーブレットまたはJSPでコミットされているかどうかを調べるには,ServletResponseクラスのisCommittedメソッドを使用します。また,バッファサイズの変更は,サーブレットの場合はServletResponseクラスのsetBufferSizeメソッドで,JSPの場合はpageディレクティブのbuffer属性の指定で実施できます。
(8) PrintWriter,JSPWriterクラス利用時の性能向上について
PrintWriterクラスおよびJSPWriterクラスのprintメソッドとprintlnメソッドの呼び出し回数を少なくすることで,アクセス回数を減らし,性能を向上できます。例えば,StringBufferクラスを使用し,最後にprintlnメソッドを呼び出すようにして,printおよびprintlnメソッドの呼び出し回数を削減します。
(9) javax.servlet.error.XXXXXによるエラー情報参照時の注意
Servlet 2.3仕様で定義されているjavax.servlet.error.XXXXX属性は,web.xmlの<error-page>タグに指定されたサーブレットまたはJSP内でそのエラーページを実行する要因となったエラー情報を参照するためのものです。web.xmlの<error-page>タグに指定されたサーブレットまたはJSP以外からは,これらの属性を参照しないでください。
(10) ファイルアクセス時の注意
ファイルにアクセスする場合は,必ず絶対パスを指定してください。相対パスを指定すると,J2EEサーバはWebコンテナサーバの実行ディレクトリからの相対パスによって目的のパスを検索しようとします。ServletContextクラスのgetRealPathメソッドで相対パスを指定すると,WARファイルを展開したディレクトリでの相対パスが取得されます。
また,ファイルにアクセスする場合は,必ずファイルをクローズしてください。WARファイル展開ディレクトリでファイルにアクセスしてクローズしないと,J2EEサーバで正常にアンデプロイできなくなります。WARファイルの展開ディレクトリ下のパスを指定していない場合でもファイルをクローズしていないと,J2EEサーバの起動中にファイルを削除できないなどの現象が発生します。
(11) 例外発生時のエラーページの設定について
JSP,サーブレットへのアクセスで例外が発生した場合,Webコンテナのデフォルトの処理では例外のステータスコードをブラウザに返します。このデフォルトの処理を変える場合はJSPのerrorPageの指定やweb.xmlでエラーページを設定してください。
(12) クラスローダの取得に関する注意
J2EEアプリケーション内のコードからComponent Containerのクラスローダを取得して,次に示すメソッドを使用する場合に,java.net.JarURLConnectionクラスが使用されます。
-
getResource(String).openConnection().getInputStream()
-
getResource(String).openStream()
これらのメソッドが呼び出される過程でjava.net.JarURLConnectionクラスのopenConnectionメソッドが呼び出され,該当するURLに指定されたJARファイルがオープンされます。このJARファイルはcloseメソッドを明示的に呼ばないかぎり,オープンされたままになり削除できません。これらのメソッドはJ2EEアプリケーション内で使用しないでください。また,JARファイルに対する操作が必要でjava.net.JarURLConnectionクラスのopenConnectionメソッドを使用する場合には,java.net.JarURLConnectionのgetJarFileメソッドが返すJarFileインスタンスのcloseメソッドを必ず呼び出すようにしてください。
(13) URLConnectionクラス使用時の注意
java.net.URLConnectionクラスはsetUseCaches(boolean)メソッドを使用して,指定されたURLに対してコネクションを取得するときにキャッシュの情報を利用するかどうかを指定できます。URLConnectionクラスに対してsetUseCaches(false)メソッドを指定した場合に,コネクションごとに対象のオブジェクトが生成されます。J2EEアプリケーション内のコードから使用する場合には,J2EEサーバのJavaVMがメモリ不足となるおそれがあります。
(14) ネイティブライブラリのロードに関する注意
System.loadLibraryメソッドを使用して,サーブレットおよびJSPからネイティブライブラリをロードしないでください。サーブレットおよびJSPでネイティブライブラリをロードすると,JNI仕様の制約によって,java.lang.UnsatisfiedLinkErrorが発生することがあります。ネイティブライブラリのロードが必要な場合は,System.loadLibraryメソッドを呼び出すコンテナ拡張ライブラリを作成し,サーブレットおよびJSPからコンテナ拡張ライブラリを参照するように実装してください。コンテナ拡張ライブラリの作成については,マニュアル「アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)」の「18. コンテナ拡張ライブラリ」を参照してください。
(15) ユーザスレッドの使用方法
アプリケーションを構成するサーブレットおよびJSPからスレッドを生成して,使用できます。ユーザがプログラムの中で明示して生成するスレッドのことを,ユーザスレッドといいます。
ユーザスレッドは,生成後の動作のしかた(ライフサイクル)によって,次の二つに分けられます。
-
サービスメソッドやinitメソッドの範囲内で動作させる。
-
サービスメソッドやinitメソッドのバックグラウンドで動作させる。
- ユーザスレッドの使用条件
-
-
ユーザスレッドは,Enterprise Beanでは使用できません(EJB仕様で,Enterprise Beanからのスレッドの生成が禁止されているため)。
-
ユーザスレッドを使用する場合のライフサイクルについて説明します。
(a) サービスメソッドやinitメソッドの範囲内で動作させる場合
サービスメソッドやinitメソッドでユーザスレッドの処理を完了させるモデルです。このモデルの処理の流れを次の図に示します。
サービスメソッドやinitメソッドの呼び出しの範囲内で,ユーザスレッドを生成します。サービスメソッドやinitメソッドでは,joinメソッドによってユーザスレッドの処理が完了するのを待ってから,リターンします。
(b) サービスメソッドやinitメソッドのバックグラウンドで動作させる場合
サービスメソッドやinitメソッドでユーザスレッドを生成し,その後ユーザスレッドをバックグラウンドで動作させるモデルです。このモデルの処理の流れを次の図に示します。
ユーザスレッドを生成したサービスメソッドやinitメソッドは,ユーザスレッドを生成したあと,処理の完了を待たないでリターンします。ただし,アプリケーションを停止したあとは,ユーザスレッドからJ2EEサービスを利用できなくなります。したがって,アプリケーションの停止によってjavax.servlet.ServletContextListenerのcontextDestroyedメソッドか,JSPまたはServletのdestroyメソッドでユーザスレッドを停止すれば問題ありません。
(16) セッション情報の永続化について
Webコンテナではセッション情報の永続化はサポートされません。Webコンテナではセッション情報は,正常,異常に関係なくWebコンテナが終了すると失われます。セッション情報を保持したい場合は,セッションフェイルオーバ機能を使用してください。
また,web.xmlで<distributable>タグを指定した場合,およびSerializableでないオブジェクトをセッション情報として登録した場合もIllegalArgumentExceptionは発生しません。
(17) initメソッドおよびdestroyメソッドをオーバーライドしていない場合に出力されるメッセージ
initメソッドおよびdestroyメソッドをオーバーライドしていないサーブレットを初期化または終了すると,次の形式のログがサーブレットログに出力されます。
-
メッセージID:KDJE39037-I
-
メッセージ本文:path="aa....aa" :bb....bb: init※
- aa....aa
-
「/」から始まるコンテキストパスを表します。
- bb....bb
-
web.xmlの<servlet-name>タグで指定したサーブレット名を表します。デフォルトマッピングのサーブレットの場合は,「org.apache.catalina.INVOKER.<クラス名>」となります。
- 注※
-
initメソッドの場合は「init」,destroyメソッドの場合は「destroy」となります。出力されるメッセージは,それぞれjavax.servlet.GenericServletクラスのinitメソッドおよびdestroyメソッドで出力されるログです。したがって,initメソッドまたはdestroyメソッドをオーバーライドしたサーブレットではこれらのメッセージは出力されません。
また,JSPの場合は,pageディレクティブのextends属性で指定するJSPの基底クラスでinitメソッドおよびdestroyメソッドをオーバーライドしなかった場合,同様のメッセージが出力されます。その場合,サーブレット名は"com.hitachi.software.web.servlet-name.jsp"となります。JSPでpageディレクティブのextends属性を指定しなかった場合は,initメソッドのログだけが出力され,destroyメソッドのログは出力されません。
ただし,サーブレットの場合もJSPの場合も,initメソッドおよびdestroyメソッドをオーバーライドしてスーパークラスのinitメソッドおよびdestroyメソッドを呼ぶときは,このメッセージを出力します。
(18) javax.servlet.ServletRequestオブジェクトのjavax.servlet.error.exception属性について
javax.servlet.ServletRequestオブジェクトのjavax.servlet.error.exception属性について,Servletで例外をスローした場合とJSPファイルで例外をスローした場合の二つに分けて説明します。
(a) Servletで例外をスローした場合
- Servletでスローした例外クラスがjava.lang.Error,またはその派生クラスの場合
-
javax.servlet.ServletExceptionクラスの例外がjavax.servlet.ServletRequestオブジェクトのjavax.servlet.error.exception属性に設定されます。Servletでスローした例外は,javax.servlet.ServletExceptionクラスのgetRootCauseメソッドで取得できます。
- Servletでスローした例外クラスがjava.lang.Error,またはその派生クラス以外のクラスの場合
-
Servletでスローした例外がjavax.servlet.ServletRequestオブジェクトのjavax.servlet.error.exception属性に設定されます。
(b) JSPファイルで例外をスローした場合
-
エラーページがJSPファイルの場合
- web.xmlの<error-page>タグでエラーページを指定した場合
-
web.xmlの<error-page>タグでエラーページを指定した場合について,JSP 2.0以降とJSP 1.2に分けて示します。
JSP 2.0以降
JSPファイルでスローした例外がjavax.servlet.ServletRequestオブジェクトのjavax.servlet.error.exception属性に設定されます。
JSP 1.2
JSPファイルでスローした例外クラスが次のクラスのどれかであれば,JSPファイルでスローした例外がjavax.servlet.ServletRequestオブジェクトのjavax.servlet.error.exception属性に設定されます。
・java.io.IOException,またはその派生クラス
・java.lang.RuntimeException,またはその派生クラス
・javax.servlet.ServletException,またはその派生クラス
JSPファイルでスローした例外クラスがこれら以外の場合,javax.servlet.ServletExceptionクラスの例外がjavax.servlet.ServletRequestオブジェクトのjavax.servlet.error.exception属性に設定されます。JSPファイルでスローした例外は,javax.servlet.ServletExceptionクラスのgetRootCauseメソッドで取得できます。
- pageディレクティブのerrorPage属性でエラーページを指定した場合
-
pageディレクティブのerrorPage属性でエラーページを指定した場合について,エラーページでpageディレクティブのisErrorPage属性にtrueを指定した場合とfalseを指定した場合に分けて示します。
エラーページでpageディレクティブのisErrorPage属性にtrueを指定した場合
JSPファイルでスローした例外がjavax.servlet.ServletRequestオブジェクトのjavax.servlet.error.exception属性に設定されます。
エラーページでpageディレクティブのisErrorPage属性にfalseを指定した場合
javax.servlet.ServletRequestオブジェクトのjavax.servlet.error.exception属性に値は設定されません。
-
エラーページがServletの場合
- web.xmlの<error-page>タグでエラーページを指定した場合
-
エラーページがJSPファイルの場合の,web.xmlの<error-page>タグでエラーページを指定した場合と同様です。
- pageディレクティブのerrorPage属性でエラーページを指定した場合
-
javax.servlet.ServletRequestオブジェクトのjavax.servlet.error.exception属性に値は設定されません。
(19) バイナリデータを含むWebアプリケーションの操作について
バイナリデータを含むWebアプリケーションでは,次のことに注意してください。
-
クライアントから送信されたバイナリデータへのリクエストを実行する場合
バイナリデータへのリクエストで適用されるフィルタ内で,レスポンスオブジェクトからのPrintWriterを取得しないでください。
-
クライアントから送信されたリクエストを処理するサーブレットまたはJSPがディスパッチする場合
次の場所では,レスポンスオブジェクトからのPrintWriterを取得しないでください。
-
バイナリデータへのリクエストで適用されるフィルタ内
-
バイナリデータにディスパッチするサーブレットまたはJSP内
- 参考
-
バイナリデータとは,拡張子にマッピングされたMIMEタイプが"text/"から始まっていない静的コンテンツ,またはマッピングが存在しない静的コンテンツです。
-
(20) レスポンスの文字エンコーディングに関する注意
JSPまたはサーブレットのレスポンスボディの文字エンコーディングが,UTF-16(16ビットUCS変換形式)の場合,ブラウザによって正しく表示できない場合があります。その場合は,JSPまたはサーブレットの文字エンコーディングに,UTF-16BE(16ビットUCS変換形式のビッグエンディアンバイト順),またはUTF-16LE(16ビットUCS変換形式のリトルエンディアンバイト順)を使用してください。
(21) javax.servlet.ServletRequestインタフェースのgetServerNameメソッドおよびgetServerPortメソッドの戻り値について
getServerNameメソッド,およびgetServerPortメソッドの戻り値について説明します。
Servlet 2.4仕様以降では,Hostヘッダの有無によって,getServerNameメソッド,およびgetServerPortメソッドの戻り値が異なります。Servlet 2.4仕様以降でのgetServerNameメソッド,およびgetServerPortメソッドの戻り値を次の表に示します。
Hostヘッダの有無 |
getServerNameメソッドの戻り値 |
getServerPortメソッドの戻り値 |
---|---|---|
あり |
Hostヘッダの「:」より前の部分 |
Hostヘッダの「:」よりあとの部分 |
なし |
解決されたサーバ名またはIPアドレス |
クライアントとの接続を受け付けたサーバのポート番号 |
アプリケーションサーバでは,getServerNameメソッド,およびgetServerPortメソッドの戻り値は,HTTPリクエストと,使用する機能の組み合わせによって得られます。なお,HTTP 1.1のリクエストにHostヘッダが含まれない場合,HTTP 1.1仕様に従って,400エラーとなります。また,HTTP 1.1仕様では,リクエストラインのリクエストURIが絶対URIの場合,ホストにはリクエストURIのホストを使用して,Hostヘッダの内容は無視するように定義されています。なお,Servlet仕様では明記されていませんが,HTTP仕様に従って,リクエストラインのURIに含まれるホスト名を優先するようになっています。
HTTPリクエストと,使用する機能の組み合わせによって得られる,getServerNameメソッド,およびgetServerPortメソッドの戻り値を次の表に示します。なお,ゲートウェイ指定機能を使用している場合の,getServerNameメソッド,およびgetServerPortメソッドの戻り値については,表8-9を参照してください。
HTTPリクエスト |
getServerNameメソッドの戻り値 |
getServerPortメソッドの戻り値 |
|
---|---|---|---|
Hostヘッダの有無 |
リクエストラインのURIの種類 |
||
あり |
絶対URI |
リクエストラインのホスト名 |
リクエストラインのポート番号 |
相対URI |
Hostヘッダのホスト名 |
Hostヘッダのポート番号 |
|
なし |
絶対URI |
リクエストラインのホスト名 |
リクエストラインのポート番号 |
相対URI |
J2EEサーバのホスト名またはIPアドレス※ |
NIO HTTPサーバのポート番号 |
(22) javax.servlet.ServletExceptionクラスのコンストラクタで指定した根本原因の例外の取得について
アプリケーションサーバでは,コンストラクタServletException(String, Throwable)またはServletException(Throwable)で指定した根本原因の例外をgetCauseメソッドで取得できます。なお,getRootCauseメソッドでも取得できます。
javax.servlet.ServletExceptionクラスのコンストラクタで指定した根本原因の例外の取得について,互換用のパラメタおよび注意事項について説明します。
-
注意事項
根本原因の例外をgetCauseメソッドの実装によって取得できる場合,コンストラクタServletException(String, Throwable)またはServletException(Throwable)で生成したServletExceptionオブジェクトに対してinitCause(Throwable)を呼び出すことはできません。initCause(Throwable)を呼び出した場合,java.lang.IllegalStateException例外がスローされます。
(23) javax.servlet.ServletOutputStreamオブジェクトに対するflushメソッドの実行についての注意
アプリケーションサーバでは,javax.servlet.ServletResponseオブジェクトから取得するjavax.servlet.ServletOutputStreamオブジェクトに対して,closeメソッドを実行したあとでflushメソッドを実行しても,java.io.IOException例外をスローしません。
(24) リクエストURIの正規化
アプリケーションサーバでは,リクエストURIに含まれる文字列は,正規化されたあと,次に示すマッチング処理で使用されます。
-
コンテキストパスとコンテキストルートのマッチング
-
サーブレットおよびJSPのURLパターンとのマッチング
-
デフォルトマッピングとのマッチング
-
静的コンテンツとのマッチング
-
フィルタのURLパターンとのマッチング
-
web.xmlの<error-page>タグ,またはJSPのpageディレクティブのerrPage属性で指定するエラーページとのマッチング
-
アクセスを制限するURLパターンとのマッチング
-
ログイン認証のURL判定
-
リクエストのフォワードおよびインクルード
-
HTTPレスポンス圧縮フィルタのURLパターンとのマッチング
-
URLグループ単位の同時実行スレッド数制御のURLパターンとのマッチング
(25) javax.servlet.http.HttpServletRequestインタフェースのgetRequestURIメソッドおよびgetRequestURLメソッドの戻り値について
javax.servlet.http.HttpServletRequestインタフェースのgetRequestURIメソッドおよびgetRequestURLメソッドでは,正規化されたURLが戻り値となります。
(26) welcomeファイルにURLマッピングされたServletまたはJSPの指定
リクエストURLがURLマッピングされたServletまたはJSPと一致しないで,welcomeファイルに転送される必要がある場合,Webコンテナでは次のように転送先のwelcomeファイルが選択されます。
まず,指定されたwelcomeファイル名から静的コンテンツやJSPファイルの候補が優先して選択されます。該当するものがない場合,URLマッピングされたServletまたはJSPの候補が選択されます。
welcomeファイルに関する注意事項について説明します。
-
welcomeファイル転送方式による制約
welcomeファイルの転送は,HTTPリダイレクト(HTTPステータスコード302でブラウザがリダイレクトする)によって実現しています。この転送方式には制約があるため,URL設計の際に次のことに注意してください。
-
POSTリクエストを受け付けた際,ブラウザから送信されたリクエストボディの情報を転送先のwelcomeファイルに引き継げません。POSTされた情報がフォーム入力形式(Content-Typeがapplication/x-www-form-urlencoded)の場合だけ,Webコンテナが生成するwelcomeファイル転送先URLのクエリ文字列に情報を付与する形で引き継げます。ただし,この場合も,リクエストボディの情報が多い場合に転送先URLが長くなり過ぎる,ブラウザのアドレスバーにクエリ文字列として情報がそのまま見える,などについて考慮が必要です。
-
転送先のwelcomeファイルのサーブレットがdoGetメソッドを実装していない場合,ブラウザに「400 Bad Request」(HTTP/1.1以外の場合)または「405 Method Not Allowed」(HTTP/1.1の場合)が表示されます。
-
Webアプリケーションからjavax.servlet.RequestDispatcherインタフェースのincludeメソッドを呼び出した際,インクルードする対象のURLとしてwelcomeファイルが存在するディレクトリを指定していても,転送先のwelcomeファイルのコンテンツは挿入されません。
-
-
JSP事前コンパイル済み環境でのwelcomeファイルの追加
JSP事前コンパイル済みのWebアプリケーションに,welcomeファイルに指定したJSPファイルを追加する場合,JSPファイルの追加後にJSP事前コンパイルを再度実行する必要があります。JSP事前コンパイルを再度実行しなかった場合,正しくwelcomeファイル転送処理が実行されません。
-
サーブレットクラスが参照できないサーブレットのwelcomeファイルの指定
サーブレットクラスが参照できないサーブレットをwelcomeファイルに指定しないでください。サーブレットクラスが参照できないサーブレットを指定した場合,正しくwelcomeファイル転送処理が実行されません。
-
ディレクトリが存在しないパスへのwelcomeファイル要求
Webアプリケーション内のリソースとして存在しないディレクトリのパスに対するリクエストの場合,リクエストURLの末尾が「/」であってもwelcomeファイル転送処理は実行されません。
(27) サーブレット,フィルタ,リスナの開始・終了順序
Webアプリケーションを開始すると,リクエストの受付を開始する前に次の順序で初期化処理をすることがServlet 2.4仕様で明確化されました。アプリケーションサーバでは,Servlet2.3以前のWebアプリケーションでも同じ順序で初期化処理をします。Webアプリケーション開始時のサーブレット,フィルタ,およびリスナは次の順序で開始されます。
-
リスナの開始(インスタンスの生成※1,@PostConstructアノテーションのメソッドおよびServletContextListenerのcontextInitializedメソッドの呼び出し※2)
-
フィルタの開始(インスタンスの生成※1,@PostConstructアノテーションのメソッドおよびinitメソッドの呼び出し)
-
load-on-startupタグで指定されたServlet/JSPの開始(インスタンスの生成※1,@PostConstructアノテーションのメソッドおよびinitメソッドの呼び出し)
注※1 Servlet 3.0以降では,API呼び出しによって動的にサーブレット,フィルタ,リスナを追加できますが,インスタンスを指定するAPI呼び出しによって定義を追加したサーブレット,フィルタ,リスナについては,インスタンス生成済みのため,Webコンテナではインスタンスを生成しません。
注※2 リスナのcontextInitialized()メソッドの呼び出しで例外が発生しても,KDJE39103-Eのメッセージを出力してWebアプリケーションの開始処理を継続します。
なお,web.xmlの<load-on-startup>要素によってWebアプリケーション開始時の初期化処理実行を指定しなかったサーブレットについては,初回リクエスト実行時にサーブレットのインスタンスの生成およびinit()メソッドを呼び出します。
このとき,サーブレットのインスタンスの生成およびinit()メソッドはフィルタより前に呼び出します。
Webアプリケーション終了時のサーブレット,フィルタ,およびリスナは次の順序で終了します。
-
開始済みのServlet/JSPの終了(destroyメソッド,@PreDestroyアノテーションのメソッド呼び出し)
-
フィルタの終了(destroyメソッド,@PreDestroyアノテーションのメソッド呼び出し)
-
リスナの終了(@PreDestroyアノテーションのメソッド呼び出し)
(28) Webアプリケーション内の静的コンテンツへのアクセス
Webアプリケーション内の静的コンテンツへのアクセス時に使用できるメソッドは,GET,HEAD,POST,TRACE,OPTIONSのどれかです。
POSTメソッドを使用した場合,GETメソッド使用時と同様,静的コンテンツの内容を応答します。
(29) 文字エンコーディングに関する注意
同じWebアプリケーション内では,web.xmlで指定したエラーページと,HTTPレスポンスに文字エンコーディングを使用するサーブレットおよびJSPに,同じ文字エンコーディングを使用してください。
(30) クエリ文字列にイコール("=")以降だけ指定した場合の戻り値について
リクエストのクエリ文字列にイコール("=")以降しか指定していない場合(例えば,http://localhost/application/getparam.jsp?=paramのような場合)の,javax.servlet.ServletRequestインタフェースのリクエストパラメタを取得するServlet APIの戻り値を次に示します。
-
getParameterメソッド
空文字("")を指定してもnullを返します。
-
getParameterMapメソッド
空のjava.util.Mapオブジェクトを返します。
-
getParameterNamesメソッド
空のjava.util.Enumerationオブジェクトを返します。
-
getParameterValuesメソッド
空文字("")を指定してもnullを返します。
(31) javax.servlet.http.HttpServletResponseインタフェースのcontainsHeaderメソッドについて
以下のレスポンスヘッダはWebコンテナにより自動的にレスポンスにセットされる場合があります。このようなレスポンスヘッダは,javax.servlet.http.HttpServletResponseインタフェースのcontainsHeaderメソッドで,レスポンスにセットされているかどうかを確認できません。
-
Connection
-
Content-Language
-
Content-Length
-
Content-Type
-
Date
-
Server
-
Set-Cookie
-
Transfer-Encoding
(32) アプリケーションサーバのライブラリに関する注意
アプリケーションサーバのライブラリをJ2EEアプリケーションに含めると,ライブラリのバージョン不整合などが原因で,アプリケーションのインポートや開始,実行で不正な動作になることがあります。そのため,製品が使用方法として明示している場合を除いて,アプリケーションサーバのライブラリはJ2EEアプリケーションに含めないようにしてください。