■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                      2009年04月05日

    Java総合講座 - 初心者から達人へのパスポート
                  vol.147

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


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


========================================================
◆ 01.SOAPのアプリケーション(Webサービス)
========================================================


では、だいたいお膳立てがそろったので、

(H_1) ホテルの空き部屋の検索:
(H_2) ホテルの客室の予約:

の実装に入っていきましょう。

まず最初に、データベースにアクセスするためのクラス群から作っていくこと
にしましょう。
例によって、テーブルに依存しない共通部分はDbManagerというクラス名で作り、
テーブルに依存するクラス群のスーパークラスにすることにします。


では、Eclipseを起動して、JStudySOAPプロジェクト内(ソース・フォルダーは
JStudySOAP/src)に

jp.co.flsi.lecture.webservice.hotel.db

というパッケージを作成してください。

そして、そのパッケージの中にHotelDbExceptionというクラス名で下記のような
内容のクラスを作成してください。これは見ての通り、例外(Exception)クラスの
サブクラスです。つまり、例外クラスの一種です。

--------------------------------------------------------
package jp.co.flsi.lecture.webservice.hotel.db;

public class HotelDbException extends Exception {

   public HotelDbException() {
   }

   public HotelDbException(String message) {
      super(message);
   }

   public HotelDbException(Throwable cause) {
      super(cause);
   }

   public HotelDbException(String message, Throwable cause) {
      super(message, cause);
   }

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

これは、今回のアプリケーション専用の例外クラスであることを明確にするために
作成するものです。
以前のようにthrow new Exception("...")などとExceptionをthrowするのではなく、
このように特別に用意した例外をプログラムの中でthrowすると、自分達が用意した
例外であることが明確になり、あとでデバッグなどを行うときに楽になるということ
が、あとで分かります。


続いて、同じパッケージの中にDbManagerというクラス名で下記のような
内容のクラスを作成してください。

--------------------------------------------------------
package jp.co.flsi.lecture.webservice.hotel.db;

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

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.log4j.Logger;

public class DbManager {
   protected static Connection conn = null;
   private static Logger logger = Logger.getLogger(DbManager.class);

   public static void connect() throws HotelDbException {
      logger.info("Start ...............");
      try{
         if (conn != null) {
            Context initCtx = new InitialContext();
            if(initCtx == null) throw new HotelDbException("Error: InitialContext could not be generated!");
            DataSource ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/HOTELDB");
            if (ds != null) {
               conn = ds.getConnection();
               if(conn == null) throw new HotelDbException("Error: Connection does not exist!");
               else logger.info("Connection has been gotten.");
            }
            else {
               throw new HotelDbException("Error: DataSource does not exist!");
            }
         }
      } catch (NamingException e) {
         logger.error(e);
         throw new HotelDbException("Error: Connect() failed!", e);
      } catch (SQLException e) {
         logger.error(e);
         throw new HotelDbException("Error: Connect() failed!", e);
      } catch (HotelDbException e) {
         logger.error(e);
         throw new HotelDbException("Error: Connect() failed!", e);
      }
      finally {
         logger.info("End ...............");
      }
   }

   public static void disconnect() {
      logger.info("Start ...............");
      try {
         conn.close();
      } catch(SQLException e) {
         logger.error(e);
      }
      finally {
         logger.info("End ...............");
      }
   }

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

上記の内、各種例外をcatchしたときに、いったんログに書き出した後で、その例外を
HotelDbExceptionに作り変えてthrowしているところ、つまり

throw new HotelDbException("Error: Connect() failed!", e);

としているところに注意してください。何のためにこうしているのかは、またあとで
説明します。
それ以外のソース・コードの内容は、特に説明しなくても分かることと思います。


続いて、同じパッケージの中にRoomInfoDbManagerというクラス名で下記のような
内容のクラスを作成してください。これは、データベースの内、ROOMINFOテーブル
に依存するクラスです。

--------------------------------------------------------
package jp.co.flsi.lecture.webservice.hotel.db;

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

import org.apache.log4j.Logger;

import jp.co.flsi.lecture.webservice.hotel.RoomInfo;

public class RoomInfoDbManager extends DbManager {
   private static final String selectAllSql = "SELECT * FROM ROOMINFO";
   private static final String selectCapaSql = "SELECT * FROM ROOMINFO WHERE CAPACITY > ?";
   private static final String selectCapaAndMinRateSql = "SELECT * FROM ROOMINFO WHERE CAPACITY > ? AND RATE > ?";
   private static final String selectCapaAndRateSql = "SELECT * FROM ROOMINFO WHERE CAPACITY > ? AND RATE > ? AND RATE < ?";
   private static Logger logger = Logger.getLogger(RoomInfoDbManager.class);

