お気に入り | 日本語 | ログイン

配備記述子: web.xml

Java ウェブ アプリケーションは、URL からサーブレットへのマッピング、認証が必要な URL などの情報の決定のために配備記述子ファイルを使用します。このファイルには web.xml という名前が付けられ、WEB-INF/ ディレクトリのアプリケーションの WAR 内に配置されます。web.xml はウェブ アプリケーションのサーブレット標準の一部です。

web.xml 標準の詳細については、Metawerx web.xml のリファレンスの wikiWebLogic web.xml 要素のリファレンスおよびサーブレットの仕様をご覧ください。

配備記述子について

ウェブ アプリケーションの配備記述子には、アプリケーションのクラス、リソース、設定、およびウェブ リクエストの処理にウェブ サーバーがどのようにそれらを使用するかを記述しています。ウェブ サーバーがアプリケーションからリクエストを受信すると、配備記述子を使用し、リクエストの URL を、リクエストを処理するコードへとマッピングします。

配備記述子は、web.xml という名前のファイルです。このファイルは、WEB-INF/ ディレクトリのアプリケーションの WAR 内に配置されます。ファイルは XML ファイルであり、ルート要素は <web-app> となります。

次に、すべての URL パス(/*)をサーブレット クラス mysite.server.ComingSoonServlet にマッピングするシンプルな web.xml の例を示します。

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
    <servlet>
        <servlet-name>comingsoon</servlet-name>
        <servlet-class>mysite.server.ComingSoonServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>comingsoon</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

サーブレットと URL パス

web.xml は、URL パスと、そのパスとのリクエストを処理するサーブレットとの間のマッピングを定義します。ウェブ サーバーはこの設定を使用して指定されたリクエストを処理するサーブレットを識別し、リクエスト メソッドに対応するクラス メソッド(HTTP GET リクエストの doGet() メソッドなど)をコールします。

URL をサーブレットにマッピングするには、<servlet> 要素を使用してサーブレットを宣言し、<servlet-mapping> 要素を使用して URL パスからサーブレット宣言へのマッピングを定義します。

<servlet> 要素は、ファイル内の他の要素からのサーブレット参照に使用される名前、サーブレットを使用するためのクラス、初期化パラメータを含め、サーブレットを宣言します。異なる初期化パラメータで同じクラスを使用して複数のサーブレットを宣言できます。各サーブレットの名前は配備記述子間で一意でなければなりません。

    <servlet>
        <servlet-name>redteam</servlet-name>
        <servlet-class>mysite.server.TeamServlet</servlet-class>
        <init-param>
            <param-name>teamColor</param-name>
            <param-value>red</param-value>
        </init-param>
        <init-param>
            <param-name>bgColor</param-name>
            <param-value>#CC0000</param-value>
        </init-param>
    </servlet>

    <servlet>
        <servlet-name>blueteam</servlet-name>
        <servlet-class>mysite.server.TeamServlet</servlet-class>
        <init-param>
            <param-name>teamColor</param-name>
            <param-value>blue</param-value>
        </init-param>
        <init-param>
            <param-name>bgColor</param-name>
            <param-value>#0000CC</param-value>
        </init-param>
    </servlet>

<servlet-mapping> 要素は URL パターン、およびそのパターンと一致する URL のリクエストの使用のために宣言されたサーブレットの名前を指定します。URL パターンでは、パターンの先頭および末尾でアスタリスク(*)を使用できます。アスタリスクは、0 個以上の文字を表します(標準仕様は、文字列の途中でのワイルドカードの使用、および 1 つのパターン内の複数のワイルドカードはサポートしていません)。パターンは URL の完全なパスに一致します。パターンは、ドメイン名に続くスラッシュ(/)から始まり、スラッシュを含みます。

    <servlet-mapping>
        <servlet-name>redteam</servlet-name>
        <url-pattern>/red/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>blueteam</servlet-name>
        <url-pattern>/blue/*</url-pattern>
    </servlet-mapping>

この例では、URL http://www.example.com/blue/teamProfile からのリクエストは TeamServlet クラスが処理します。teamColor パラメータは blue に、また、bgColor パラメータは #0000CC となります。サーブレットは、ServletRequest オブジェクトの getPathInfo() メソッドを使用し、ワイルドカードに一致する URL パスの一部を取得します。

注意: 静的ファイル、つまりユーザーが直接参照する画像、CSS、JavaScript などのファイルは、配備記述子に記載されたパスとは別個に処理されます。静的ファイルとみなされる WAR 内のファイルへのパスに一致する URL パスへのリクエストにより、サーブレットおよび配備記述子内のフィルタ マッピングにかかわらず、ファイルは処理されます。appengine-web.xml ファイルを使用し、静的ファイルとして処理されるファイルを除外することができます。

サーブレットは独自の getServletConfig() メソッドを使用してサーブレット設定を取得し、続いて設定オブジェクトに対してパラメータ名を引数として getInitParameter() メソッドをコールし、初期化パラメータにアクセスできます。

        String teamColor = getServletConfig().getInitParameter("teamColor");

JSP

アプリケーションはウェブ ページの実装に JavaServer Pages(JSP)を使用できます。JSP は、静的なコンテンツ(HTML など)と Java コードが混在したサーブレットです。

App Engine は、JSP の自動コンパイルと URL マッピングをサポートしています。アプリケーションの WAR 内(WEB-INF/ の外)にある JSP ファイルで、名前が .jsp で終わるものは自動的にサーブレット クラスにコンパイルされ、WAR のルートにある JSP ファイルへのパスと同じ URL パスにマッピングされます。たとえば、アプリケーションの register/ というサブディレクトリの WAR に start.jsp という名前の JSP ファイルが含まれている場合、App Engine はそのファイルをコンパイルし、URL パス /register/start.jsp にマッピングします。

JSP の URL へのマッピングをさらに制御したい場合、配備記述子の <servlet> 要素内で明示的に宣言して指定できます。<servlet-class> 要素の代わりに <jsp-file> 要素で、WAR ルートから JSP ファイルへのパスを指定できます。JSP への <servlet> 要素には初期化パラメータを含めることができます。

    <servlet>
        <servlet-name>register</servlet-name>
        <jsp-file>register/start.jsp</jsp-file>
    </servlet>

    <servlet-mapping>
        <servlet-name>register</servlet-name>
        <url-pattern>/register/*</url-pattern>
    </servlet-mapping>

<taglib> 要素と共に JSP タグ ライブラリをインストールできます。タグ ライブラリには JSP タグ ライブラリ記述子(TLD)ファイル(<taglib-location>)、および読み込むライブラリの選択に JSP が使用する URI(<taglib-uri>)へのパスが含まれます。App Engine はJavaServer Pages Standard Tag Library(JSTL)を提供しているため、インストールする必要はありません。

    <taglib>
        <taglib-uri>/escape</taglib-uri>
        <taglib-location>/WEB-INF/escape-tags.tld</taglib-location>
    </taglib>

セキュリティと認証

App Engine はユーザー認証に Google アカウントを使用できます。アプリケーションは Google Accounts API を使用し、ユーザーがログイン中であるかどうかの検知、現在ログインしているユーザーのメール アドレスの取得、ログインおよびログアウトの URL の生成を実行できます。アプリケーションは配備記述子を使用することで Google アカウントに基づいた URL パスへのアクセス制限を指定できます。

<security-constraint> 要素がパターンに一致する URL へのセキュリティ制限を定義します。ログインしていないユーザーがセキュリティ制限のある URL にアクセスした場合、App Engine はユーザーを Google アカウントのログイン ページへと自動的にリダイレクトします。ログインまたはアカウント作成の完了後、アプリケーションの URL にリダイレクトで戻されます。ログインしたユーザーにのみ URL へのアクセスを許可するために、アプリケーション側では何もする必要がありません。

セキュリティ制限には、どの Google アカウント ユーザーがパスにアクセスできるかという認証制限も含まれます。認証制限が * というユーザー ロールを指定している場合、Google アカウントでログインしているユーザーなら誰でもその URL にアクセスできます。制限が admin というユーザー ロールを指定している場合、アプリケーションの登録デベロッパー(管理者)のみが URL にアクセスできます。admin ロールを使用し、サイト内での管理者専用セクションの構築が容易になります。

    <security-constraint>
        <web-resource-collection>
            <url-pattern>/profile/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>*</role-name>
        </auth-constraint>
    </security-constraint>

    <security-constraint>
        <web-resource-collection>
            <url-pattern>/admin/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>admin</role-name>
        </auth-constraint>
    </security-constraint>

App Engine は、配備記述子でのカスタム セキュリティ ロール(<security-role>)および代替認証メカニズム(<login-config>)はサポートしていません。

セキュリティ制限は静的ファイルとサーブレットの両方に適用されます。

セキュアな URL

Google App Engine は *.appspot.com ドメインを使用している URL への HTTPS 経由のセキュアな接続をサポートしています。リクエストが HTTPS を使用している URL にアクセスすると、送信者はリクエスト データとレスポンス データの両方を暗号化し送信します。受信者はデータを受信後復号化します。セキュアな接続は、連絡先、パスワード、プライベート メッセージなど顧客データの保護に役立ちます。

注意: Google Apps ドメインは現在 HTTPS をサポートしていません。HTTPS は *.appspot.com ドメインを経由してアクセスするアプリケーションに制限されます。Google Apps ドメイン上の HTTPS URL へのアクセスは「ホストがみつかりません」というエラーを返します。また、HTTPS のみを受け付けるハンドラ(下記参照)の URL への HTTP を使用したアクセスは、HTTP 403 の「アクセス不可」エラーを返します。セキュアなアクセスのために、*.appspot.com ドメインへ HTTPS URL でリンクし、他の Apps ドメインのサイトには HTTP でリンクすることもできます。

アプリケーションでセキュアな URL を使用する前に、アプリケーションの appengine-web.xml ファイルで <ssl-enabeld>true</ssl-enabled> 要素を使用しセキュアな URL を有効にする必要があります。このファイルの詳細については、アプリケーション設定: セキュアな URL を有効にするをご覧ください。

ある URL で HTTPS を使用するよう宣言するには、<transport-guarantee>CONFIDENTIAL である <user-data-constraint> を使用し、配備記述子でセキュリティ制限を設定します(セキュリティと認証をご覧ください)。次に例を示します。

    <security-constraint>
        <web-resource-collection>
            <url-pattern>/profile/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

transport guarantee が CONFIDENTIAL である URL への HTTP を使用した(セキュアでない)リクエストは、HTTPS を使用して同じ URL へ自動的にリダイレクトされます。

セキュアな接続は、セキュアでない接続よりも CPU と帯域幅を多く使用するため、より高価です。また、セキュアな接続は、セキュアでない接続よりも遅くなります。

JSP と静的ファイルを含めたすべての URL で transport guarantee CONFIDENTIAL を使用できます。

開発用 Web サーバーは HTTPS 接続をサポートしていません。開発用サーバーは transport guarantee を無視します。そのため、HTTPS を使用すべきパスは開発用 Web サーバーでは通常の HTTP 接続を使用しテストされます。

https://1.latest.app-id.appspot.com/ などのバージョン付きの appspot.com URL を使用してアプリケーションの HTTPS ハンドラをテストする場合、指定されたドメイン パスで HTTPS 証明書が署名されていないとブラウザから警告が表示されます。そのドメインの証明書を受け入れると、ページは正常に読み込まれます。ユーザーが https://app-id.appspot.com/ にアクセスする際は、証明書の警告は表示されません。

Google アカウントのログインおよびログアウトは、アプリケーションの URL の設定にかかわらず、常にセキュアな接続を使用して実行されます。

前述のとおり、セキュリティ制限は静的ファイルとサーブレットの両方に適用されます。これには transport guarantee も含まれます。

ウェルカム ファイル リスト

サイトの URL が静的ファイルまたは WAR 内への JSP を示している場合、ディレクトリへのパスにも工夫をすることをおすすめします。あるユーザーがアカウントのパスワードについての情報を取得するために URL パス /help/accounts/password.jsp にアクセスした場合、/help/accounts/ にアクセスしてアカウント システムのドキュメントを紹介しているページを検索しようとすることが想定できます。ユーザーが(サーブレットに明示的にマッピングされていない)WAR サブディレクトリを表すパスにアクセスしようとしたときに、サーバーがアクセスを試みるファイル名のリストを、配備記述子内に記述できます。サーブレット標準ではこのリストを「ウェルカム ファイル リスト」と呼んでいます。

たとえば、ユーザーが URL パス /help/accounts/ にアクセスすると、サーバーは URL が見つからないと報告する前に、配備記述子内の次の <welcome-file-list> 要素に基づき help/accounts/index.jsp および help/accounts/index.html を探します。

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

フィルタ

フィルタはリクエストに対しサーブレットのように動作するクラスですが、リクエストの処理は他のフィルタやサーブレットが引き継ぐことができます。フィルタはログ記録、特別な認証チェック、リクエスト オブジェクトやレスポンス オブジェクトのアノテーションなどの補助的なタスクをサーブレットのコールの前に実行します。フィルタを使用し、配備記述子からリクエスト処理タスクを構成できます。

フィルタ クラスは doFilter() メソッドを含めた javax.servlet.Filter インターフェースを実装します。 次に、メッセージのログを記録してから、処理の受け渡しを行う簡単なフィルタ実装を示します。配備記述子に記載されたこの後の処理には、他のフィルタやサーブレットが含まれる場合があります。

package mysite.server;

import java.io.IOException;
import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LogFilterImpl implements Filter {
    private FilterConfig filterConfig;
    private static final Logger log = Logger.getLogger(LogFilterImpl.class.getName());

    public void doFilter(HttpServletRequest request,
                         HttpServletResponse response,
                         FilterChain filterChain)
            throws IOException, ServletException {
        log.info("Log filter processed a " +
                 getServletConfig().getInitParameter("logType") +
                 " request");

        filterConfig.doFilter(request, response);
    }

    public FilterConfig getFilterConfig() {
        return filterConfig;
    }
    public void setFilterConfig(FilterConfig filterConfig) {
        this.filterConfig = filterConfig;
    }
}

サーブレットと同様に、<filter> 要素を使用して配備記述子内でフィルタを宣言し、<filter-mapping> 要素を使用して URL パターンにマッピングしてフィルタを設定します。フィルタは他のサーブレットに直接マッピングすることもできます。

<filter> 要素には、<filter-name><filter-class>、およびオプションの <init-param> 要素が含まれます。

    <filter>
        <filter-name>logSpecial</filter-name>
        <filter-class>mysite.server.LogFilterImpl</filter-class>
        <init-param>
            <param-name>logType</param-name>
            <param-value>special</param-value>
        </init-param>
    </filter>

<filter-mapping> 要素は、宣言されたフィルタの名前に一致する <filter-name> を含みます。また、フィルタを URL に適用する <url-pattern> 要素、またはサーブレットがコールされたときにフィルタを定義するための宣言されたサーブレットの名前に一致する <servlet-name> 要素のいずれかを含みます。

    <!-- Log for all URLs ending in ".special" -->
    <filter-mapping>
        <filter-name>logSpecial</filter-name>
        <url-pattern>*.special</url-pattern>
    </filter-mapping>

    <!-- Log for all URLs that use the "comingsoon" servlet -->
    <filter-mapping>
        <filter-name>logSpecial</filter-name>
        <servlet-name>comingsoon</servlet-name>
    </filter-mapping>

エラー ハンドラ

エラーが発生したときにサーバーがユーザーに送信する内容を、配備記述子を使用してカスタマイズできます。サーバーはある特定の HTTP ステータス コードを送信するとき、またはサーブレットである特定の Java 例外が発生したときに、別の場所にある代替ページを表示できます。

<error-page> 要素には、HTTP エラー コード値(500 など)を含む <error-code> 要素、または想定される例外(java.io.IOException など)のクラス名を含む <exception-type> 要素のいずれかが含まれます。この要素にはまた、エラーが発生したときに表示されるリソースの URL パスを含む <location> 要素が含まれます。

    <error-page>
        <error-code>500</error-code>
        <location>/errors/servererror.jsp</location>
    </error-page>

注意: このドキュメントの執筆時では、いくつかのエラー条件に対してカスタム エラー ハンドラを設定することはできません。特に、特定の URL にサーブレット マッピングが定義されていない場合は 404 レスポンス コードをカスタマイズできません。また、App Engine の内部エラーにより「403 割り当てエラー」または「500 サーバー エラー」が発生した場合のエラーにも、コードをカスタマイズすることはできません。

サポートされていない web.xml の機能

App Engine は、サーブレット宣言の <load-on-startup> 要素をサポートしています。しかし実際には、データは Web サーバー インスタンスが処理する最初のリクエストの処理の時点で読み込まれます。

App Engine は、ファイル名が決められた拡張子で終わるリソースでの MIME タイプを指定するための <mime-mapping> 要素をサポートしています。しかし、MIME マッピングはサーブレットにのみ適用され、静的ファイルには適用されません。静的ファイルは、ファイル名の拡張子を MIME タイプへとマッピングする固定リストを使用します。

配備記述子の要素の中には、総合開発環境で使用するために人間にも認識可能な表示名、詳細およびアイコンを使用します。App Engine はこれらを使用せず、無視します。

App Engine は JNDI 環境変数(<env-entry>)はサポートしていません。

App Engine は EJB リソース(<resource-ref>)はサポートしていません。

<distributable> 要素は無視されます。

<run-at> を使用したサーブレットのスケジューリングはサポートしていません。