Dev Study
← 解説「Servlet・Tomcat・Servlet コンテナ・Jakarta EE」に戻る

サンプルコードで身につける: Servlet・Tomcat・Servlet コンテナ・Jakarta EE

解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。

1用語早見表: Web の用語

このレッスンの用語を1つずつ並べた表です。「近いもの」はたとえで、当たらない点は5本目にまとめました。 と は、このコースでは名前だけ出てきます。

用語早見表(Servlet・Tomcat・Jakarta EE)表
用語 | 一言で
手元では: 何として見えるか
近いもの: Node / NestJS で近いもの
 
Servlet | HTTP の要求を受けて応答を返す、
Java のクラスの決まった形
手元では: HttpServlet を継承して doGet を書いたクラス
近いもの: Express のハンドラ(ただし関数ではなくクラス)
 
Servlet コンテナ | Servlet を載せて動かすサーバ
サーブレットコンテナとも書く
手元では: Tomcat など
近いもの: Node の http サーバ(役割だけ)
 
Tomcat | Servlet コンテナの実装の1つ
それ自体が Java のプログラム
手元では: 先に起動しておく製品。Spring Boot では中の JAR
近いもの: Node の http サーバ(Express ではない)
 
Jakarta EE | Servlet などサーバ側の API をまとめた規格群
旧称は Java EE、さらに前は J2EE
手元では: jakarta.servlet などのパッケージ名
近いもの: 無い
 
javax / jakarta | それらの API のパッケージ名
Jakarta EE 9 で javax から jakarta に変わった
手元では: import jakarta.servlet.http.HttpServlet;
近いもの: 無い
 
アプリケーションサーバ | このコースでは、Jakarta EE を
広く実装したサーバ製品の意味で使う
手元では: TomEE など(自分でそう名乗っている製品)
近いもの: 無い
 
デプロイ | アプリ(WAR など)をサーバに置いて、
動く状態にすること
手元では: Tomcat の webapps/ に WAR を置く
近いもの: 無い(サーバ製品にアプリを渡す形が Node に無い)
 
web.xml | Servlet と URL の対応などを書くファイル
手元では: WAR の中の WEB-INF/web.xml
近いもの: Express ならコードに書く app.get('/x', handler)
 
JSP | Web アプリ用のテンプレートの仕組み(名前だけ)
JavaServer Pages。現行名は Jakarta Pages
近いもの: 対応を確かめていない
 
EJB | サーバ側の業務部品を書くための仕様(名前だけ)
Enterprise JavaBeans。現行名は Jakarta Enterprise Beans
近いもの: 対応を確かめていない

2Tomcat 自体が Java のプログラムである

公式の の(Tomcat 11.0.26 / 25)の中を見た結果です。起動スクリプトは、最後に コマンドへ Bootstrap という名を渡しています。本体は、強調した catalina.jar など、 に並んだ 35 本の です。# で始まる行は補足です。

Tomcat 11.0.26 のフォルダの中(tomcat:11.0-jdk25-temurin)コマンド出力
# 起動スクリプト bin/catalina.sh のうち、起動するクラスの名前が出てくる行(左は行番号)
346: org.apache.catalina.startup.Bootstrap "$@" start
357: org.apache.catalina.startup.Bootstrap "$@" start
422: org.apache.catalina.startup.Bootstrap "$@" start \
 
# lib/ の中(先頭の8件。全部で 35 件あり、すべて .jar)
annotations-api.jar
catalina-ant.jar
catalina-ha.jar
catalina.jar
catalina-ssi.jar
catalina-storeconfig.jar
catalina-tribes.jar
ecj-4.40.jar
...
 
# bin/ の中にある JAR
bin/bootstrap.jar
bin/commons-daemon.jar
bin/tomcat-juli.jar

3Servlet の API は JDK に入っていない

クラスの名前を渡して、今の Java の中にあるかを尋ねるコードです。 の API は新旧どちらの名前でも見つからず、Tomcat か、依存として足した JAR が持ってきます。一方、同じ で始まる は JDK の一部で、 への改名の対象ではありません。

Java

4デプロイのログと、Spring Boot の起動ログを並べる

(1) は先に起動しておく Tomcat が、置かれた をしたときの行です。(2) は のアプリを で起動したときの行で、Tomcat はアプリの中から起動されています。どちらも Tomcat が動いていますが、どちらがどちらの中にいるかが逆です。... の行は省略で、時間の数字は各1回の値です。

Tomcat が出てくる2種類のログ(Tomcat 11.0.26 / Spring Boot 4.1.1、抜粋)追跡ログ
# (1) 先に起動しておく Tomcat 11.0.26 に WAR を置いたとき(Tomcat のログ)
INFO [main] ...VersionLoggerListener.log Server version name: Apache Tomcat/11.0.26
...
INFO [main] ...HostConfig.deployWAR Deploying web application archive [/usr/local/tomcat/webapps/demo.war]
INFO [main] ...HostConfig.deployWAR Deployment of web application archive [/usr/local/tomcat/webapps/demo.war] has finished in [84] ms
...
INFO [main] ...Catalina.start Server startup in [116] milliseconds
 
# (2) Spring Boot 4.1.1 のアプリを java -jar で起動したとき(アプリのログ)
$ java -jar target/demo-0.0.1-SNAPSHOT.jar
...
:: Spring Boot :: (v4.1.1)
...
... INFO 1 --- [demo] [main] o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
...
... INFO 1 --- [demo] [main] o.s.boot.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
... INFO 1 --- [demo] [main] com.example.demo.DemoApplication : Started DemoApplication in 0.657 seconds (process running for 0.891)

5たとえが当たらない点: Express と Node の http サーバ

Servlet を Express の、Tomcat を Node の http サーバにたとえると読みやすくなりますが、どちらもたとえで、外れる点があります。Tomcat を Express にたとえるのは、層が違うので当たりません。

Web の用語と Node の用語: 当たる点と当たらない点表
Tomcat と Node の http サーバ
当たる点 : ソケットを開いて HTTP を解釈し、アプリのコードを呼ぶ
当たらない点: http サーバは Node に入っているライブラリで、
アプリが自分で createServer する
Tomcat は(従来の使い方では)先に起動しておく製品で、
アプリのほうが WAR として置かれる。アプリに main が無い
Tomcat は1つの要求に1つのスレッドを割り当てる
 
Tomcat と Express
当たらない寄り: Express はルーティングとミドルウェアの層で、
ソケットを開くのは Node の http
Java でこの層に当たるのは Servlet の API か Spring MVC
 
Servlet と Express のハンドラ
当たる点 : 要求と応答の2つを受け取って処理する、
サーバから呼ばれるコード
当たらない点: ハンドラは関数。Servlet はクラスのインスタンスで、
init / service / destroy という一生を持つ
1つのインスタンスを複数のスレッドが同時に呼ぶことがある
URL との対応づけはコードではなく、web.xml か
アノテーションでコンテナに伝える
 
WAR / デプロイ
当たるもの : Node には無い
(アプリをサーバ製品に渡す、という形が無い)

図やコードに出てくる用語(タップで説明)