お知らせ−−−このページの文字コードはShift_JISを使用しています。

(前のページに戻る)
(目次に戻る)

21 サーブレットからアプリケーションを起動する(段階16)

 前セクションでサーブレットとアプレットを組み合わせてインタラクティブに用いる方法を紹介しました。
 しかし、ここまできて若干の問題が生じてきました。と言いますのは、JDK1.4のコンパイラでコンパイルしたアプレットのクラスファイルをIEやNetscapeで閲覧しようとしても、そのままではこれらのアプレットは動作しないのです。もし動作させようと思うなら、IEやNetscapeのブラウザにJDK1.4用のJavaのアプレットを動作させるインタプリタ(Java Vertual Machine--JVM)をプラグインする必要があるのです。
 逆に考えると、IEやNetscapeにJDK1.4のアプレットのインタプリタをプラグインしないであろう一般の多くの人には、JDK1.4バージョンのアプレットは正常には動作しないということにもなります。要するにここに来て(2002年9月現在)アプレットの普遍性が一般ユーザーには薄れてしまった訳です。
 どうしてこういうことになったのかは、私としては詳しい事情は知りませんが、恐らくJavaのシェアの現状に脅威を抱いた勢力が存在して、何らかの形でこれにストップをかけたいという事情が働いたのではないでしょうか。従いまして、このままではJavaのアプレットはイントラネットやLANでは強力な力を発揮しますが、一般ユーザーがインターネット上で使用するには影が薄くなると思います。
 さて、そうした複雑な人間社会のやり取りから生まれた、こうした不便な問題はしばらく棚に上げておくことにします。では、今後Javaとどのように付き合っていったらよいのでしょうか。
 幸いJavaは新しい方向へ発展し、今ではサーブレットプログラムという便利なNet言語へと進化しました。このサーブレットはJavaアプリケーションを一般ユーザーの求めに応じてサーバー側で動作させ、一般ユーザーのブラウザにその結果を送り返すことができます。これは非常に便利な機能なので、アプレットが普遍性を失ったことなど帳消しにしてしまうくらいの効果があります。この優れた便利な機能に狙いをつけて、これから益々Javaのプログラミングを掘り下げていくことが可能です。

@ 最も基本的なサーブレットとアプリケーションの連携

 1) GUI表示におけるアプレットとアプリケーションの違いについて
 これまでにネットワークの手法として、アプレットから始まりCGI、サーブレット、そしてサーブレットとアプレットの連携と試みてきましたが、2002年9月時点でのアプレットの一般ユーザに対する普遍性の喪失といった事情を考えると、ここではどうしてもサーブレットとアプリケーションの連携を考えていかなければならないと思います。もしそうしないと、Javaはネットワーク言語から遠ざかってしまい、多くの人の脳裏から忘れ去られてしまう危険性すらあります。この講座では、どうしてもそういう状況を回避したいと思います。そして、そうした短絡的な思いはJavaの持つ能力から必然的に駆逐できるということを示さなければなりません。  さて、Javaのアプリケーションですが、アプリケーションを起動させるにはWindows上ではMS-DOSプロンプトのコマンドライン上で

例えば   D:\Java\testprgm>java Keisan

 のように入力して起動させることは、この講座のセクション5 アプレットとアプリケーション(段階1)のA Javaのアプリケーションとは何かで触れました。しかし、インターネットを利用する一般のユーザーの方がある特定のサーバー上のアプリケーションを、遠く離れたそれぞれの人のブラウザ上からコマンドラインを使って起動させることはできません。そこで、遠く離れた場所からアプリケーションを起動させる方法としてサーブレットを使うということになる訳です。
 サーブレットは、それぞれの別の場所のブラウザからサーブレットが置かれている場所を指定して、全く別の場所にあるサーバーコンピュータ上のプログラムを起動させることができます。そして、そのサーバー上で複雑な処理をさせ、再び指示を発した遠く離れたブラウザにその結果を戻したり、或いはサーバー上に様々な 処理の結果を残すことができます。
 さて、アプレットでGUIにパネルを配置し、そのパネルの中にボタンを一つ表示させるにはどのように書けばよいのでしょうか。もう既に説明しましたが、アプレットで書くと次のようになります。

