◆ はじめに
本ページは、とにかく、メモです。普通、サーブレットの解説本は、前半をTomcatのインストールと設定に終始します。しかし、本メモは、すでにされている状態からスタートします。なぜって、それは、もう、私の会社の後輩がそこのところを設定してくれて、私は、何も知らないからです。ゴメン!
とにかく、なんとか、サーブレットが動く環境をご用意してください(以下のダウンロードのリンクを辿って...)。しかし、それが自力で出来た人は、以下のことぐらいは、もうすでのにご存知だと思います。だから、本タイトルは、単に忘れないための、サーブレット・メモなのです(謎梨)。
また、サーブレットが動く環境など設定せず、単にサーブレットの概略を知りたい人には、ざーっと読んでいただければ、なんとなくサーブレットの雰囲気がわかると思います。
では、『サーブレットとは』から...。
◆ もくじ
◆ サーブレットとは
サーブレット(Servlet)は、主にWebサーバと連携してJavaのプログラムを動作させるための仕組みで、サーバサイドでのJava実行形態の1つです。
まぁ、Webサーバ側で動作するJavaアプレットで、Java版のCGIみたいなものです。
サーブレットは、Webサーバの一部として動作するため、セッション管理を行うこともでき、また、常駐している分、実行速度も速くなります。
また、普通のJavaアプリケーションやJavaアプレットと違い、JavaVM(Javaバーチャルマシン)上で動作するのでなく、サーブレットコンテナ(Servlet Container)という実行環境の上で動作します。ちなみに、本ページで説明しているサンプルのサーブレットコンテナは、Tomcat4です。
◆ サーブレットコンテナのダウンロード
サーブレットを使いたいという人は、以下の辺でJavaとTomcatをダウンロードして、Javaのコンパイルが出来て、サーブレットが動作する環境を設定してください。
尚、私は、この辺に関して特に詳しくないです。申し訳ない! 実は、Javaそのものも詳しくないです。これから、あなたと一緒にお勉強をしていきましょう!
あと、以下の内容は、「アプレットの基礎」を一通り理解できたレベルで記述されています。とりあえず、先に一読することをお薦めします。
◆ サーブレットサンプルの説明
まずは、以下のソースをご覧ください。尚、Lesson01ではなく、いきなりLesson05xですが、あまり気にしないでください。
また、単にサーブレットにターゲットを絞るのではなく、Java言語仕様の概要、オブジェクト指向の概念等を織り交ぜながら解説していきます。
では、本題に入ります。このクラスの処理は、URLで引数なしで Lesson05x をハイパーリンクすると『0から100までの数〜』を入力するフォームのページが表示されます。
つぎに、フォームのテキストボックスに数を入力してサブミットするとmethod属性getで引数つきでハイパーリンクされ、『あなたが思い浮かべたのは〜』のページが表示されます。
実際にWebブラウザからURLを指定しないとイメージがつかめないと思いますが...。とりあえず、先に進みます。
Lesson05x.javaのソース
では、サーブレットのサンプルソースLesson05x.javaをステップごとに詳細に説明して行きます。
尚、本ソースは、アプレットと同じく丸の内とらさんの『初体験Javaサーブレット』を大変参考にしています。著作権等の問題がありましたら、ご連絡ください。いつもお世話になっています!
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Lesson05x extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html; charset=SJIS"); PrintWriter pw = response.getWriter(); String strValue = request.getParameter("param"); if (strValue == null) { pw.println("<html><head><Title>なんちゃって読心術</title></head>" + "<body><center><h2>なんちゃって読心術</h2><hr size=0><br><br>" + "0から100までの数字の中から、好きなものを思ってください。<br>" + "思い浮かべたら、その数に100を掛けてください。<br>" + "次にそこから28を引きましょう。<br>" + "更にその数を2倍してください。<br>" + "最後にそこに16を足してください。<br><br>" + "<hr width=500 size=0>" + "<form action=/koike/servlet/Lesson05x method=get>" + "答えはいくつになりましたか?<br>" + "<input type=text name=\"param\"><br><br>" + "<input type=submit value=\"送信\"></form></body></html>"); } else { int intAnswer = ((Integer.parseInt(strValue) - 16) / 2 + 28) / 100; pw.println("<html><head><title>なんちゃって読心術---こたえ---</title></head>\n" + "<center><br>あなたが思い浮かべたのは" + intAnswer + "ですね。<br>\n"); } } }
import文
import java.io.*; import javax.servlet.*; import javax.servlet.http.*;
これは、指定したパッケージのクラスを取り込んで(importして)います。「*」になっているのは、そのパッケージに含まれるすべてのクラスを対象としています。なぜ、importしているかというと、Lesson05xで使いたい機能がそこにあるからです。
尚、 javax.servlet.httpはjavax.servletに含まれるイメージですが、javax.servletとjavax.servlet.httpは全く別パッケージです。
また、最後が「*」以外のときは、そのパッケージのひとつのクラスそのものになります。
java.io パッケージ
このパッケージには、データストリーム、直列化、ファイルシステムによるシステム入出力等のクラスがあります。
javax.servlet パッケージ
このパッケージには、サーブレットで発生する例外 SevletExceptionクラス等があります。
javax.servlet.http パッケージ
通常、サーブレットはHttpServletクラスを継承して作成しますが、これがここにあります。また、HttpServletRequestやHttpServletResponseのインターフェイスもここにあります。
補足:パッケージについて
ある一つのJavaのソースファイル(Lesson05x.java)は、クラスの集まりで、その集まりをパッケージと言います。また、特にパッケージ宣言がないものを無名パッケージいい、有名にしたい時は、以下のようにパッケージ宣言を行います。
package パッケージ名;
複数のソースファイルでも同じパッケージ名のpackage宣言がしてあれば、同じパッケージに属します。また、一つのソースファイルの中でpackage宣言は、一回だけ行うことができます。
尚、ひとつのソースファイルには、publicなクラスは、2つ以上あってはいけません。つまり、MAX一つだけ。
補足:javaxパッケージについて
javaxパッケージは、Servlet APIモジュール等で、Webサーバでサーブレットを動作させるために必要なモジュールです。
クラスの定義
とにかく、Javaで作られたプログラムはすべてオブジェクトで、オブジェクトの元になるのがクラスです。
つぎの
public class Lesson05x extends HttpServlet { : : }
は、クラスを定義しています。HttpServlet
はスーパークラスで、クラスLesson05x
はそれを継承しています。
そして、典型的なクラスは次のような構成をしています。
[クラスの修飾子] class <クラス名> extends <スーパークラス名> { //メンバ変数 [メンバの修飾子] <型> <変数名> = 値; //メソッド [メソッドの修飾子] <戻り値型> <メソッド名>([メソッド引数]) { コンピュータ制御 } //コンストラクタ [コンストラクタの修飾子] <クラス名>([パラメタ]) { インスタンス化処理 } }
クラスの中身
クラスの中身は、以下の3つがあります。
- メンバ変数 - オブジェクトの変数です。フィールド、プロパティ、クラス属性などということもあります。
- メソッド - オブジェクトの機能です。C言語でいえば、関数みたいなものです。
- コンストラクタ - メソッドの内、クラスを初期化するメソッドを特にコンストラクタといいます。
クラスの修飾子
- abstract
抽象クラス。継承されることを明示する。このクラスはインスタンス化できないクラス。サブクラスで実装してはじめてインスタンス化できる。 - final
継承されたくないことを明示する。これ以上機能拡張/変更されたくないときに使う。インスタンス化はできる。 - public
全てのクラスから参照できる。継承もインスタンス化も制限がない。 - 省略
同じパッケージ内からしか参照できない 。
メンバの修飾子
- public
アクセスに制限がない。 - protected
同じパッケージ、またはそのサブクラスからしかアクセスできない。 - 省略
同じパッケージ内からしかアクセスできない。 - private
同じクラスからしかアクセスできない。 - static
静的変数でインスタンス化の必要がない変数です。要は、インスタンス毎でなくクラス毎の変数です。 - final
初期化した値以外に変更できない。定数として用いる。 - transient
(私には、まだ説明できるレベルではありません。) - volatile
(同じく、まだ説明できるレベルではありません。)
コンストラクタの修飾子
- public
どこからでも呼び出せる。 - protected
同じパッケージか、そのサブクラスからしか呼び出せない。 - 省略
同じパッケージ内からしか呼び出せない。 - private
同じクラス内からしか呼び出せない。
メソッドの修飾子
- public
何処からでも呼び出せる。 - protected
同じパッケージかそのサブクラスからしか呼び出せない。 - 省略
同じパッケージ内からしか呼び出せない 。
- private
同じクラスからしか呼び出せないメソッド。 - abstract
抽象メソッド。抽象メソッドを一つでも持つクラスは抽象クラス。メソッド名、引数、戻り値は定義されているが、ブロック内の処理(実装)が行われていない。 - static
静的メソッド。当該メソッドが定義されているクラスをインスタンス化しなくても利用できる。インスタンスによらず同じ働きをするメソッドに用いる。 - final
オーバーライドできないメソッド。継承によってこのメソッドの機能変更/拡張はできない。 - synchronized
マルチスレッド時に同期を取るメソッド。スレッドに呼び出された時点でロックされる為、複数のプロセスによって実行されることがなくなる。 - native
(私には、まだ説明できるレベルではありません。)
補足(アクセス修飾子)
修飾子は、クラス、メンバ、コンストラクタ、メソッドを修飾しますが、そのうち、public,protected,省略,privateを特にアクセス修飾子といいます。
で、Javaプログラム(クラス)は、普通、複数のパッケージを利用します。ある一つのクラスを他のパッケージやどこからでも呼び出せる(アクセスできる)ようにすることをpublic修飾するといいます。
しかし、あんまり呼ばれるのも嫌な場合もありますので、いろいろとアクセスが制限できます。
- まず、自分のクラス内のみしかアクセスできないようにするprivate修飾。
- 自分のパッケージ内のみしかアクセスできないようにする修飾子の省略。
- 自分のパッケージ内と自分のサブクラスからしかアクセスできないようにするprotected修飾。
...があります。ちなみに、サブクラスとは、自分(スーパークラス)を継承してくれたクラスです。
メソッドの定義(オーバーライド)
メソッドは、C言語でいう関数みたいなものです。しかし、機能的にはいろいろ増えています。
public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException { : }
[メソッドの修飾子] <戻り値型> <メソッド名>([メソッド引数]) throws 例外クラスリスト { コンピュータ制御 }
戻り値型
メソッドの修飾子は、上記で説明しました。さて、戻り値型ですが、メソッドで何かの処理をしたあと結果を返す場合がほとんどです。そのときのデータの型を戻り値型といい、大きく分けて基本型(プリミティブ)と参照型(リファレンス)の2つがあります。
尚、戻り値のないメソッドの場合は、void
を指定します。
- 基本型(プリミティブ)
型名 ビット数(バイト数) 表現できる範囲 分類 byte
8 (1) (-27, 27-1) 符号付整数型 short
16 (2) (-215, 215-1) int
32 (4) (-231, 231-1) long
64 (8) (-263, 263-1) char
16 (2) Unicode の一文字 整数型(文字) float
32 (4) 単精度浮動小数点数 浮動小数点数型 double
64 (8) 倍精度浮動小数点数 boolean
? (?) true
/false
論理値型 void
? (?) 空を表す 空を表す型 - 参照型(リファレンス)
参照型には、クラス型、インターフェイス型、配列型の3つがあります。
引数
引数は、型名と変数名がペアで、複数ある場合はそのペアでのリストになります。
doGetメソッドの場合は、引数が HttpServletRequest と HttpServletResponse の2つのインターフェイス型になっています。 これらの実装は、サーブレットコンテナにあり、操作を行うためのインタフェースが提供されています。
どんなインタフェースかは、以下のリンクを参考にしてください。
- HttpServletRequest - Webブラウザからのリクエスト(フォームで入力されたもろもろのデータ)を表すオブジェクト。
- HttpServletResponse - Webブラウザへの返答を表すオブジェクト。
サーブレットコンテナ
サーブレットは、普通のJavaアプリケーションやJavaアプレットと違い、JavaVM上で動作するのでなく、サーブレットコンテナ(Servlet Container)という実行環境の上で動作します。
実体は、Servlet APIモジュール等で、Webサーバでサーブレットを動作させるためものです。
throws句
throws の後ろに、例外クラスをカンマ区切りで、複数記述することができます。
このように明示しておくと、利用者に分かりやすいだけではなく、コンパイル時に、スローされた例外が呼び出し元でキャッチされているかどうかチェックされます。キャッチされていなければ、コンパイルエラーになります。つまり、コンポーネントの開発者が、利用者に対して、例外処理を強制することができるわけです。尚、throws句が必要なクラスでthrows句を省略するとコンパイルエラーになります。
しかし、throws句を必要としないクラスでも、例外は呼び出し元に返されます。
尚、throwでなく複数形の throwsであることに注意。
コンテントタイプ設定
response.setContentType("text/html; charset=SJIS");
Webブラウザへ表示データを出力する際のコンテントタイプと漢字コードをdoGetメソッド引数のオブジェクトresponseのメソッドsetContentType()を使って設定しています。
サーブレット標準出力オブジェクト作成
PrintWriter pw = response.getWriter();
サーブレット標準出力オブジェクトをdoGetメソッド引数のオブジェクトresponseのメソッドgetWriter()を使って作成します。
尚、本オブジェクトを作成する前に必ずコンテントタイプ設定が必要です。
Webブラウザのフォームからのリクエスト取得
String strValue = request.getParameter("param");
Webブラウザのフォームからのリクエストで設定された、要素のname属性名が param の値を取得しています。
サーブレット標準出力へ出力
if (strValue == null) { pw.println("<html><head><Title>なんちゃって読心術</title></head>" + "<body><center><h2>なんちゃって読心術</h2><hr size=0><br><br>" + "0から100までの数字の中から、好きなものを思ってください。<br>" + "思い浮かべたら、その数に100を掛けてください。<br>" + "次にそこから28を引きましょう。<br>" + "更にその数を2倍してください。<br>" + "最後にそこに16を足してください。<br><br>" + "<hr width=500 size=0>" + "<form action=/koike/servlet/Lesson05x method=get>" + "答えはいくつになりましたか?<br>" + "<input type=text name=\"param\"><br><br>" + "<input type=submit value=\"送信\"></form></body></html>"); } else { int intAnswer = ((Integer.parseInt(strValue) - 16) / 2 + 28) / 100; pw.println("<html><head><title>なんちゃって読心術---こたえ---</title></head>\n" + "<center><br>あなたが思い浮かべたのは" + intAnswer + "ですね。<br>\n"); }
request.getParameter("param")で取得した値を判断して、それぞれ、サーブレット標準出力オブジェクトへprintln()メソッドを使ってWebブラウザへの表示データを出力しています。
尚、println()メソッドの引数中の + は文字列の連結になります。また、Integer.parseInt()は、引数のString型の文字列をint型の整数にして返すもので、java.langパッケージにあり、このパッケージのみは、import文なしに利用することが出来ます。
◆ おわりに
どうですか、サーブレットの雰囲気は、伝わったでしょうか。書いている本人が、Java修行中ですので、いろいろおかしな点が多々あると思いますが...、思った方、メール等でご指摘、ご指導を頂ければ幸いです。
で、次のターゲットは、『デザインパターン』と『JSP』ですか、たぶん。
では、また、お互いにJava修行に精進を致しましょう。悩みに悩んだあなたには、すぐ傍に、光が見え始めているはずです。頑張りましょう! 自分も含めて...。
未熟なコンテンツを最後まで、読んで頂いて、本当にありがとうございました。