WebSphere Liberty で静的コンテンツを処理する際のティップス

WebSphere Liberty で静的コンテンツを処理する際のティップスを記載します。内容としては、以下の２点です。

- 静的コンテンツを war モジュールの外に置く
- コンテキスト・ルート外の静的コンテンツを扱う

## 静的コンテンツを war モジュールの外に置く
ご存じのように、WebSpehre Liberty は war モジュール内の静的コンテンツを処理する機能（ファイル・サービング機能）を提供しています。この機能をカスタマイズすると、war モジュールの外部に配置された静的コンテンツを利用できるようになります。

設定はいたって簡単で、`webApplication` タグ内の `web-ext` タグで以下のように指定するだけです。
この例では、ホスト上のディレクトリー `/htdocs/hogehoge` 内の静的コンテンツが使用されることになります。

```xml:serve.xml 内の webApplication / web-ext タグの内容
    <webApplication id="hogehoge" location="hogehoge.war" name="hogehoge" contextRoot="/hogehoge">
        <web-ext enable-file-serving="true" enable-directory-browsing="false">
            <file-serving-attribute name="extendedDocumentRoot" value="/htdocs/hogehoge" />
        </web-ext>
    </webApplication>
```

尚、war モジュール内に該当の静的コンテンツが存在する場合は、そのコンテンツが使用されます。war モジュール内に該当のコンテンツが存在しない場合にのみ、`extendedDocumentRoot` 内のコンテンツが使用されることになります。
また、ディレクトリーのブラウジング機能を有効化（`enable-directory-browsing="true"`）しても、`extendedDocumentRoot` 内のコンテンツはその対象にはなりません。対象になるのは、war モジュール内のコンテンツのみです。一般的な Web サーバーでは、ディレクトリーのブラウジング機能を無効化していることが多いと思いますので、あまり影響はないかと思います。

`extendedDocumentRoot` に関しては、WebSphere Liberty のドキュメントには記載されておらず、以下の WAS traditional のドキュメントにのみ記載されているようです。

- [WAS traditonal - ファイル・サービス （"ファイル・サービング"の誤訳）](https://www.ibm.com/docs/ja/was-nd/9.0.5?topic=applications-file-serving)

## コンテキスト・ルート外の静的コンテンツを扱う
ここでは、war モジュールのコンテキスト・ルート外に配置されたコンテンツを WebSphere Liberty に処理させる方法に関して記述します。例えば、アプリケーションが `http://host/hogehoge/` のコンテキスト・ルートを持つ場合に、`http://host/forbar/` や `http://host/` 内などの静的コンテンツを WebSphere Liberty に処理させる方法です。

これは、ちょっとしたトリック？を使用することで簡単に実現できます。
方法は簡単で、本来の Web アプリケーションとは別に、コンテキスト・ルートが `/` の Web アプリケーションを追加し、このアプリケーションの `extendedDocumentRoot` で所定のディレクトリーを指定するだけです。
尚、Servlet API の仕様では、パスの最長一致で割り振り先の Web アプリケーションを特定することになっていますので、コンテキスト・ルートが `/` の Web アプリケーションを追加しても、他のアプリケーションへの割り振りは影響を与えません。

`sever.xml` に追加する定義は、以下のようになります。

```xml:serve.xml に追加する定義
    <webApplication id="WebServer" location="WebServer.war" name="WebServer" contextRoot="/">
        <web-ext enable-file-serving="true" enable-directory-browsing="false">
            <file-serving-attribute name="extendedDocumentRoot" value="/htdocs" />
        </web-ext>
    </webApplication>
```

Web アプリケーションが必要になりますが、特にモジュールやコンテンツが必要となるわけではないので、所定のディレクトリー内に `web.xml` ファイルを配置するだけで済みます。
上記の例であれば、`apps/WebServer.war/WEB-INF` ディレクトリー内に以下のような `web.xml` ファイルを配置することになります。

```xml:wev.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_4_0.xsd"
         version="4.0">
    <display-name>WebServer</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    <error-page>
      <error-code>404</error-code>
      <location>/error/404.html</location>
    </error-page>

</web-app>
```

上記の例では、`error-page` タグでコンテンツが無かった場合の 404 (NotFound) 応答をカスタマイズしています。

尚、`welcome-file-list` で指定した内容が有効になるのは、war モジュールのコンテキスト・ルート直下のみで、その他のディレクトリーに対しては有効になりません。つまり、コンテキスト・ルートが `/` なので、`http://host/` の要求は、ディレクトリー・ブラウジングを無効にしてあるので、`http://host/index.html` と解釈されますが、`http://host/foobar/` の要求は、ディレクトリー・ブラウジングを無効にしても、`http://host/foobar/index.html` とは解釈されず、`http://host/foobar/` のまま処理されます。この動作は、一般的な Web サーバーと異なることになりますので、注意が必要です。

## 終わりに
今回は、WebSpehre Liberty で静的コンテンツを処理する際のティップスに関して記載しました。
簡単な内容でしたが、何かのお役に立てばと思います。