Servlet 3.1 での動作の変更

Servlet 3.1 実装には、Servlet 3.1 フィーチャーを使用した場合に Servlet 3.0 用に作成されたアプリケーションが異なる動作をしたり、失敗したりする可能性がある動作の変更が含まれています。

動作の変更を考慮して、サーバー・インスタンスごとに、Servlet 3.0 と Servlet 3.1 フィーチャー実装のいずれを使用するかを選択できます。 必要な動作が Servlet 3.1 フィーチャーにのみ含まれている場合、Servlet 3.1 フィーチャーを使用する必要があります。 既存のアプリケーションが Servlet 3.1 フィーチャーの動作変更で悪影響を受ける場合、Servlet 3.0 フィーチャーを使用すれば、そのアプリケーションの既存の動作が保持されます。 同じサーバーで Servlet 3.0 と Servlet 3.1 の両方のフィーチャーを使用することはできません。 両方のフィーチャーを構成すると、エラーになります。 両方のフィーチャーを構成した場合、いずれのサーブレット・フィーチャーもロードされません。

動作の変更は、以下の 3 つの理由で導入されています。
  • Servlet 3.1 仕様での明確化によって必要となった変更。
  • Servlet 3.1 実装で Servlet 3.1 Technology Compatibility Kit (TCK) を渡すために必要となった変更。
  • サーブレット実装を改善するための変更。

プログラムで追加されるサーブレット、フィルター、およびリスナー

Servlet 3.1 仕様での明確化により、ServletContextListener が web.xml ファイルまたは web-fragment.xml ファイルで宣言されていないか、@WebListener のアノテーションが付けられていない場合、ServletContextListener でのプログラムによるサーブレット、フィルター、およびリスナーの構成が正しくなくなりました。 結果として、ServletContext でそのようなプログラムによる構成の実行を呼び出すと、UnsupportedOperationException が発生します。

非同期処理の開始後のフォワード

Servlet 3.0 実装では、RequestDispatcher インターフェースの forward メソッドが戻る前に、応答が常に閉じられます。 しかし、Servlet 3.1 仕様での明確化のため、Servlet 3.1 実装では、要求が非同期モードにされた場合、RequestDispatcher インターフェースの forward メソッドが戻る前に応答が閉じられず、またフラッシュもされません。 この変更は、forward からの戻り時に応答出力を追加する既存の 3.0 アプリケーションに影響する可能性があります。これは、そのような応答データが Servlet 3.0 では送信されていませんでしたが、Servlet 3.1 では送信されるようになったためです。

URL パターンの競合

Servlet 3.0 では、URL パターンが複数のサーブレットにマップされた場合でも、アプリケーションは正常に開始します。 しかし、Servlet 3.1 仕様での明確化のため、アプリケーションは必ず開始に失敗します。 Liberty Servlet 3.1 実装では、メッセージが出力され、アプリケーションは開始に失敗します。
SRVE9016E: Unable to insert mapping [{0}] for servlet named [{1}]. The URL pattern is already defined for servlet named [{2}].

Explanation: There is an application error. A servlet mapping URL pattern should not map to multiple servlets.

User action: Change the URL pattern for the servlet mapping.

ServletContext.getMinorVersion()

Servlet 3.0 フィーチャー実装では、この API は、0 を返します。

Servlet 3.1 フィーチャーでは、この API は 1 を返すようになっています。

ServletContext.getServerInfo()

Servlet 3.0 フィーチャー実装では、この API は、SMF WebContainer を返します。

Servlet 3.1 フィーチャーでは、この API は IBM WebSphere Liberty/8.5.5.<x>を返すようになりました。ここで、 < x> は WebSphere® Application Server のフィックスパック番号です。

ServletResponse.reset()

応答がまだコミットされていないときに、ServletResponse.reset() を使用して、バッファーに入れられているデータ、状況コード、および応答ヘッダーをクリアできます。 Servlet 3.1 フィーチャーを使用している場合、このメソッドは、前に呼び出された ServletResonse.getWriter() や ServletResponse.getOutputStream() のレコードもクリアします。

X-Powered-By ヘッダー

Servlet 3.0 フィーチャー実装では、X-Powered-By ヘッダーは、Servlet/3.0 に設定されます。 Servlet 3.1 フィーチャー実装では、X-Powered-By ヘッダーは、Servlet/3.1 に設定されます。