Frametest.java(アプレット)

import java.applet.*;
import java.awt.*;

public class Frametest extends Applet
{
 Button b1;
 Panel p1;

 public void init( )
 {
  setBackground(Color.yellow);
  p1 = new Panel( );
  b1 = new Button("ボタン1");
  p1.add(b1);
  add(p1);
 }
}


 これをコンパイルしクラスファイルを作り、HTMLファイルに

<applet codebase="./sonota/" code="Frametest.class" width=300 height=100></applet>

 と呼び出せば、300×100という指定サイズのアプレットを実行することができます。

Frametest.classのアプレットの表示

しかし、ここで紹介するアプレットはJDK1.4のバージョンを使いコンパイルしているので、ブラウザにJDK1.4のアプレットのインタプリタがプラグインされていないと見ることができません。そこでJDK1.4のコンパイラをプラグインしていない人のためにjpg形式の画像をここにリンクして、実際の様子を表示しておきます。

Frametest.classのアプレットの様子をjpg画像で表示するとこのとおりです。

 ところで、アプリケーションで同様の表示をしようとすると若干違う取り扱いになります。要するにアプリケーションではButtonとかLabel等々の部品は、Frameという表示用クラスの上に配置することになります。また、アプレットはinit( )メソッドを用いてプログラムを開始(初期化)させるのに対して、アプリケーションはmain( )メソッドを用いてプログラムを実行します。
 従って、最初にFrameクラスのインスタンスを作り、その中にいろいろな部品を配置し、main( )メソッドでプログラムを実行し、Frameを表示させることになります。

 2) 実際にアプリケーションで部品を表示する
 次に実際にインスタンスの作り方を考えます。上に示したアプレットと全く同じGUIをアプリケーションでプログラムすると次のとおりになります。

Frametest1.java(アプリケーションの)コード

import java.awt.*;                ・・・・・@

public class Frametest1 extends Frame      ・・・・・A
{
 Button b1;
 Panel p1;

 Frametest1( )                  ・・・・・B
 {
  p1 = new Panel( );
  b1 = new Button("ボタン1");
  p1.add(b1);
  add(p1,"North");               ・・・・・C
  setBackground(Color.yellow);
  setTitle("フレームのテスト");         ・・・・・D
  setSize(300, 100);              ・・・・・E
 }

 public static void main(String arg[ ])     ・・・・・F
 {
  Frametest1 ftest1 = new Frametest1( );    ・・・・・G
  ftest.show( );                 ・・・・・H
 }
}


 このコードを入力しましたら、アプレットと全く同様の方法でFrametest1.javaという名前を付けて保存し、Javaのアプレットと同様の方法でjavac Frametest1.javaとコマンドラインに入力してコンパイルしてください。そして、その結果生成したクラスファイルFrametest.classをコマンドラインからjava Frametestと指示し、プログラムを実行してみてください。実行の結果は次のようになります。

アプリケーションFrametest1.classクラスの実行結果

 この画像はjpg形式のものでプログラムの実行結果をお見せするためのものですから、その点は勘違いしないようにしてください。
 このプログラムはフレームと、そこに配置された部品を表示するだけのもので、プログラムを閉じることすらできません。しかし、アプリケーションとしてFrameクラスのftest1というフレームを表示することができます。とじることができませんから、プログラムを閉じるときにはMS-DOSのコンソールをアクティブにしてCtrlキーを押しながら、アルファベットの文字キーのCキーを押してください。そうすればプログラムを終了させることができます。
 さて、アプリケーションとはなんとも不便なものと思ってもらっては困ります。後はアプレットのときに使った文法に従えばどんなことでもさせることができます。
 このプログラムを口頭で説明するとすれば「Frameクラスを継承したFrametest1クラスのインスタンスFrametest1( )を作り、main( )メソッドを使いFrametest1クラスのオブジェクトftest1をshow( )メソッドで呼び出す」ということになると思います。
 次にこのプログラムを具体的に説明すると以下のとおりになります。