   public static Vector<RoomInfo> getAllData() throws HotelDbException {
      Vector<RoomInfo> roomInfoList = new Vector<RoomInfo>();
      logger.info("Start ...............");
      try {
         Statement selectSql = conn.createStatement();
         ResultSet rs = selectSql.executeQuery(selectAllSql);
         while (rs.next()) {
            RoomInfo roomInfo = new RoomInfo();
            roomInfo.setRoomNum(rs.getInt("ROOMNUM"));
            logger.info("ROOMNUM = " + rs.getInt("ROOMNUM"));
            roomInfo.setCapacity(rs.getInt("CAPACITY"));
            roomInfo.setRatePerNight(rs.getInt("RATE"));
            roomInfo.setRoomType(rs.getString("TYPE"));
            if ("Y".equals(rs.getString("WEB"))) {
               roomInfo.setWebBrowsable(true);
            }
            else {
               roomInfo.setWebBrowsable(false);
            }
            roomInfoList.add(roomInfo);
         }
         selectSql.close();
      }
      catch (SQLException e) {
         logger.error(e);
         throw new HotelDbException("Error: getAllData() failed!", e);
      }
      finally {
         logger.info("End ...............");
      }
      return roomInfoList;
   }

   public static Vector<RoomInfo> getData(int capacity, int minRate, int maxRate) throws HotelDbException {
      Vector<RoomInfo> roomInfoList = new Vector<RoomInfo>();
      logger.info("Start ...............");
      try {
         PreparedStatement selectPs = null;
         ResultSet rs;
         if (maxRate > -1) {
            selectPs = conn.prepareStatement(selectCapaAndRateSql);
            selectPs.setInt(1, capacity);
            selectPs.setInt(2, minRate);
            selectPs.setInt(3, maxRate);
         }
         else if (minRate > -1) {
            selectPs = conn.prepareStatement(selectCapaAndMinRateSql);
            selectPs.setInt(1, capacity);
            selectPs.setInt(2, minRate);
         }
         else {
            selectPs = conn.prepareStatement(selectCapaSql);
            selectPs.setInt(1, capacity);
         }
         rs = selectPs.executeQuery();
         while (rs.next()) {
            RoomInfo roomInfo = new RoomInfo();
            roomInfo.setRoomNum(rs.getInt("ROOMNUM"));
            logger.info("ROOMNUM = " + rs.getInt("ROOMNUM"));
            roomInfo.setCapacity(rs.getInt("CAPACITY"));
            roomInfo.setRatePerNight(rs.getInt("RATE"));
            roomInfo.setRoomType(rs.getString("TYPE"));
            if ("Y".equals(rs.getString("WEB"))) {
               roomInfo.setWebBrowsable(true);
            }
            else {
               roomInfo.setWebBrowsable(false);
            }
            roomInfoList.add(roomInfo);
         }
         selectPs.close();
      }
      catch (SQLException e) {
         logger.error(e);
         throw new HotelDbException("Error: getData() failed!", e);
      }
      finally {
         logger.info("End ...............");
      }
      return roomInfoList;
   }

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



(次回に続く)


では、今日はここまでにします。



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