tomcatは C:\Users\nitta\Documents\tomcat8 (Windowsの場合) または /Users/nitta/Documents/tomcat9 (macOS の場合) にインストールされていて、 環境変数CATALINA_HOMEはこのpathを保持しているものとする。
環境変数の値を表す文法はOS(Shell)によって異なり、 Unix系 (macOS, Linux等)では ${CATALINA_HOME}, Windows では %CATALINA_HOME% である。 以下の記述では、Unix系の記法を採用して、Tomcat 8 がインストールされたパスを ${CATALINA_HOME} で表している。自分の環境に適宜読み替えて理解してほしい。
Webアプリケーションは ${CATALINA_HOME}/webapps の下に配置する。 ここでは entry というWebアプリケーションを作成する例で説明する。
Tomcatは起動時の ${CATALINA_HOME}/webapps/ 以下の状態をキャッシュしている。 そのため、webappsより下のファイルを変更した場合は、 一旦Tomcatを停止して (${CATALINA_HOME}\bin\shutdown.bat をエクスプローラ上でクリック)、 その後でTomcatを起動し直す (${CATALINA_HOME}\bin\startup.bat をエクスプローラ上でクリック) 必要がある。
[ファイル配置]
${CATALINA_HOME}/webapps/entry/hello.html
| ${CATALINA_HOME}/webapps/entry/hello.html |
<html> <head> <title>html example</title> </head> <body> <h2>Hello</h2> This is HTML. </body> </html> |
[ブラウザでアクセスするURL] http://localhost:8080/entry/hello.html

[ファイル配置]
${CATALINA_HOME}/webapps/entry/sub/sub.html
| ${CATALINA_HOME}/webapps/entry/sub/sub.html |
<html> <head> <title>Sub</title> </head> <body> <h2>Sub</h2> This is Sub. </body> </html> |
[ブラウザでアクセスするURL] http://localhost:8080/entry/sub/sub.html

[ファイル配置]
${CATALINA_HOME}/webapps/entry/WEB-INF/src/HelloServlet.java ←作成する
/classes/HelloServlet.class←コンパイラで生成する
クラスファイル(拡張子が.classのファイル)は
「
HelloServlet.javaで記述するのは以下の点である。
コンパイル時には、Javaの標準でないAPIを利用するので、 servlet-api.jarを環境変数CLASSPATHに含めておく必要がある。
環境変数名: CLASSPATH
値: .;C:\Users\nitta\Documents\tomcat8\lib\servlet-api.jar;その他のパス
(または .;%CATALINA_HOME%\lib\servlet-api.jar;その他のパス ) ←他の環境変数を使って記述してもよい
環境変数を設定した後で起動したプログラム(たとえばコマンドプロンプト等)では、CLASSPATH変数に値が設定されている。 CLASSPATH変数に値を設定する場合は、必ず '.' (カレント・ディレクトリ)も先頭に含めておくこと。 複数の値を設定する場合は ';' (セミコロン)でつなぐ。
| ${CATALINA_HOME}/webapps/entry/WEB-INF/src/HelloServlet.java |
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloServlet extends HttpServlet {
public void doGet(HttpServletRequest req,HttpServletResponse res)
throws IOException, ServletException {
PrintWriter out = res.getWriter();
out.println("Hello");
}
}
|
コンパイルは次のように指定する。 -dオプションによって .classファイルを生成する先のフォルダを指定する(classesフォルダは前もって作っておくこと)。 また -sourcepathオプションは、コマンドラインで指定したファイル以外が必要になった ときに探すフォルダである(今回のコンパイルでは必要ないが、後で必要になる場合がある)。
| HelloServlet.javaのコンパイル |
C:\Users\nitta> echo %CLASSPATH% |

[ファイル配置]
${CATALINA_HOME}/webapps/entry/WEB-INF/classes/HelloServlet.class
/src/HelloServlet.java
/web.xml ←このファイルを作成する
web.xmlは、Webアプリケーションの動作を記述するためのファイルで、 Deployment Descriptor (配備記述子)と呼ばれる。 このファイルはXML形式で表現する。
| 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"
metadata-complete="false">
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
</web-app>
|
| url-patternの記述 | 呼び出すときのURLの指定 |
|---|---|
| /aaa | http://マシン名:ポート番号/entry/aaa |
| /aaa/bbb | http://マシン名:ポート番号/entry/aaa/bbb |
| /aaa/bbb.ccc | http://マシン名:ポート番号/entry/aaa/bbb.ccc |
url-patternの記述には先頭に'/'が必要なことに注意すること。
${CATALINA_HOME}/webapps/examples/WEB-INF/web.xmlを参考に記述すること。 web.xmlの最初のweb-appタグに関する記述はタイプミスをしやすいので、 エディタでコピーしてしまう方がよい。 コピーしたあと metadata-complete要素の値を "true"から"false"へ変更しておくこと。
metadata-complete要素を"false"にしておくと、 Servlet3.0テクノロジーで導入された web fragmentやAnnotationの機能を使うことができる。 (これらの機能については次週以降に述べる。)
[ブラウザでアクセスするURL] http://localhost:8080/entry/HelloServlet