@行目でButtonとかPanel等の部品を取り扱うためのawtパッケージというものをimportします。これについては、後でもう少し説明しますが、基本的にはアプレットの考え方と全く同じです。
A行でここで作るFrametest1クラスにFrameクラスを継承して、Frameクラスの機能をそっくり引き継ぎます。この継承の考え方はJavaの最も基本となる考え方ですから、もしよく分からなければこの講座のセクション19 Javaのオブジェクト指向を考える(段階14)を徹底的に見直してください。
B行でFrameクラスの機能を引き継いだFrametest1クラスのインスタンス(実体とか実例)をFrametest1( )と定めます。そして{ }の中にそのインスタンスの具体的な構造を記します。
C行は、Frameクラスの場合はデフォルトのレイアウトはBorderLayoutなので、アプレットと同じ位置にパネルを配置するにはこのようにしてやります。このようなJavaのレイアウトについては、この講座のセクション8 アプレットのレイアウトを考える(段階4)の@ 部品のレイアウトを工夫する。で詳しく説明してありますので、それを参照してください。
D行でフレームにタイトルを入れることができます。
E行でフレームのサイズを決めます。
 このDとEについては、アプレットではHTMLファイルの方で指定しますが、アプリケーションではHTMLファイルは使いませんので、プログラムの中で決めることになります。
F行はアプリケーションを実行するときのいつものやり方です。
G行で、Frametest1のオブジェクトftest1を作り、
H行で、show( )メソッドで実際に表示します。

 次に同じプログラムをアプレットとアプリケーションで分かり易くするため、HTMLファイルで作ったフレームを使って比較してみます。

 

 この二つのコードを比較すると、アプレットとアプリケーションの違いがよく分かることと思います。

 このFrametest1クラスとftest1というフレームをアプリケーションで表示させる話は以上ですが、それにしてもGUIでこのクラスを終了できないのは不便極まりないと思います。そこでこのプログラムを若干改良し、GUI上でButtonをクリックすれば閉じるようにしてみます。そして始めはアプリケーションとして実行できるように考えますが、それができたらサーブレット上で実行させるにはどうすればよいかという方向に発展させたいと思います。
 FrameにButtonを配置し、クリックするとFrameが閉じるという考え方は、この講座ではセクション7 四則の演算をする(段階3)B 入力の窓を持った計算ソフト(整数)のところでふれた内容と基本的には同じです。必要な部品は、Buttonクラスを用いてクリック用のボタンを作ることと、そのボタンをクリックしたときにプログラムを閉じるというeventを実行させることが必要になります。このとき用いる部品であるButton等々は、JavaのGUIのツールキットであるAWT(Abstract Windows Toolkit)で提供されています。これを直訳すれば、抽象的窓口表示用道具セットということになりますが、このAWTにはJavaで使うGUIの様々な部品のクラスがパッケージとして組み込まれています。従ってJavaのGUIの部品クラスを使用するときは、アプレットであれアプリケーションであれ、さらにはサーブレットであっても全てプログラムの冒頭に

import java.awt.*;

と書く必要があり、awtパッケージをインポートしなければなりません。
 そして次に、これらの部品に機能を与えるためには、例えばボタンをクリックしたときに発生するイベントを感知するために、イベントのインターフェースを使用できるように、やはりプログラムの冒頭で
import java.awt.event.*;

という書き込みをして、eventパッケージをインポートしてやる必要があります。そうした上で、アプレットと同じような考え方で、部品を配置したりイベントを感知するためのメソッドを定義したりします。
 以下に、Frame上にあるボタンをクリックしたときに、このプログラム自体が終了する機能を備えたアプリケーションプログラムを紹介します。

Frametest2.java

import java.awt.*;
import java.awt.event.*;

public class Frametest2 extends Frame implements ActionListener  ・・・・・@
{
 Button b1;
 Panel p1;

 Frametest2( )
 {
  p1 = new Panel( );
  b1 = new Button("閉じる");                    ・・・・・A
  b1.addActionListener(this);                    ・・・・・B
  p1.add(b1);
  add(p1,"North");
  setBackground(Color.yellow);
  setTitle("フレームのテスト");
  setSize(300, 100);
 }