リソース参照注入ターゲットのマージ

Servlet 3.0 仕様では、web-fragment.xml ファイルに定義されているリソース参照の <injection-target> エレメントは、同じ名前の web.xml リソース参照定義に <injection-target> エレメントがない場合にのみ親の web.xml ファイルに追加されます。 Servlet 3.1 仕様では、web-fragment.xml 記述子内のすべての <injection-target> エレメントが、同じ名前のリソース参照の <injection-target> エレメントの親の web.xml 記述子リストに追加されることが明確化されました。 Servlet 3.1 フィーチャーを使用している場合、このフィーチャーは、以前は web.xml ファイルから除外されていた注入ターゲットをアクティブ化して、既存のアプリケーションの機能を変更する可能性があります。

Web 記述子内の重複エレメントの許容

Servlet 3.1 仕様では、web.xml ファイルに 2 つの <absolute-ordering> エレメントを含めることはできないことが明確化されました。 複数の <absolute-ordering> エレメントを使用したアプリケーションのデプロイメントは失敗します。 また、 web-fragment.xml 記述子に 2 つの <ordering> 要素を含めることはできません。 複数の <ordering> エレメントを使用したアプリケーションのデプロイメントは失敗します。 以前のバージョンでは、デプロイメントは失敗しません。ただし、エレメントの機能が予測不能になる可能性があります。

メタデータ内の Web フラグメント順序の変更 - 完全な場合

<absolute-ordering> エレメントの処理は、web.xml 記述子が metadata-complete="true" とマークされている場合に変更されます。 以前のバージョンでは、metadata-complete="true" の場合、すべての Web フラグメント・アーカイブが使用されます。 Servlet-3.1 フィーチャーを使用している場合、metadata-complete の場合の <absolute-ordering> エレメントは、完全と見なされます。 この変更により、<absolute-ordering> エレメントにリストされていないフラグメントは、処理から除外されます。

AsyncContext.dispatch()

AsyncContext.dispatch() を (例えば、パラメーターを指定せずに) 使用している場合、要求は元の URL にディスパッチされます。 Servlet-3.0 フィーチャーを使用している場合、照会ストリングが元の要求に含まれていれば、ディスパッチされたリソースでそれを使用できます。 しかし、Servlet 3.1 フィーチャーを使用している場合、照会ストリングがディスパッチング・リソースに提供された場合、ディスパッチされたリソースで使用できるのは、その照会ストリングになります。 例:
Request for /FirstResource?param=One
First Resource:
    getParameter("param") returns "One"
           forward request to /SecondResource?param=Two
SecondResource
           getParameter(param) returns "Two"
           ac.start()
           ac.dispacth() dispatches to /FirstResource
First Resource
           Servlet-3.0 feature : getParamter("param") returns "One"
           Servlet-3.1 feature : getParameter("param") returns "Two"

This change was required by the Servlet 3.1 TCK.
AsyncContext.dispatch() または AsyncContext.complete() の後に要求または応答オブジェクトを取得することは許可されず、以下の例外がスローされます。
java.lang.IllegalStateException: SRVE9015E: Cannot obtain the request or response object after an AsyncContext.dispatch() or AsyncContext.complete().
    at com.ibm.ws.webcontainer31.async.AsyncContext31Impl.getRequest(AsyncContext31Impl.java:72)
    [...]

SessionCookieConfig.setComment()

Java™ Servlet 3.1 仕様によれば、この API は、 ServletContext が初期化を完了した後に呼び出され、Servlet 3.1 フィーチャーがこの必要な動作に従う場合、 illegalState例外を返します。 しかし、Servlet 3.0 フィーチャーでは、コンテキストの初期化後におけるこの API の使用が妨げられないため、Servlet 3.0 フィーチャーの動作に依存しているアプリケーションは、Servlet 3.1 フィーチャーでは機能しません。

sendRedirect(java.lang.String location) API

sendRedirect(java.lang.String location) API は相対 URL を受け入れます。ただし、サーブレット・コンテナーは、応答をクライアントに送信する前に相対 URL を絶対 URL に変換する必要があります。 先頭に '/' がない相対ロケーション (folder/default.jsp) の場合、コンテナーは現行要求 URI を基準とした相対ロケーションとして解釈します。 先頭に '/' がある相対ロケーションの場合、コンテナーはサーブレット・コンテナー・ルートを基準とした相対ロケーションとして解釈します。