ここで HelloServlet.javaを書き換えてみる。
| HelloServlet.javaの書き換え |
*** ../webapps/entry/WEB-INF/src/HelloServlet.java Thu Nov 24 12:08:44 2016
--- ../webapps/entry/WEB-INF/src/HelloServlet2.java Wed Jul 27 17:40:14 2011
***************
*** 5,10 ****
public void doGet(HttpServletRequest req,HttpServletResponse res)
throws IOException, ServletException {
PrintWriter out = res.getWriter();
! out.println("Hello");
}
}
--- 5,10 ----
public void doGet(HttpServletRequest req,HttpServletResponse res)
throws IOException, ServletException {
PrintWriter out = res.getWriter();
! out.println("Hello2");
}
}
|
このファイルをコンパイルし直した後で、ブラウザで先ほどのURL (http://マシン名:ポート番号/entry/HelloServlet) にアクセスし直しても(or reloadしても)表示は変わらないはずである。 Tomcatはサーブレットのクラスファイルを読み込んだ後は キャッシュしてしまうので、クラスファイルを変更しても その変更は即座には動作に反映されない。 (Tomcatを再起動すれば反映される。)
クラスファイルを変更する度にTomcatを再起動するのは煩わしいので、 以下のようにオートリロードの設定をしておくとよい。 META-INF の下に context.xmlというファイルを作成する。
[ファイル配置]
${CATALINA_HOME}/webapps/entry/META-INF/context.xml
(注意) META-INF/の下であることに注意。WEB-INF/の下ではない。
| ${CATALINA_HOME}/webapps/entry/META-INF/context.xml |
<Context reloadable="true" /> |
「オートリロード」機能が有効になったことを確認しておくこと。
[ファイル配置]
${CATALINA_HOME}/webapps/entry/WEB-INF/src/foo/BarServlet.java
| ${CATALINA_HOME}/webapps/entry/WEB-INF/src/foo/BarServlet.java |
package foo;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class BarServlet extends HttpServlet {
public void doGet(HttpServletRequest req,HttpServletResponse res)
throws IOException, ServletException {
PrintWriter out = res.getWriter();
out.println("bar");
}
}
|
| web.xmlへの記述の追加 |
*** ../webapps/entry/WEB-INF/web.xml.01 Fri Nov 18 19:12:38 2016
--- ../webapps/entry/WEB-INF/web.xml.02 Fri Nov 18 19:12:55 2016
***************
*** 9,16 ****
--- 9,24 ----
<servlet-name>HelloServlet</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
+ <servlet>
+ <servlet-name>BarServlet</servlet-name>
+ <servlet-class>foo.BarServlet</servlet-class>
+ </servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>BarServlet</servlet-name>
+ <url-pattern>/BarServlet</url-pattern>
+ </servlet-mapping>
</web-app>
|
| BarServlet.javaのコンパイル |
> cd %CATALINA_HOME%\webapps\entry\WEB-INF |

[ブラウザでアクセスするURL] http://localhost:8080/entry/BarServlet

[ファイル配置]
${CATALINA_HOME}/webapps/entry/WEB-INF/src/Oracle.java
OracleServlet.java
運勢を占うサーブレットを作る。
乱数を発生させて、その結果に応じて異なる文字列を返す getResult()メソッドを持つ Oracleクラスを作成する。
| ${CATALINA_HOME}/webapps/entry/WEB-INF/src/Oracle.java |
import java.util.*;
public class Oracle {
private static Random random = new Random();
public String getResult() {
int n = random.nextInt(10);
if (n < 2 ) return "very good";
else if (n < 5) return "good";
else if (n < 7) return "bad";
else return "very bad";
}
}
|
Oracleクラスを呼び出すサーブレットとしてOracleServletクラスを作成します。
| ${CATALINA_HOME}/webapps/entry/WEB-INF/src/OracleServlet.java |
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class OracleServlet extends HttpServlet {
public void doGet(HttpServletRequest req,HttpServletResponse res)
throws IOException, ServletException {
PrintWriter out = res.getWriter();
Oracle ora = new Oracle();
String result = ora.getResult();
out.println("Your fortune is " + result);
}
}
|
| web.xmlへの記述の追加 |
*** ../webapps/entry/WEB-INF/web.xml.02 Fri Nov 18 19:12:55 2016
--- ../webapps/entry/WEB-INF/web.xml.03 Fri Nov 18 19:13:08 2016
***************
*** 13,18 ****
--- 13,22 ----
<servlet-name>BarServlet</servlet-name>
<servlet-class>foo.BarServlet</servlet-class>
</servlet>
+ <servlet>
+ <servlet-name>OracleServlet</servlet-name>
+ <servlet-class>OracleServlet</servlet-class>
+ </servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
***************
*** 21,24 ****
--- 25,32 ----
<servlet-name>BarServlet</servlet-name>
<url-pattern>/BarServlet</url-pattern>
</servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>OracleServlet</servlet-name>
+ <url-pattern>/OracleServlet</url-pattern>
+ </servlet-mapping>
</web-app>
|
コンパイルするときはOracleクラスのソースの置き場所を示すために 必ず -sourcepathオプションを指定する必要がある。
| OracleServlet.javaのコンパイル |
> cd %CATALINA_HOME% |

[ブラウザでアクセスするURL] http://localhost:8080/entry/OracleServlet ←reloadする度に表示が変わる。
