■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                      2007年12月30日

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

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


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


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


今回は、サーブレットとBeanとRDBMS(MySQL)とJSPを連携させる方法
を説明するためのサンプルとして、顧客のリストをWebブラウザーに
表示するアプリケーションを作ってみましょう。


Eclipseを起動し、Javaのパースペクティブを開いてください。

まず最初に、Customerクラスを作成しましょう。
これは、顧客を表現するクラスですが、CUSTOMERテーブルとの間に
対応付け(マッピング(vol.038参照))するものです。
すなわち、CUSTOMERテーブルとCustomerクラスの間には一対一の
対応付けがあり、CUSTOMERテーブルの一つのレコードがCustomerクラス
の一つのインスタンスに対応付けられます。

ではまず、クラスを入れるパッケージを作っておきましょう。

(1) パッケージ・エクスプローラーの中のJStudy2(プロジェクト)の
中のWEB-INF/src(フォルダー)を右クリックし、「新規」→「パッケージ」
を選択します。

(2) 「ソース・フォルダー」欄に
JStudy2/WEB-INF/src
がはいっていることを確認し、「名前」欄に
jp.co.flsi.lecture.webapp.entity
と入力し、「終了」ボタンをクリックします。

続いて、このパッケージの中にCustomerクラスを作りましょう。
なお、これから作るクラスはすべてBeanの条件を満たしています。
つまり、Beanでありますからして、サーブレットやJSPで呼び出して
使うことができるのであります。はい。

(1) パッケージ・エクスプローラーの中のjp.co.flsi.lecture.webapp.entity
(先ほど作成したパッケージ)を右クリックし、「新規」→「クラス」
を選択します。

(2) 「ソース・フォルダー」欄に
JStudy2/WEB-INF/src
がはいっていることを確認し、「パッケージ」欄に
jp.co.flsi.lecture.webapp.entity
がはいっていることを確認し、「名前」欄に
Customer
と入力して「終了」ボタンをクリックします。

Customer.javaのエディターが開いたら、下記のように編集しま
しょう。

--------------------------------------------------------
package jp.co.flsi.lecture.webapp.entity;

public class Customer {
   private String num;
   private String name;
   private String zipCode;
   private String address;

   public void setNum(String num) {
      this.num = num;
   }

   public String getNum() {
      return num;
   }

   public void setName(String name) {
      this.name = name;
   }

   public String getName() {
      return name;
   }

   public void setZipCode(String zipCode) {
      this.zipCode = zipCode;
   }

   public String getZipCode() {
      return zipCode;
   }

   public void setAddress(String address) {
      this.address = address;
   }

   public String getAddress() {
      return address;
   }
}
--------------------------------------------------------

(以後、毎度同じことなのでいちいち書きませんけど、編集が
終わったら、適時、保管を行っておいてください。)


続いて、データベースにアクセスするためのクラスを作成しておき
ましょう。
こちらはjp.co.flsi.lecture.webapp.dbというパッケージに入れる
ことにし、パッケージを作成しておきましょう。

(1) パッケージ・エクスプローラーの中のJStudy2(プロジェクト)の中
のWEB-INF/src(フォルダー)を右クリックし、「新規」→「パッケージ」
を選択します。

(2) 「ソース・フォルダー」欄に
JStudy2/WEB-INF/src
がはいっていることを確認し、「名前」欄に
jp.co.flsi.lecture.webapp.db
と入力し、「終了」ボタンをクリックします。

続いて、このパッケージの中にデータベースに接続するためのクラス
を作りましょう。

(1) パッケージ・エクスプローラーの中のjp.co.flsi.lecture.webapp.db
(先ほど作成したパッケージ)を右クリックし、「新規」→「クラス」
を選択します。

(2) 「ソース・フォルダー」欄に
JStudy2/WEB-INF/src
がはいっていることを確認し、「パッケージ」欄に
jp.co.flsi.lecture.webapp.db
がはいっていることを確認し、「名前」欄に
DbManager
と入力して「終了」ボタンをクリックします。

DbManager.javaのエディターが開いたら、下記のように編集しましょう。