 public void actionPerformed(ActionEvent ae)            ・・・・・C
 {
  if(ae.getSource( ) == b1)                     ・・・・・D
  {
   System.exit(0);                         ・・・・・E
  }
 }

 public static void main(String arg[ ])
 {
  Frametest2 ftest2 = new Frametest2( );
  ftest2.show( );
 }
}


 このプログラムをいつものとおりjavacでコンパイルし、javaで実行するとアプリケーションのFrametest1と見た目は全く同じ実行結果になります。しかし、実際にやってみれば分かるでしょうが、閉じるボタンをクリックすればこのFrametest2クラスは終了し、閉じるようになっています。是非皆さんが自身のコンピュータを使って、ここでお話したことを実際にやってみて試してください。
 さて、いよいよアプリケーションをサーブレットプログラムに組み込み、サーバー上で実行させるという試みのところまでやってきました。今まではアプリケーションとして取り扱ってきたプログラムであるFrametest2.classのフレームを、クライアントからの指示に基づき、サーバー上で実行してみることにします。

 3) サーブレット上でFrametest2.classのフレームを表示させる。
 今までのアプレットやアプリケーションは、処理を要求するクライアントと、その要求を実行する実行環境が同一のパソコン等にありました。しかしサーブレットでは、処理を要求するクライアントと、その要求を実行する実行環境が全く別のところにあります。これを分かり易く図示すると次のようになります。

a) アプレットの場合

b) アプリケーションの場合

c) サーブレットによるアプリケーションの実行の場合

 c)のサーブレットによるアプリケーションの実行を見ても分かるように、サーブレットを利用すれば、Javaのアプリケーションをサーバー上で実行することができます。そのための手段としては、先ずクライアント側からサーバーに対して何らかのパラメータを送ってやり、サーブレットプログラムを起動してやります。その時、そのサーブレットプログラムの中に必要なアプリケーションを組み込んでおいてやればよい訳です。
 この方法は最も基本的な方法ですが、クライアント(ブラウザ)とサーバー上のサーブレットに組み込まれたアプリケーションプログラムの実行が可能です。
 この一連の処理の実行環境としては、クライアント側にはパラメータを渡せるようにしたHTMLのドキュメントに<Form>タグを使って、例えばテキストフィールドを準備します。そして、サーバー側にはセクション18 Javaのサーバー機能とサーブレット(段階13)の A 最も易しいカウンタプログラム 3)JSDKを利用するで説明した方法で、あなたのパソコンにサーブレットランナー(servletrunner)を実行しておきます。その他の、これから作成するサーブレットプログラムのコンパイルやコンパイル後のクラスファイルの置き場所、HTMLドキュメント内で呼び出すサーブレットクラスの場所の指定等は、3) JSDKを利用するで説明した方法と全く同様です。

★ サーブレット起動用のFormを作る
 それでは、サーバー上に置かれているサーブレット起動用のHTMLドキュメントを考えてみます。このドキュメントは、インターネットに接続しているサーバーであればどこに置かれていても構いません。HTMLドキュメントの中に、今、自分が呼び出したいサーブレットクラスのインターネット上のアドレスをしっかりと指定してやればよいということです。(・・・これはCGIではどうなんでしょうか。私はCGIは詳しくないのでよく分からないのですが、CGIでも利用するCGIの置き場所さえしてやれば、呼び出し用のHTMLドキュメントはどのサーバーに置こうと構わないんでしょうか?・・・多分構わないのでしょうが、誰か詳しい方がいたらお教えください。E-mail:kogasaki@mb.infoweb.ne.jp)
 しかし、サーブレットがCGIとはっきり違うところは、そのサーブレットが置かれているクラスは常時動作しているということです。そうした意味ではこれから利用する上でサーブレットは非常に便利です。
 ではとりあえず、次にサーブレット起動用のHTMLドキュメントをFrametest3.htmlという名前で作ってみます。特に注意することは、文字コードをcharset=iso-2022-jpと指定することと、このHTMLドキュメント自体をJISコードで作成するという点です。これは、前にも説明していますが、サーブレットエンジンにJSDK2.0を使っているため、JISコードで構成する必要があるためです。

