■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                      2007年09月30日

    楽しいJava講座 - 初心者から達人へのパスポート
                  vol.072

                                セルゲイ・ランダウ
 バックナンバー: http://www.flsi.co.jp/Java_text/
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


[このメールマガジンは、画面を最大化して見てください。]


========================================================
◆ 01.Tomcatのアプリケーション開発
========================================================


今回は、手始めに極簡単なTomcatのアプリケーションを作成して
みましょう。



まずは、Tomcatのアプリケーション用のプロジェクトを作りましょう。

Eclipseを起動しておいてください。

┌───────────────────────────┐
  1. Tomcatのプロジェクトの作成
└───────────────────────────┘

(1)メニュー・バーの「ファイル」をクリック(またはパッケージ・
エクスプローラー内で右クリック)し、「新規」→「プロジェクト」
を選択します。

(2)「Java」の中の「Tomcatプロジェクト」を選択し、「次へ」ボタン
をクリックします。

(3)「プロジェクト名」に
JStudy2
と入力し、「次へ」ボタンをクリックしましょう。

(4)「コンテキスト名」に/JStudy2がはいっていることを確認します。
また、「Webアプリケーション・ルートとするサブディレクトリー(オプ
ション)」という項目がありますが、これはデフォルト(/)のままにし
ておいてください。これが何を意味するのかは、後でお話します。

ここでは、そのまま「終了」ボタンをクリックしてください。

これでプロジェクトができましたので、次にサーブレット用のJavaの
パッケージを作成しましょう。


┌───────────────────────────┐
  2. サーブレットのパッケージの作成
└───────────────────────────┘

(1)パッケージ・エクスプローラー内で今作成したプロジェクトのJStudy2
を右クリックし、「新規」→「パッケージ」を選択します。

(2)ソース・フォルダーがJStudy2/WEB-INF/srcになっていることを確認し、
「名前」に
jp.flsi.lecture.servlet
と入力して、「終了」ボタンをクリックしましょう。
(ここで、JStudy2/WEB-INF/srcのsrcは、先日(vol.070で)Eclipseの
「ソースおよび出力フォルダー」の設定を変更してbinとsrcに分けたとき
のsrcフォルダーを意味します。また、WEB-INFについては後ほど説明します。)


これで、JStudy2プロジェクトのWEB-INF/srcディレクトリー下に
jp.flsi.lecture.servletパッケージが用意されました。

では、続いてテスト用のサーブレットを作ってみることにしましょう。
以下のようにして、このjp.flsi.lecture.servletパッケージの中に、
TestServletという名前のサーブレットを作ってみてください。


┌───────────────────────────┐
  3. サーブレットの作成
└───────────────────────────┘

(1)パッケージ・エクスプローラー内で今作成したパッケージの
jp.flsi.lecture.servletを右クリックし、「新規」→「クラス」
を選択します。

(2)ソース・フォルダーがJStudy2/WEB-INF/srcになっていることを確認し、
「パッケージ」がjp.flsi.lecture.servletになっていることを確認し、
「名前」に
TestServlet
を入力しましょう。

今作成しようとしているクラスはサーブレットですが、サーブレットは
Servletというインターフェースを実装(implements)しなければなら
ないことになっています。
しかし、実際にはHttpServletというクラスによってServletの基本的な
実装(implements)が行われていますので、このクラスのサブクラスと
して作成すればいいことになっています。

そこで、「スーパークラス」に
javax.servlet.http.HttpServlet
と入力してください。(直接入力するよりも、「参照」ボタンをクリック
し、HttpServletと入力して選択すると簡単です。)

最後に「終了」ボタンをクリックします。


┌補足─────────────────────────┐
以前(vol.067で)お話したように、サーブレット関連のインター
フェースやクラスはJava EEによって提供されています。つまり、
上記のServletやHttpServletはJava EEのAPIに含まれています。
Java EEのAPIは
http://java.sun.com/
のホームページからもダウンロードできますが、Tomcatをインス
トールした場合は、サーブレットやJSPのAPIがTomcatの中に含まれ
ているので、Java EEのAPIを別途ダウンロードする必要はありま
せん。

なお、Java EEのAPIの詳細については、
http://java.sun.com/javaee/5/docs/api/
などを参照してください。
ちなみに、Servletはjavax.servletパッケージ、HttpServletは
javax.servlet.httpパッケージにはいっています。
└───────────────────────────┘

(3)TestServletのエディターが開きますので、次のようにソース・コード
を編集してみてください。