--------------------------------------------------------
package jp.co.flsi.lecture.webapp.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DbManager {
   protected static Connection conn = null;
   protected String driver = "com.mysql.jdbc.Driver";
   protected String url = "jdbc:mysql://127.0.0.1:3306/INTSHOP";
   protected String dbUser = "root";
   protected String dbPassword = "rootpass";

   protected void connect() throws java.sql.SQLException {
      try {
         if(conn == null || conn.isClosed()) {
            Class.forName(driver);
            conn = DriverManager.getConnection(url, dbUser, dbPassword);
            conn.setAutoCommit(false);
         }
      } catch(ClassNotFoundException ex) {
         ex.printStackTrace();
      }
   }

   protected void disconnect() {
      try {
         conn.close();
      } catch(SQLException ex) {
         ex.printStackTrace();
      }
   }

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


今度は、CUSTOMERテーブルからデータを読み取るためのクラスを
作りましょう。

(1) パッケージ・エクスプローラーの中のjp.co.flsi.lecture.webapp.db
(先ほど作成したパッケージ)を右クリックし、「新規」→「クラス」
を選択します。

(2) 「ソース・フォルダー」欄に
JStudy2/WEB-INF/src
がはいっていることを確認し、「パッケージ」欄に
jp.co.flsi.lecture.webapp.db
がはいっていることを確認し、「名前」欄に
CustomerDbManager
と入力します。
また、「スーパークラス」には先ほど作成した
DbManager
を指定し、「終了」ボタンをクリックします。

CustomerDbManager.javaのエディターが開いたら、下記のように
編集しましょう。

--------------------------------------------------------
package jp.co.flsi.lecture.webapp.db;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;

import jp.co.flsi.lecture.webapp.entity.Customer;

public class CustomerDbManager extends DbManager {
   private Vector<Customer> customerList = new Vector<Customer>();

   public Vector<Customer> getCustomerList() {
      return customerList;
   }

   public void selectAllData() {
      try {
         connect();
         Statement selectSql = conn.createStatement();
         ResultSet rs = selectSql.executeQuery("SELECT * FROM CUSTOMER");
         while (rs.next()) {
            Customer aCustomer = new Customer();
            aCustomer.setNum(rs.getString("NUM"));
            aCustomer.setName(rs.getString("NAME"));
            aCustomer.setZipCode(rs.getString("ZIPCODE"));
            aCustomer.setAddress(rs.getString("ADDRESS"));
            getCustomerList().addElement(aCustomer);
         }
         selectSql.close();
         disconnect();
      }
      catch (SQLException exception) {
         exception.printStackTrace();
      }
   }

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


これらのソース・コードも解説は不要ですね。
もし、これらのソース・コードが理解できない場合は、vol.037〜vol.039
あたりを復習してください。

なお、これらのクラスではSQLExceptionなどのエラーの記録を
printStackTrace()メソッドで書かせていますが、もっと好ましい
記録方法があります。しかし、それをここで説明すると話が煩雑に
なってしまうので、後述いたします。

また、最近のWebアプリケーションは、上記のクラスとは異なり、
DriverManagerを使わない別の方法でデータベースに接続します。
その理由と、別の接続方法についても後ほど詳しく説明いたします。



では今度は、これらのクラスを使って取り出した顧客の情報をWebページ
として返すためのJSPを作成しましょう。

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

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

customerList.jspのエディターが開いたら、下記のように編集
しましょう。

--------------------------------------------------------
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="Shift_JIS" %>

<HTML>
<HEAD>
<TITLE>顧客リスト</TITLE>
</HEAD>
<BODY bgcolor="#77ffff" text="#fa5a00">
<H1>顧客のリスト</H1>
<TABLE border="1" width="100%">
  <TBODY>
    <TR>
      <TH>顧客番号</TH>
      <TH>氏名</TH>
      <TH>郵便番号</TH>
      <TH>住所</TH>
    </TR>

<%@ page import="java.util.Vector" %>
<%@ page import="jp.co.flsi.lecture.webapp.entity.*" %>
<jsp:useBean class="jp.co.flsi.lecture.webapp.db.CustomerDbManager" id="CUSTOMERDB" scope="request" />
<%      Customer  aCustomer;
       Vector<Customer> customerList = CUSTOMERDB.getCustomerList();
      for (int i = 0; i < customerList.size(); i++) {
         aCustomer = customerList.elementAt(i); %>
          <TR>
            <TD><%= aCustomer.getNum() %></TD>
            <TD><%= aCustomer.getName() %></TD>
            <TD><%= aCustomer.getZipCode() %></TD>
            <TD><%= aCustomer.getAddress() %></TD>
          </TR>
<%      } %>

  </TBODY>
</TABLE>

</BODY>
</HTML>
--------------------------------------------------------

このソース・コードの解説は次回行います。



では、これらのJavaのクラス(Bean)やJSPを呼び出して業務
(顧客リストの表示)を行うための処理の流れを制御するサーブ
レットを作りましょう。

(1) パッケージ・エクスプローラーの中のJStudy2(プロジェクト)の中の
WEB-INF/src(フォルダー)の中のjp.co.flsi.lecture.webapp.servlet
(パッケージ)を右クリックし、「新規」→「クラス」を選択します。

(2) 「ソース・フォルダー」欄に
JStudy2/WEB-INF/src
がはいっていることを確認し、「パッケージ」欄に
jp.co.flsi.lecture.webapp.servlet
がはいっていることを確認し、「名前」欄に
CustomerServlet
と入力します。
また、「スーパークラス」には
javax.servlet.http.HttpServlet
を指定し、「終了」ボタンをクリックします。

CustomerServlet.javaのエディターが開いたら、下記のように編集
しましょう。

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

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jp.co.flsi.lecture.webapp.db.CustomerDbManager;

public class CustomerServlet extends HttpServlet {
   public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
      CustomerDbManager customerDb = new CustomerDbManager();
      customerDb.selectAllData();
      req.setAttribute("CUSTOMERDB",customerDb);
      getServletContext().getRequestDispatcher("/customerList.jsp").forward(req,res);
   }

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

このサーブレットでは、CustomerDbManagerのインスタンスにデータ
ベース(CUSTOMERテーブル)を全件検索させていますね。検索の結果
はVectorの入れ物に入れた形でインスタンスに保持されますから、
インスタンスごとcustomerList.jspに渡しています。そうすると、
あとはcustomerList.jspがそのインスタンスからデータを取り出して
WebページとしてWebブラウザーに顧客情報のリストを返してくれます。
このサーブレットのソース・コードは、これまでに作成したサーブレッ
トを理解できていれば容易に理解できる内容なので、解説は省略させて
いただきます。


このサーブレットは新規に作られたものですから、Web Application
Deployment Descriptor(Webアプリケーション・デプロイメント記述子
 = web.xml)に登録しておきましょう。
パッケージ・エクスプローラーの中のJStudy2(プロジェクト)の中
のWEB-INF(WEB-INF/srcではなくWEB-INF)の中の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.flsi.lecture.servlet.TestServlet</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>TestServlet2</servlet-name>
        <servlet-class>jp.flsi.lecture.servlet.TestServlet2</servlet-class>
    </servlet>

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

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

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

    <servlet-mapping>
        <servlet-name>TestServlet2</servlet-name>
        <url-pattern>/servlet/test2</url-pattern>
    </servlet-mapping>
   
    <servlet-mapping>
        <servlet-name>AgeCalcServlet</servlet-name>
        <url-pattern>/servlet/age</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>CustomerServlet</servlet-name>
        <url-pattern>/servlet/customers</url-pattern>
    </servlet-mapping>
   
</web-app>
--------------------------------------------------------

CustomerServletについての記述が追加されたわけですが、
どこが追加された部分か説明しなくてもわかりますね。


ところで、単独でJVMで実行されるアプリケーションとは異なり、
Tomcatのアプリケーションがデータベースにアクセスするためには、
Tomcatが認識できる場所にJDBCドライバーのJARファイルを置いて
おかなければなりません。
これはTomcatのクラス・ローダーによって参照される場所(要するに
クラスパスに追加される場所)ですが、アプリケーション別にしたい
場合と、すべてのアプリケーションで共通に使いたい場合で、場所が
異なります。
ここでは、すべてのアプリケーションでMySQLのJDBCドライバーを
使えるようにすることとし、後者の場所にMySQLのJDBCドライバーの
JARファイルをコピーすることにしましょう。

では、先日
C:\MySQL_Driver
にコピーした
mysql-connector-java-5.0.8-bin.jar
をTomcatをインストールしたフォルダー下のlibフォルダー、すなわち
C:\Tomcat6.0\lib
にコピーしてください。

(ちなみに、アプリケーション別にしたい場合は、WEB-INF下のlibに
コピーします。)

なお、Tomcatの各フォルダー(ディレクトリー)の役割については、
のちほどデプロイを行うときにいっしょに説明いたしますので、
ここではlibフォルダーはJARファイルを入れる場所だという程度に
頭に入れておいてください。


では、Tomcatを起動してテストしてみましょう。

(1) メニュー・バーの「Tomcat」→「Tomcat起動」を選択します。

(2) いつものことですが、コンソールに
情報: Server startup in xxxx ms
が表示されれば起動完了ですね。(ただしxxxxは数字です。)

(3) Webブラウザーを起動して、下記のURLを入力してください。

http://localhost:8080/JStudy2/servlet/customers


はい。ちゃんとCUSTOMERテーブルのデータがリストされましたね。



では、今回はここまでにしましょう。


(次回に続く)


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



┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
★ホームページ:
      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. 不許無断複製