Frametest3.html

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-2022-jp">
<title>Frame Test(Frametest3)</title></head>
<body>
<center><Font Size=5><B>Servletプログラムからフレームを呼び出す。</B></Font><P>

<Font Size=4>次のフォームにあなたの名前を入力してみて!!</Font><P>

<form method="POST" action="http://127.0.0.1:8080/servlet/Frametest3">
あなたの名前(アルファベットで入力してください。):<input type="TEXT" name="your"><P>

<input type="submit" value="入力OK!"> <input type="reset" value="リセット"></form></center>
</body>
</html>


 次に、このドキュメントをブラウザに実際に再現すると次のようになります。

Frametest3.htmlをブラウザ上での実際の表示

 皆さんは、サーブレットランナーを使いバーチャルサーバーを使っていますが、このフォームは、私のapacheサーバー上のサーブレットのデーモン(常に動作しているサーバー用プログラム)Jservでパラメータを受け取りますのでactionの指定先action="htto://www.e-asu.com/servlets/Frametest3としています。この点だけは違っていますが、後は全て同じです。

★ フレームを実行するサーブレットプログラム
 そしてフレームを実行する肝心のサーブレットプログラムのコードは、一例として次のように書くことができます。このプログラムは、テキストフィールドにあなたの名前でも何でも構いません。入力してボタン入力OK!をクリックし、パラメーターがサーバー上のFrametest3.classに届くと、このFrametest3.classクラスがJserv上で実行され、サーバー上にフレームを表示させます。このフレームは、サーブレットランナーを使って実行しているバーチャルサーバー上では同一のパソコン等で直接見ることができますか、通常のインターネット上では、クライアント側からは直接確認することはできません。しかし、クライアントのブラウザからどんなに遠く離れた場所にあるサーバーでも、サーブレットの実行環境上にこのクラスファイルが置かれていれば、フレームを確実に表示させることができます。

Frametest3.java

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Frametest3 extends HttpServlet
{
 String namae, your;
 Frametest2 frt2;

 /*public void init(ServletConfig conf) throws ServletException    ・・・・・@
 {
 }*/                                    ・・・・・A

 public void doPost( HttpServletRequest req, HttpServletResponse res )throws ServletException, IOException
 {
  frt2 = new Frametest2( );                       ・・・・・B
  frt2.show( );                              ・・・・・C
  res.setContentType("text/html;charset=ISO-2022-JP");         ・・・・・D
  PrintWriter pw = res.getWriter( );
  pw.println("");<br>   pw.println("Frame_Test");<br>   pw.println("");
  pw.println("");
  namae =new String( req.getParameter("your").getBytes( ), "JIS");  ・・・・・E
  pw.println(namae);
  pw.println("");
  pw.println("");
  pw.close( );
 }
}

class Frametest2 extends Frame implements ActionListener        ・・・・・F
{
 Panel p1;
 Button b1;

 Frametest2( )                              ・・・・・G
 {
  p1 = new Panel( );
  b1 = new Button("Frameを終了");
  b1.addActionListener(this);
  p1.add(b1);
  add(p1, "South");
  setTitle("フレームのテスト");
  setSize(300, 200);
 }                                     ・・・・・H