--------------------------------------------------------
package jp.flsi.lecture.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestServlet extends HttpServlet {

   public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
      response.setContentType("text/html");
      PrintWriter out = response.getWriter();
      out.println("<HTML>");
      out.println("<HEAD>");
      out.println("<TITLE>Servlet Test Page</TITLE>");
      out.println("</HEAD>");
      out.println("<BODY bgcolor=\"#77ffff\" text=\"#fa5a00\">");
      out.println("<H1>vol.072 Test Page</H1>");
      out.println("This page is the output of TestServlet.");
      out.println("</BODY>");
      out.println("</HTML>");
   }

}
--------------------------------------------------------

編集が終わったら、保管(Ctrl + S)しておいてください。ソース・
コードの解説は次回行います。でも、たぶん解説しなくても、大体
何をやっているのかわかりますね。このプログラムは簡単なWebページ
を出力している(WebページはWebブラウザーに送られる)だけですね。


続いて、このサーブレットを「デプロイ」します。
「デプロイ(deploy)」とは、元々は軍事用語で、軍隊や兵器を戦地に配備
もしくは展開することを意味します。この用語がソフトウエアの世界でも
使われるようになり、Webアプリケーションにおいては、そのアプリケー
ションに関する各ファイルを適切な場所に置いて、起動可能な状態にする
ことを意味します。なお、デプロイ(deploy)は動詞で、名詞はデプロイメ
ント(deployment)です。ただし、日本語ではデプロイも名詞的に使ったり
しますが。


┌───────────────────────────┐
  4. サーブレットのデプロイ(deployment)
└───────────────────────────┘

EclipseでTomcatを起動し、Webアプリケーションを実行するのであれば、
上記の開発作業をするだけで、すでにWebアプリケーション(ここでは
サーブレット)のファイルは適切な場所に保管されています。
(本番用のTomcat環境にデプロイする方法については、後ほど説明します。)

あと残っている作業は、このサーブレットの名前、場所、URLの指定方法を
Tomcatに認識させることです。
そのためには、「Web Application Deployment Descriptor」(Webアプリ
ケーション・デプロイメント記述子)と呼ばれる情報を記述します。
Web Application Deployment Descriptorの実体は、web.xmlというファイル
です。
これは、拡張子を見ればわかるようにXML(EXtensible Markup Languageの
略)という言語で書かれたファイルです。XMLについては後ほど詳しく説明
することにして、ここではとりあえず今回の目的に応じたweb.xmlを作成し
ておきましょう。

┌補足─────────────────────────┐
自力でweb.xmlについて調べたい人は、まず概略については
C:\Tomcat6.0\webapps\docs\appdev\deployment.html
または
http://tomcat.apache.org/tomcat-6.0-doc/appdev/deployment.html
を参照し、詳細は
http://jcp.org/aboutJava/communityprocess/final/jsr154/index.html
からSpecificationをダウンロードして参照してください。
また、Tomcatをインストールしたフォルダーのうち
C:\Tomcat6.0\webapps\examples\WEB-INFフォルダーにweb.xmlのサンプル
が入っていますので、参考にしてください。

ちなみに、Tomcatのドキュメントは、Tomcatをインストールしたフォルダー
の中の
C:\Tomcat6.0\webapps\docs\index.html
から参照することができます。
└───────────────────────────┘

では、以下のようにしてweb.xmlを作成しましょう。

(1)パッケージ・エクスプローラー内でJStudy2の中のWEB-INFを右クリック
(WEB-INF/srcではなくWEB-INFを右クリックします。間違えないように注意
してください)し、「新規」→「ファイル」を選択します。

(2)「ファイル名」に
web.xml
を入力し、「終了」ボタンをクリックします。

(3)web.xmlのエディターが開きますので、次のようにソース・コードを
編集してみてください。

--------------------------------------------------------
<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   version="2.5">

   <servlet>
      <servlet-name>TestServlet</servlet-name>
      <servlet-class>jp.co.flsi.lecture.servlet.TestServlet</servlet-class>
   </servlet>

   <servlet-mapping>
      <servlet-name>TestServlet</servlet-name>
      <url-pattern>/servlet/test</url-pattern>
   </servlet-mapping>

</web-app>
--------------------------------------------------------

この内容についても次回解説いたします。

編集が終わったら保管しておいてください。


では、サーブレットがちゃんと動くかテストしてみましょう。

┌───────────────────────────┐
  5. サーブレットのテスト実行