例えば、アプリケーションによって提供されるリダイレクト・ロケーションが folder/default.jspで、先行 '/'がなく、インバウンド要求 URL が http://host:port/context_root/folder または http://host:port/context_root/folder/である場合、要求は現在の要求 URI に対して相対的な http://host:port/context_root/folder/folder/default.jspにリダイレクトされます。

この動作が見られるのは、Servlet 3.0 フィーチャーで com.ibm.ws.webcontainer.redirectwithpathinfo プロパティーが true に設定されている場合です。 このプロパティーは Servlet 3.1 フィーチャーでは無視され、動作は説明したようにデフォルトのものになります。

デフォルト・エラー・ページ

IBM® 拡張機能は、 ibm-web-ext.xmlなどの Web 拡張を使用してデフォルトのエラー・ページを指定する機能です。

Servlet 3.0 以上の機能として、デフォルト・エラー・ページは、エラー・ページを指定する機能を変更したものです。 通常の (非デフォルト) エラー・ページと同様に、デフォルト・エラー・ページは、Web モジュール記述子 (web.xml) および Web フラグメント記述子 (web-fragment.xml) で指定します。

通常の (非デフォルト) エラー・ページでは、例外タイプまたはエラー・コードのいずれかを指定します。 デフォルト・エラー・ページでは、例外タイプとエラー・コードの両方を省略します。 デフォルト・エラー・ページは、サーブレットで例外がスローされるか、エラー・コード結果が設定されたが、例外タイプまたは設定されたエラー・コードに一致するエラー・ページが構成されていない場合に使用されます。

デフォルト・エラー・ページを定義する機能は Servlet 3.0 仕様で提供され、Servlet 3.0 スキーマでサポートされます。 デフォルト・エラー・ページは、Servlet 3.1 仕様に従い、exception-type エレメントまたは error-code エレメントが含まれていないエラー・ページです。

以下に、エラー・ページおよびデフォルト・エラー・ページの例を示します。

デフォルト・エラー・ページの優先順位ルール
web.xmlweb-fragment.xml、および ibm-web-ext.xml の各ファイルでのデフォルト・エラー・ページの優先順位の決定には、以下の 3 つのルールが適用されます。
  • ルール 1: web.xml ファイルおよび web-fragment.xml ファイル。

    デフォルト・エラー・ページが web.xml ファイルで指定されている場合、そのページは、web-fragment.xml ファイルで指定されているすべてのデフォルト・エラー・ページをオーバーライド (マスク) します。 また、複数の web-fragment.xml ファイルでさらにデフォルト・エラー・ページが指定されていても、エラーは発生しません。

  • ルール 2: web-fragment.xml および web-fragment.xml

    デフォルト・エラー・ページが web.xml ファイルで指定されていない場合、異なる複数のデフォルト・エラー・ページが 2 つ以上の web-fragment.xml ファイルで指定されていれば、エラー状態が存在することになります。

  • ルール 3: ibm-web-ext.xml ファイルおよび web.xml ファイルまたは web-fragment.xml ファイル。

    ibm-web-ext.xml ファイルと、web.xml ファイルまたは web-fragment.xml ファイルとの間の優先順位のルールは、Web コンテナー・フィーチャー・レベルによって異なります。

Web コンテナー・フィーチャー・レベルが 3.0 の場合、ibm-web-ext.xml ファイルで定義されているデフォルト・エラー・ページは、web.xml または web-fragment.xml ファイルで定義されているデフォルト・エラー・ページよりも優先されます。
注: Web コンテナーがフィーチャー・レベル 3.0を使用する場合、Servlet 3.1 スキーマは使用できません。 サーブレット 3.0 スキーマのデフォルト・エラー・ページの使用に関するルールを参照してください。

Web コンテナー・フィーチャー・レベルが 3.1 以上の場合、web.xml または web-fragment.xml ファイルで指定されているデフォルト・エラー・ページが、ibm-web-ext.xml ファイルで指定されているデフォルト・エラー・ページよりも優先されます。

スキーマ・ルール

web.xml ファイルまたは web-fragment.xml ファイル内のいずれのデフォルト・エラー・ページが処理されるのかに関する 2 つのルールが適用されます。 規則は、Web コンテナー・フィーチャーのバージョン、使用中のサーブレット・スキーマ、および Java カスタム・プロパティーの設定によって異なります。

