インストールし立てのTomcatを起動してHTMLブラウザでアクセスすると、予め用意されているコンテンツ(TomcatではWebアプリと言うらしい)が表示され、ブラウザがJavaに対応していれば、サンプルのServletやJSPがすぐに動く。サンプルのServletのソースを見ることもでき、開発意欲をかき立てられる。
なお、Tomcatのマニュアル(RUNNING.txt)には、デフォルトの設定ではポート8080で待ち受けると書いてあるが、FreeBSDのportsはそれを8180に書き換えるので、注意が必要だ。
そのサンプルソースを改造して、自前のServletを作成して、いざTomcatで動かそうとすると、作成したServletをどこに置いてどういう設定をすれば良いかがわからない。
とりあえず、最初のテストとしては、クラスファイルをサンプルServletのある所(webapp/examples/WEB-INF/classes/)に置いて、サンプルServletの設定があるwebapps/examples/WEB-INF/web.xmlに同じような設定(<servlet>と<servlet-mapping>)を加えればよい。そうして新たなServletが動けば、JDKの動作には問題なしだ。
Servletのきちんとした配置と設定は、大変見つけにかったが、TomcatのマニュアルのDeploymentのページ(TomcatのデフォルトのWebアプリのページから"Tomcat Documentation"→"App Developer Guide"→"Deployment"と順に辿る)に書いてあった。Servletを動かすための最低限の準備は、
(1) Tomcatのwebappsディレクトリに新たなディレクトリ(ここでは"sample"とする)を作成し、
(2) webapps/sample/WEB-INF/classes/ にクラスファイルを置き、
(3) webapps/sample/WEB-INF/ に設定ファイルであるweb.xmlを置く
だ。web.xmlは、conf/web.xml.sampleをコピーして編集するが、筆者が試した所、Tomcat 4.1では<web-app>の中に<servlet>と<servlet-mapping>だけでうまくいったが、Tomcat 5.5では<session-config>も必要だった。
今回、試験的なアプリとして、ランダムな表を出力するServletを作ってみた。
・RandomTable Servletへのリンク
※アクセス後、ブラウザでページの更新(再読み込み)をすると違う表が出てくると思います。
※JRE 1.3.1 + Tomcat 4.1で動かしています。
・RandomTable Servletのソースコードへのリンク
・web.xmlへのリンク
※Tomcat 4.1で不要だった部分はコメントアウトしています。
ところで、Servletを試しに作って思ったことは、結局はServletはHTTPサーバー側でHTMLを出力するプログラムなので、できることはCGIと大差ないのではなかろうか、Servletの利点とは何だろうか、ということだ。(注:筆者はCGIやServletの仕様を詳しく知りません。)
比較のために、前記のRandomTable Servletと同じ事をするPerlのCGIも作ってみた。
・RandomTable CGIへのリンク
・RandomTable CGIのソースコードへのリンク
サーバー側の処理時間は、Pentium 150MHzという比較的低速のCPUで動かしても、若干PerlのCGIの方が長いが、ほとんど差が無い。0.1秒あるか無いかだ。Servletの方は、TomcatがJavaプロセスを起動しっぱなしで、その上で動いているのに対し、PerlのCGIの方は、毎回Perlのプロセスを起動しているのだが、そのオーバーヘッドは大したことが無いようだ。
ソースコードのサイズは、Javaの方が書式に制限が多いため、文字数がPerlより1.5倍くらい多い。もっともこれは書き方によるので良い比較にはならないが、少なくともHTMLを作成するコードに関しては、ほとんどの場合、テキスト処理に特化して開発されたPerlの方が短く書けると思う。
ソースコードの読みやすさについては、言語に対する慣れの問題をさておくと、特に文字列処理に関して、Javaの方は不器用で苦しそうに見えるのに対し、Perlの方は自然に見える。
プログラムの規模が大きくなると、Perlのコードも読みやすさを確保するためにオブジェクト指向型にするだろうから話は違ってくるが、プログラムが小規模なら、PerlのCGIの方がシンプルで作成しやすいと思われる。
そもそもCGIはCでもJavaでも書けるのだから、ServletとCGIを言語で比較するのは意味が無いかも知れない。ServletとJavaのCGIとを比べると、本質的な違いは何なのだろうか?
ynomura
ServletとCGIの違いであるが、プログラムを作る側にとっては、その起動形態の違いが結構大きいということがわかってきた。
CGIのプログラムは毎回ゼロから起動される(新しいプロセスで動く)ため、メモリ上のデータは毎回失われるのに対し、ServletはHTTPサーバーが動いている間ずっと動き続ける(プロセスに残る)ため、メモリ上にデータを残すことができるのだ。
具体的には、例えばServletの静的クラス変数は、そのServletが呼び出された時に前回の値が残っている。従って、そのServletが何回起動されたかは、静的クラス変数で簡単に記録できるわけだ。
同様に、HTTPセッションの保持も比較的簡単にできる。JDBCのDBとの接続をServletで一定数保持して使い回すという使い方も定番のようだ。
HTTPサーバーの一部として動くという形態のServletは、CGIよりサーバーの負荷を低く抑えられることが多いので、アクセス頻度の高いシステムでは有効であろう。
ynomura
Servletのデメリットとして、全てのServletでJava VMを共用するので、全てのServletが動く設定でJava VMを動かさないといけない。そのため、1つのServletがJava VMの設定を制限すると、全てのServletに影響してしまう。
例えば、MySQL Connector/Jモジュールを使うにはclass verifierをOFFにする必要があるので、そのモジュールを使うServletがあると、全てのServletでclass verifierが使用不能になってしまう。
JavaのCGIだとプログラム毎にJava VMの起動オプションを変えることができるので、この点もServletとCGIの違いと言えるだろう。