└───────────────────────────┘

(1)EclipseでTomcatを起動してください。(メニュー・バーの
「Tomcat」→「Tomcat起動」)
(もし、すでに起動済みの場合は、「Tomcat」→「Tomcat再起動」
で再起動する。)

(2)Webブラウザー(Internet Explorer)を起動し、以下のURLを
入力することによって、TomcatにTestServletを実行させます。

http://localhost:8080/JStudy2/servlet/test


Webブラウザーに

vol.072 Test Page
This page is the output of TestServlet

という文字列が表示されたら、テストOKです。サーブレットは正常
に動いています。



では、今度は上記のサーブレットと同じ出力をJSPにやらせてみま
しょう。

┌───────────────────────────┐
  6. JSPのテスト
└───────────────────────────┘

(1)パッケージ・エクスプローラー内でJStudy2を右クリックし、
「新規」→「ファイル」を選択します。

(2)「ファイル名」に
test.jsp
と入力し、「終了」ボタンをクリックしましょう。

(3)test.jspのエディターが開きますので、次のようにソース・コード
を編集してみてください。

--------------------------------------------------------
<HTML>
<HEAD>
<TITLE>Servlet Test Page</TITLE>
</HEAD>
<BODY bgcolor="#77ffff" text="#fa5a00">
<H1>vol.072 Test Page</H1>
This page is the output of test.jsp.
</BODY>
</HTML>
--------------------------------------------------------

編集が終わったら、保管しておいてください。

ところで、このソース・コードは、たんなるHTMLのコードに
すぎないですね。
本来のJSPならば、間にJavaのコードが入るものなのですが、
ここでは簡単のためにHTMLのコードだけにしています。
HTMLのコードだけならば、本来はJSPにする意味はありませんが、
今回はこれをJSPの動作確認に利用します。

というわけで、Webブラウザーに次のURLを入力してみてください。

http://localhost:8080/JStudy2/test.jsp

さきほどのTestServletと同じようなWebページが表示されていれば、
JSPはちゃんと作動しています。
ただし、さきほどのTestServletのときのページがそのまま残っている
ものと誤解されるといけないので、出力内容の一部を変えてあること
には、お気づきですね。まだ気がついていない人は、よく見直して
ください。



さて、Tomcatは(標準の設定では)URLにtest.jspのような、拡張子が
jspになっているファイルが指定されると、そのファイルをJSPと判断
してサーブレットへ変換し、そのサーブレットの起動を行います。
詳しいことは、後ほどまた説明しますので、今は何のことかわからなく
てもかまいませんが、とにかく拡張子がjspのファイルは、普通のHTMLの
ファイルとは違う扱いになるということを頭に入れておいてください。



今回はここまでにします。
何か、わからないところがありましたら、下記のWebページまで質問を
お寄せください。


(続く)



========================================================
◆ 02.Java(文法等)解説 [JavaBeans (7)]
========================================================

[JavaBeans (7) イベント<4>]


(4) イベント・ソースの定義

LuckyNumberCheckerという名前で以下のようなクラスを作成してみて
ください。
--------------------------------------------------------

import java.util.Vector;

public class LuckyNumberChecker {
  
   private Vector listeners = new Vector();
   int [] luckyNumbers;
  
   public synchronized void addBingoListener(BingoListener l) {
      listeners.addElement(l);
   }
  
   public synchronized void removeBingoListener(BingoListener l) {
      listeners.removeElement(l);
   }
  
   protected void notifyBingoEvent(int luckyNumber) {
      Vector listeners;
      BingoEvent e = new BingoEvent(this, luckyNumber);
     
      synchronized (this) {
         listeners = (Vector) this.listeners.clone();
      }
     
      for (int i = 0; i < listeners.size(); i++) {
         BingoListener bl = (BingoListener)listeners.elementAt(i);
         bl.hit(e);
      }
   }
  
   public LuckyNumberChecker(int [] luckyNumbers)  {
      this.luckyNumbers = luckyNumbers;
   }

   public void checkNumber(int number) {
      for (int num : luckyNumbers) {
         if (num == number) notifyBingoEvent(num);
      }
   }
}
--------------------------------------------------------
このクラスでは、checkNumber()というメソッドを呼び出すと、
引数に指定された数値と同じものがluckyNumbers配列の中にあるか
どうかが確認され、あればnotifyBingoEvent()メソッドを呼び出す
ようにしています。
notifyBingoEvent()メソッドはBingoEventイベント・オブジェクト
を通知するためのメソッドで、その仕組みは、このLuckyNumberChecker
のインスタンスに(addBingoListener()メソッドの呼び出しに
よって)登録されているリスナーのhit()メソッドを呼び出すこと
です。
BingoEventイベント・オブジェクトはhit()メソッドの引数として
リスナーに渡されます。