これらの規則が発生したのは、 IBM WebSphere Application Server traditional V8.0が V8.0 一般出荷版リリースでデフォルト・エラー・ページをサポートしなかったためです。 デフォルト・エラー・ページのサポートは、サービス・パックで APAR PM94199 によって WebSphere Application Server traditional に追加されました。 APAR PI05845により、サービス・パックの Liberty にデフォルト・エラー・ページのサポートが追加されました。 これらの更新は外部から可視の機能の変更であるため、新しい機能はデフォルトで無効になっており、Java システム・プロパティーによって有効にする必要があります。

  • ルール 1: Servlet 3.0 スキーマおよび Web コンテナー・フィーチャーのバージョン 3.0 を使用しているデフォルト・エラー・ページ。

    Web コンテナー・フィーチャーのバージョンが 3.0 で、Servlet 3.0 スキーマを使用する web.xml ファイルまたは web-fragment.xml ファイルでデフォルトのエラー・ページが指定されている場合、デフォルトのエラー・ページが処理されるのは、 com.ibm.ws.webcontainer.allowdefaulterrorpage Java システム・プロパティーが trueに設定されている場合のみです。 Java システム・プロパティーが設定されていないか、 trueに設定されていない場合、デフォルトのエラー・ページは無視されます。 ibm-web-ext.xml ファイルで指定されているデフォルト・エラー・ページが使用されます。

  • ケース 2: Web コンテナー・フィーチャーのバージョン 3.1 を使用しているデフォルト・エラー・ページ。

    Web コンテナー・フィーチャーのバージョンが 3.1 以上の場合、どのサーブレット・スキーマ・バージョンが使用されているか、および Java カスタム・プロパティーが設定されているかどうかに関係なく、 web.xml ファイルまたは web-fragment.xml ファイルに指定されているデフォルトのエラー・ページが常に処理されます。

    Servlet 3.1 スキーマを使用している記述子の処理には Web コンテナー・フィーチャーのバージョン 3.1 が必要であるため、このケースは、記述子が Servlet 3.1 スキーマを使用している場合に発生します。

重要: Servlet 3.0まで Web フラグメントは追加されませんでした。 web-fragment.xml ファイルには、Servlet 2.5 からのスキーマはありません。
エラー・ページおよびデフォルト・エラー・ページの例
ibm-web-ext.xml ファイルに定義されているデフォルト・エラー・ページ:
<?xml version="1.0" encoding="UTF-8"?>
<web-ext xmlns="http://websphere.ibm.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-ext_1_0.xsd"
    version="1.0">

	<default-error-page uri="/ExtErrorPage.html"/>
</web-ext>
web.xml ファイルまたは web-fragment.xml ファイルに定義されている error-code エラー・ページ・エレメント:
<error-page>
		<error-code>404</error-code>
			<location>/ErrorCodeErrorPage.html</location>
</error-page>
web.xml ファイルまたは web-fragment.xml ファイルに定義されている exception-type エラー・ページ・エレメント:
<error-page>
		<exception-type>javax.servlet.ServletException</exception-type>
		<location>/ExceptionTypeErrorPage.html</location>
</error-page>
web.xml ファイルまたは web-fragment.xml ファイルに定義されているデフォルト・エラー・ページ・エレメント:
<error-page>
		<location>/DefaultErrorPage.html</location>
</error-page>
スキーマの例
Servlet 2.5 スキーマを使用している web.xml ファイルのヘッダーの例:
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_2_5.xsd"
      version="2.5">
Servlet 3.0 スキーマを使用している web.xml ファイルのヘッダーの例:
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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"
      version="3.0">
Servlet 3.1 スキーマを使用している web.xml ファイルのヘッダーの例:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
Servlet 3.0 スキーマを使用している web-fragment.xml ファイルのヘッダーの例:
<?xml version="1.0" encoding="utf-8"?>
<web-fragment 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-fragment_3_0.xsd"
      version="3.0">
Servlet 3.1 スキーマを使用している web-fragment.xml ファイルのヘッダーの例:
<?xml version="1.0" encoding="utf-8"?>
<web-fragment xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns="http://xmlns.jcp.org/xml/ns/javaee"
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
      version="3.1">