 public void actionPerformed(ActionEvent ae)              ・・・・・I
 {
  if(ae.getSource( ) == b1)
  {
   dispose( );                             ・・・・・J
  }
 }
}


 ところで、このプログラムを説明しますと、始めのimport部分はそれぞれのパッケージをimportしています。既に何度も説明してきたので、ここではもう説明しません。
 次に@行からA行の部分は、参考にお見せしておきました。このinit( )メソッドはアプレットのときと同じで、Frametest3.classが最初に読み込まれた時の一度だけ、{ }内の内容が実行されます。それ以降は、このメソッドは実行されません。従って、最初の一回だけ実行させたいことがあれば、ここで指示しておくことになります。
 次のB行とC行が一番のポイントです。アプリケーションの時はpublic static void main( )メソッドの中で実行させました。サーブレットでは、このmain( )メソッドと同じ役割を果たすメソッドがdoPost( )メソッドです。従って、サーブレットで実行させたいことは、このdoPost( )メソッドの中に書き込みます。
 D行は、このサーブレットがブラウザに送り返す結果の文字コードの定義です。要するにHTML形式、文字コードはJISでアクセスをかけてきたブラウザにレスポンスを返します。
 F行以下はアプリケーションと全く同じです。アプリケーションをこのようにしてサーブレットプログラムに組み込むことができるという分かり易い例ですのでよく比較してください。
 GからH行までがFrametest2クラスのインスタンスを定義した部分で、IからJ行までがButton b1にイベントを受け取る時の条件を書いたものです。これはアプリケーションのときと全く同じです。
 ここでつくづく考えておくこととしては、Javaのオブジェクト指向が如何に便利であるかということです。フレームを表示するFrametest3.classとフレームの形式を規定するFrametest2.classが全く独立しているということです。Frametest3.classではdoPost( )メソッドにより、Frametest2.classでフレームの細部を規定したクラスファイルを実行するだけです。従って、実行するフレームのGUIの設計は、何者にも捕われずFrametest2.classで自由にできるのです。
 このため、クライアントからインターネットを経由して送られてきたデータとしてのパラメータを、doPost( )メソッドで受け取り、Frametest3のクラス変数に保管しておけば、その後、そのクラス変数をどういうふうに取り扱うかは、Frametest3.classの設計とは全く切り離してFrametest2.classで独自に取り扱えるということです。もっと簡単に言えば、Frametest3.classの設計とFrametest2.classの設計は、お互いに干渉しないということです。
 これは、オブジェクト指向のプログラム言語の最大のメリットです。もし、こうしたことをオブジェクト指向でないプログラム言語で行おうとすると、実行部分と設計部分が微妙に関連し互いに干渉しあうため、ある部分の変数の用い方が別の部分の構造に思わぬ影響を与えて、テストを何度も繰り返さないとうまくいかないという現実の問題が重く押し被さってきます。Javaを使っているとなんでもないことでも、他のプログラム言語では大変な作業になってしまうということが、現実には非常に多く存在します。
 ちょっと本題から反れましたが、以上が、フレームを組み込んだ最も基本的なサーブレットプログラムの説明です。後は、この考え方をどんどん拡張していけば、世界中のユーザーがあなたのコンピュータに送り込んできたデータを、Javaのアプリケーションを使ってどのようにでも取り扱えるという訳です。その活用方法はインターネット上でのアンケート調査、注文表の整理、意見の集約等々、あなたのサーバーは、特定の或いは不特定多数のユーザー(クライアントのブラウザ)からPOST形式で送られてきたパラメータを、Javaのアプリケーションで変数として受け取り、データベースアプリケーションに渡したり、目的に応じて直接処理したりできるのです。もちろん、その結果を即座にアクセスしてきたユーザーのブラウザに返すことだってできます。要するに、この原理さえ知っていれば後は応用さえすればよいのです。
 では次のページでは、アプレットとサーブレットそしてアプリケーションという、三つの代表的なJavaプログラムを連携させた応用システムについて考えてみることにします。

(目次に戻る)
(次のページに移る)


 このホームページの内容はすべて自由に使用することを認めます。使用・活用等をする旨と使用目的の連絡を入れるようにお願いします。なお、使用・活用者の連絡先を記入しておいてくださるようお願いいたします。また、Java及びこのページ等で私宛にご意見・質問・問合せ等がある方は、Eメールを利用してご連絡ください。後ほど返事をさせて頂きます。

問い合わせ等はここをクリックしてください。kogasaki@mb.infoweb.ne.jp

電話及びFAX:047-362-1143(斉藤信之)
電話・FAXでの問合せに関するお願い…問合せはなるべくE-Mailを使うようにお願いします。
状況によりE-Mailではうまく問合せができないとき等で電話やファックスを使用して問合せる時は、P.M.8時から11時迄にお願いします。

住所:〒271-0068 千葉県松戸市古ヶ崎 2-3231-7