なお、上記ソース・コードの中で使われているsynchronizedという
キーワードについては後ほど詳しく説明しますが、ここでは、この
クラスがマルチ・スレッド環境で使われても安全なようにするため
の手続きである、という程度に頭に入れておいてください。
(clone()メソッドの使用についても同様です。)


(5) イベント・ソースとリスナーを使ったプログラムの完成

LuckyNumberFrameという名前で以下のようなクラスを作成してみて
ください。
--------------------------------------------------------
import java.awt.Button;
import java.awt.Frame;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class LuckyNumberFrame extends Frame {
  
   private LuckyNumberChecker checker = new LuckyNumberChecker(new int [] {7, 77, 777});
   private BingoObserver observer = new BingoObserver();
   private LuckyEventListener eventListener = new LuckyEventListener();
   private LuckyActionListener actionListener = new LuckyActionListener();
   private Button instanceButton = new Button();
   private TextField textFieldNumber = new TextField();
  
   class LuckyEventListener implements WindowListener {
      public void windowActivated(WindowEvent e) {};
      public void windowClosed(WindowEvent e) {
         checker.removeBingoListener(observer);
         System.exit(0);
      };
      public void windowClosing(WindowEvent e) {
         Frame frame = (Frame)e.getSource();
         frame.setVisible(false);
         frame.dispose();
      };
      public void windowDeactivated(WindowEvent e) {};
      public void windowDeiconified(WindowEvent e) {};
      public void windowIconified(WindowEvent e) {};
      public void windowOpened(WindowEvent e) {};
   };
  
   class LuckyActionListener implements ActionListener {
      public void actionPerformed(ActionEvent e) {
         Button button = (Button)e.getSource();
         LuckyNumberFrame window = (LuckyNumberFrame)button.getParent();
         int n = Integer.parseInt(window.getTextFieldNumber().getText());
         checker.checkNumber(n);
      };
   };
  
   public LuckyNumberFrame()  {
      super();
      setTitle("ラッキー・ナンバー当てゲーム");
      setSize(400, 150);
      setLayout(null);
      getTextFieldNumber().setBounds(180, 60, 40, 20);
      instanceButton.setBounds(50,90, 300, 20);
      add(getTextFieldNumber());
      add(instanceButton);
      instanceButton.setLabel("上に数字を入れてここをクリック");
      instanceButton.addActionListener(actionListener);
      addWindowListener(eventListener);
      checker.addBingoListener(observer);
      setVisible(true);
   }

   public TextField getTextFieldNumber() {
      return textFieldNumber;
   }

   public static void main(String[] args) {
      LuckyNumberFrame frame = new LuckyNumberFrame();
   }

}
--------------------------------------------------------
このクラスは、BingoEventのイベント・ソースであるLuckyNumberCheckerと、
BingoEventのリスナーであるBingoObserver(前回作成)を使って、
画面上に入力した数字が7か77か777のときに、標準出力(コンソール)に

大当たり!
ラッキー・ナンバーはnでした。

という文字列を表示するアプリケーションです。
(ただし、nは7か77か777の数字)


以上の編集&保管が終わったら、LuckyNumberFrameを実行してテスト
してみてください。



(続く)



================================================
◆ 03.演習問題
================================================

独自のイベントを作って使用するための、上記のソース・コード例
(前回提示したソース・コード例も含める)を参考にして、自分なり
に別の独自イベントを定義し、それを使用するアプリケーションを
作ってみてください。



(続く)



┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
★ホームページ:
      http://www.flsi.co.jp/Java_text/
★このメールマガジンは
     「まぐまぐ(http://www.mag2.com)」
 を利用して発行しています。
★バックナンバーは
      http://www.flsi.co.jp/Java_text/
 にあります。
★このメールマガジンの登録/解除は下記Webページでできます。
      http://www.mag2.com/m/0000193915.html
★このメールマガジンへの質問は下記Webページにて受け付けて
 います。わからない所がありましたら、どしどしと質問をお寄
 せください。
      http://www.flsi.co.jp/Java_text/
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Copyright (C) 2007 Future Lifestyle Inc. 不許無断複製