この記事ではJavaで作成したWebアプリケーションを動作させる際に使用する環境設定ファイルについて説明する。
目次
Webアプリケーションの設定とは
最初にWebアプリケーションがどのように動いているかを簡単に説明しよう。ユーザがブラウザの画面に表示された絵や文章とリンクしたURL (http://www.linuxacademy.ne.jp/servlet など)を選ぶか、直接ブラウザにURLを入力すると、選んだリンク先の画面がブラウザに表示される。この時、何が起きているかと言うと、ブラウザからWebサーバーに送られてきたリクエストに対してレスポンスを返すよう設定されたサーブレットが起動されている。そして、そのサーブレットが返すレスポンスによって、次の画面が表示される。このリクエストとサーブレットの関係を設定することを「Webアプリケーションの設定」と呼んでいる。
Webアプリケーションを動かすためには、ただサーブレットクラスを作成するだけでは足りない。クライアントからのリクエストに対応するサーブレットを設定するとことをマッピング(紐付け)と呼ぶ。
このマッピングのために必要な基本的な情報は次の通りである。
- URLパス:サーブレットを起動するためのパス
例: http://www.linuxacademy.ne.jp/servlet
- コンテキストルート(Context-root):;サーブレットやHTMLやWebアプリケーションの設定などが入っている一番上位のディレクトリ
例: C:\WebApplication
- サーブレットの完全修飾名:パッケージ名とクラス名の両方を持つクラス名
例: sample.Servlet
クライアントがリクエストにURLパスを指定してWebサーバーに送ると、WebサーバーにあるWebコンテナが対応するサーブレットにリクエストを渡してくれる。この時、URLパスの中のurl-patternからサーブレットへのマッピングは、web.xml(ディプロイメント・デスクリプタとも呼ばれる)にアプリケーション設定情報として登録されている。次の図はリクエストのURLパスからどのように、サーブレットへマッピングされるかを示している。
web.xmlの設定の仕方
web.xmlとは、Webアプリケーションを動かすために関係する環境(サーブレット、HTMLファイルなど)を設定するためのファイルである。Java EEの最新のバージョンでは、web.xmlを使わなくても替わりにアノテーションを使うことができる。web.xmlを使うかどうかは選択できる。
その基本的な設定の仕方を見てみよう。
次の図は、どのようにurl-patternがサーブレットにマッピング情報として登録されているかを示している。url-patternがservlet-nameにマッピングされ、そのservlet-nameからservlet-classへとマッピングされる。
例えば、
- リクエストのurl-patternがApplication1であれば
- url-pattern:Application1が一致するのは<servlet-mapping>の<url-pattern>:Application1である。
- <url-pattern>:Application1に<servlet-name >のservlet1の名前が付けられている。
- <servlet-name>のservlet1が<servlet>の<servlet-name>:servlet1にマッピングされている。
- <servlet-name>のservlet1に<servlet-class>ApplicationServlet1がサーブレットとして割り当てられる。
バージョン
このドキュメントを書くために使用した各コンポーネントのバージョンを示す。次のセクションの「名前空間宣言とスキーマロケーション」などは、このバージョンに対応して定義されているので注意が必要である。
構成要素 | バージョン |
Servlet | 3.1. |
Apache Tomcat | 8.5. |
JRE | 1.8 |
名前空間宣言とスキーマロケーション
web.xmlファイルの先頭に「名前空間宣言とスキーマロケーション」を必ず記述しなければならない。
1 |
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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-app_3_1.xsd" id="WebApp_ID" version="3.1"> |
サーブレット<servlet>
サーブレット<servlet>要素は、サーブレットについて名前やクラスなのどのデータを、必要に応じ宣言できる。以下にそれらのデータを扱うための要素をあげる。
要素 | 必須 | 内容 |
<servlet-name> | ○ | サーブレットの標準的な名前で、web.xml(ディプロイメント・デスクリプタ)の中でサーブレットの定義を参照するために用いられる名前を定義する。 |
<display-name> | - | GUIツールによって表示するための短い名前。 |
<description> | - | サーブレットのテキスによる説明。 |
<servlet-class> | - | サーブレットの完全修飾名。
Servlet 3.0以降、<servlet-class> と<jsp-file>はオプションである。<servlet-class> と<jsp-file>なしの環境設定は、予備とみなされている;プログラムで動的にサーブレットを登録するためのサーブレットAPIを使用すべきである。その他は、配置が失敗する。 |
<jsp-file> | - | Webアプリケーション内のJSPファイルへのフルパス、つまりWebアプリケーションのルートに対する相対ディレクトリである。
Servlet 3.0以降、<servlet-class> と<jsp-file>はオプションである。<servlet-class> と<jsp-file>なしの環境設定は、予備とみなされている;プログラムで動的にサーブレットを登録するためのサーブレットAPIを使用すべきである。その他は、配置が失敗する。 |
<init-param> | - | サーブレットの初期属性の名前と値のペアーを含む。
各属性のための<init-param>タグのセットをセパレータに使ってください。 |
<load-on-startup> | - | WebLogicサーバーはWebLogicサーバーが立ち上がったとき、サーブレットを初期化する。要素のオプションである値は、サーブレットがロードされる順番を表す正の整数でなければならない。低い整数値が高い整数値よりも先にロードされる。もし、値が特定できないか、またはもし値が正の整数値でなければ、WebLogicサーバーはアプリケーションが立ち上がっている間にサーブレットをなんらかの順番でロードする。 |
<run-as> | アプリケーション実行のために使用されるrun-as認証として指定される。 | |
<security-role-ref> | サーブレットロジックの中に直接コードで書かれた代替ロール名に<security-role>によって定義されたセキュリティロール名をリンクするために使われる。抽象的に拡張されたレイヤーはサーブレットにサーブレットのコードの変更なしに配置を構成することを許す。 |
必須項目の「-」:オプションの意味である。
サーブレット・マッピング<servlet-mapping>
サーブレット・マッピング<servlet-mapping>要素はサーブレットとURLパターンの紐付けを行う。以下にそのマッピングを行うための要素をあげる。
要素 | 内容 |
<servlet-name> | servletの<servlet-name>と同じ。 |
<url-pattern> | URLを解決するために用いるパターンを記述する。
「http://host:port + WebAppName」に続く部分はWebLogic Server によって<url-pattern>と比較される、もしパターンが一致すれば、サーブレットはこの要素に紐付けされたサーブレットが呼び出される。
パターンの例: /soda/grape/*, /foo/* , /contents, *.foo
URLはサーブレット3.0仕様に規定された規則に従わなければならない。サーブレット・マッピングの付加的な例は、サーブレット・マッピングを参照してください。 |
シンプルなweb.xmlのサンプルプログラム
このサンプルプログラムは、シンプルなweb.xmlを使ったものだ。クライアントからのリクエストがサーブレットクラスを呼び出す。そのサーブレットは「Hello World!」を表示するレスポンスを返す。その手順とレスポンスによって表示される画面は実行結果で確認できる。
web.xmlの定義
URLパスよって呼び出されるサーブレットクラスの場所は次の図の通りである。また、URLパスとサーブレットのマッピングはweb.xmlに定義されている。
これが、web.xmlである。ひとつのサーブレットがマッピングされている。
1 2 3 4 5 6 7 8 9 10 11 |
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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-app_3_1.xsd" id="WebApp_ID" version="3.1"> <servlet> <servlet-name>helloworld</servlet-name> <servlet-class>HelloWorld</servlet-class> </servlet> <servlet-mapping> <servlet-name>helloworld</servlet-name> <url-pattern>/HelloWorld</url-pattern> </servlet-mapping> </web-app> |
サンプルプログラム
次のプログラムは、HttpServletクラスを継承して作成されたサーブレットクラスである。リクエストメソッドはGETに対応したdoGet()メソッドのみが実装されている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloWorld extends HttpServlet {//[]1] protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//[2] response.setContentType("text/html");//[3] PrintWriter out = response.getWriter();//[4] out.println("<html><head></head><body>");//[5] out.println("<p>Simple Application</p>");//[6] out.println("<p>Hello World!</p>");//[7] out.println("</body></html>");//[8] } } |
実行結果
コンテキストルートはServletSimpleXMLなので、クライアントからのパスは以下のようになる。
http://localhost:8080/ServletSimpleXML/HelloWorld
次の画面は、web.xmlの設定に対してパスをIEのアドレスに入力した結果である。
サンプルプログラムの説明
それでは簡単にプログラムの解説をしていこう。
- [1] HttpServletを継承して、HelloWorldクラスを定義する。
- [2] doGet()メソッドをオーバーライドして定義する。
- [3] Content Typeに「text/html」を設定する。
- [4] HTMLを出力するためのoutオブジェクトを取得する。
- [5]-[8] outオブジェクトに「Simple Application」と「Hello World!」を表示するHTMLコードを出力する。
パッケージに入ったサーブレットのweb.xml
前のセクションのサンプルプログラムは、サーブレットがパッケージ入っていないシンプルなweb.xmlファイルだった。今度は、そのサーブレットが次のように「sample」というパッケージに入っている。この場合は、パッケージ名も含めた完全修飾名でサーブレットを定義しなければならない。
これがweb.xmlの定義の中の完全修飾名でサーブレットが定義されている部分だ。
1 2 3 4 |
<servlet> <servlet-name>helloworld</servlet-name> <servlet-class>sample.HelloWorld</servlet-class> </servlet> |
では、web.xmlの全体を見てみよう。
web.xmlの定義
URLパスよって呼び出されるサーブレットクラスの場所は次の図の通りである。また、URLパスとサーブレットのマッピングはweb.xmlに定義されている。
これが、web.xmlである。パッケージの名前が付いたサーブレットがマッピングされている。
1 2 3 4 5 6 7 8 9 10 11 |
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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-app_3_1.xsd" id="WebApp_ID" version="3.1"> <servlet> <servlet-name>helloworld</servlet-name> <servlet-class>sample.HelloWorld</servlet-class> </servlet> <servlet-mapping> <servlet-name>helloworld</servlet-name> <url-pattern>/HelloWorld</url-pattern> </servlet-mapping> </web-app> |
サンプルプログラム
サンプルプログラムのコードは、基本的に「シンプルなweb.xmlのサンプルプログラム」と同じである。違いは、最初の行にパッケージの宣言があるだけだ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package sample; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloWorld extends HttpServlet {//[]1] protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//[2] response.setContentType("text/html");//[3] PrintWriter out = response.getWriter();//[4] out.println("<html><head></head><body>");//[5] out.println("<p>Simple Application</p>");//[6] out.println("<p>Hello World!</p>");//[7] out.println("</body></html>");//[8] } } |
実行結果
コンテキストルートはServletPackageXMLなので、クライアントからのパスは以下のようになる。
http://localhost:8080/ServletPackageXML/HelloWorld
レスポンス画面は、「シンプルなweb.xmlのサンプルプログラム」に同じになる。
サンプルプログラムの説明
プログラムのコードも、パッケージの宣言を除いて「シンプルなweb.xmlのサンプルプログラム」に同じである。
web.xmlの<init-param>による初期設定
このサンプルプログラムは、web.xmlの<servlet>要素に<init-param>要素を追加して、サーブレットに初期属性を渡している。サーブレットは、その初期属性を使って「Hello World!」に続いて都市と国を表示するレスポンスを返す。そのレスポンスによって初期属性が表示される画面を実行結果のセクションで確認できる。
web.xmlの定義
URLパスによって呼び出されるサーブレットクラスの場所は次の図の通りである。また、URLパスとサーブレットのマッピングはweb.xmlに定義されている。
これが、web.xmlである。サーブレットの初期属性が<init-param>要素の<param-name>要素と<param-value>要素のペアーに設定されている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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-app_3_1.xsd" id="WebApp_ID" version="3.1"> <servlet> <servlet-name>helloworld</servlet-name> <servlet-class>HelloWorld</servlet-class> <init-param> <param-name>country</param-name> <param-value>Japan</param-value> </init-param> <init-param> <param-name>city</param-name> <param-value>Tokyo</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>helloworld</servlet-name> <url-pattern>/HelloWorld</url-pattern> </servlet-mapping> </web-app> |
サンプルプログラム
このプログラムは、HttpServletクラスを継承して作成されたサーブレットクラスである。リクエストメソッドはGETに対応したdoGet()メソッドのみが実装されている。web.xmlで設定された初期属性をgetInitParameter()メソッドで取得して、レスポンスの中で表示している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloWorld extends HttpServlet {//[]1] protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//[2] String country = getInitParameter("country");//[3] String city = getInitParameter("city");//[4] response.setContentType("text/html");//[5] PrintWriter out = response.getWriter();//[6] out.println("<html><head></head><body>");//[7] out.println("<p>Simple Application</p>");//[8] out.println("<p>Hello World! from " + city + " " + country + ".</p>");//[9] out.println("</body></html>");//[10] } } |
実行結果
コンテキストルートはServletInitParamXMLなので、クライアントからのパスは以下のようになる。
http://localhost:8080/ServletInitParamXML/HelloWorld
次の画面は、web.xmlの設定に対してパスをIEのアドレスに入力した結果である。
サンプルプログラムの説明
それでは簡単にプログラムの解説をしてゆこう。
- [1] HttpServletを継承して、HelloWorldクラスを定義する。
- [2] doGet()メソッドをオーバーライドして定義する。
- [3] Content Typeに「text/html」を設定する。
- [4] getInitParameter()メソッドでパラメータ名:countryを取得し、変数countryに代入する。
- [5] getInitParameter()メソッドでパラメータ名:cityを取得し、変数cityに代入する。
- [6] HTMLを出力するためのoutオブジェクトを取得する。
- [7]-[10] outオブジェクトに「Simple Application」と「Hello World! from + (都市名:変数city) + (国名:変数country)」を表示するHTMLコードを出力する。
デフォルトサーブレット
このサンプルプログラムは、デフォルトサーブレットのweb.xml宣言を示すものである。デフォルトサーブレットは、WebコンテナがURLパターンからサーブレットを選択しようとしてサーブレットが見つからないときに呼び出される。
web.xmlの定義
URLパスよって呼び出されるサーブレットクラスの場所は次の図の通りである。また、URLパスとサーブレットのマッピングはweb.xmlに定義されている。
これが、web.xmlである。HelloWorldとDefaultServletのふたつが定義されている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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-app_3_1.xsd" id="WebApp_ID" version="3.1"> <servlet> <servlet-name>helloworld</servlet-name> <servlet-class>HelloWorld</servlet-class> </servlet> <servlet> <servlet-name>defaultservlet</servlet-name> <servlet-class>DefaultServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>helloworld</servlet-name> <url-pattern>/HelloWorld</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>defaultservlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> |
サンプルプログラム
サンプルプログラムのHelloWorldは、「シンプルなweb.xmlのサンプルプログラム」と同じである。またDefaultServletも、基本的に「シンプルなweb.xmlのサンプルプログラム」と同じである。違いは、クラスの名前と画面の表示だけである。
ここでは、DefaultServletのコードだけを掲載する。HelloWorldは「シンプルなweb.xmlのサンプルプログラム」のセクションを参照してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DefaultServlet extends HttpServlet {//[1] protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//[2] response.setContentType("text/html");//[3] PrintWriter out = response.getWriter();//[4] out.println("<html><head></head><body>");//[5] out.println("<p>Servlet not found.</p>");//[6] out.println("<p>Default Servlet</p>");//[7] out.println("</body></html>");//[8] } } |
実行結果
コンテキストルートはServletDefaultXMLなので、HelloWorldを呼び出すクライアントからのパスは以下のようになる。
http://localhost:8080/ServletDefaultXML/HelloWorld
次の画面は、このパスをIEのアドレスに入力した結果である。
コンテキストルートはServletDefaultなので、存在しないURLパターンHelloXXXXXを呼び出すクライアントからのパスは以下のようになる。
http://localhost:8080/ServletDefaultXML/HelloXXXXX
次の画面は、このパスをIEのアドレスに入力した結果である。
サンプルプログラムの説明
それでは簡単にデフォルトサーブレットのプログラムの解説をしてゆこう。
- [1] HttpServletを継承して、HelloWorldクラスを定義する。
- [2] doGet()メソッドをオーバーライドして定義する。
- [3] Content Typeに「text/html」を設定する。
- [4] HTMLを出力するためのoutオブジェクトを取得する。
- [5]-[8] outオブジェクトに「DefaultServlet」を表示するHTMLコードを出力する。
まとめ
この記事では環境設定用にweb.xmlファイルを作成してWebアプリケーションを動作させる、という手法について説明した。実際にサンプルプログラムを動作させながら仕組みについて理解を深めよう。