広告

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                      2011年02月21日

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

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


-------------------------------------------------------
・現在、このメールマガジンは以下の2部構成になっています。
[1] 当初からのコース:vol.xxx(xxxは番号)が振られています。
   これは現在、中級レベルになっています。
[2] 2009年11月開講コース:xxx号(xxxは番号)が振られています。
   これは現在、初心者向けのレベルになっています。
・このメールマガジンは、画面を最大化して見てください。
小さな画面で見ていると、不適切な位置で行が切れてしまう
など、問題を起すことがあります。
・このメールマガジンに掲載されているソース・コード及び
文章は特に断らない限り、すべて筆者が著作権を所有してい
ます。また、これらのソース・コードは学習用のためだけに
提供しているものです。
-------------------------------------------------------


========================================================
◆ 01.Strutsのアプリケーション開発(プロジェクト:StrutsShop)
        --- Tiles ---
========================================================

前回作成した雛型のアプリケーションでは支払い方法や支払い状況、配達状況
に数字やtrue/falseなどのわかりずらい値を表示していましたので、これらを
文字列を表示するように変えましょう。

すなわち、支払い方法については0は「クレジットカード」、1は「銀行振込」、
支払い状況についてはfalseは「未払い」、trueは「支払い済み」、
配達状況については0は「未配達」、1は「配達済み」、2は「配達中」
と表示するようにしましょう。

(これらの他に、「顧客番号だけが表示されていて顧客の氏名や住所などの詳細
な項目が表示されていない」などの不十分さもありますが、これは支払い方法の
文字列の表示の仕方がわかれば対処法がわかることなので割愛します。)

なお、これらの文字列は本来はデータベースに登録しておいて、データベースから
取り出して表示するようにすべきです。

なぜならば、こういった値は今後変更される可能性もあるし(例えば、支払い方法
に「デビットカード」などの別の手段が追加されるなど)、そうでなくても、こう
いったデータは(データベースなどに)一元化させることが望ましいからです。
(もし、個々のJSPファイルなどに直接文字列を書き込んでいると、複数のファイル
に重複して同じ文字列を書き込むことになり、書き間違いなどのミスを犯す確率が
大きくなるし、作業量が増えて生産性も落ちます。)

┌補足─────────────────────────┐
 支払い状況は「未払い」か「支払い済み」かのどちらかしか
 ないと思うかもしれませんが、実際には「頭金のみ支払い済み」
 とか「分割払いのうち1回目が支払い済み」といったさまざま
 な状況を今後追加することがあるかも知れません。
 また、配達状況についても、今後は在庫が無くても受注して
 おいて、「メーカーに手配中」とか「メーカーから直送中」、
 「メーカーから配達済み」とかいった状況を追加する可能性も
 あります。
 今後このような項目の追加があったとしても、そういった項目
 データをデータベースに一元化して管理していれば、データ
 ベースにデータを追加するだけで済み、アプリケーションを
 修正せずに済みます。
└───────────────────────────┘


しかしながら、今回はこれらの文字列のうち「支払い方法」のものだけをデータベース
に持たせ、「支払い状況」についてはBean(クラス)に、「配達状況」についてはJSP
ファイルに直接文字列を書き込むというやり方でやってみます。(さまざまな方法を
学んでおくためです。)



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆

┌───────────────────────────┐
 データベースに文字列を持たせる方法
└───────────────────────────┘

ではまず、「支払い方法」の文字列を登録するテーブルを作りましょう。

その名もずばり、PAYMETHODにします。

では、下記のようなSQLのファイルを作成しましょう。

(1) [テーブル名]:PAYMETHOD
--------------------------------------------------------
create table PAYMETHOD (
NUM decimal(1,0) not null,
NAME varchar(20) not null,
primary key(NUM)
);
--------------------------------------------------------
これは、C:\JavaWorkSpaceフォルダーの中に、
PAYMETHOD.sql
というファイル名で保管しておきましょう。

ちなみに、ORDERHEADERテーブルのPAYMETHODカラム(vol.186参照)は
このPAYMETHODテーブルのNUMカラムに対する外部キー(foreign key)
として設定変更すべきですが、これは読者各自の自由課題とし、ここでは
割愛します。(以前(vol.027などで)お話したようにデータベースに
整合性を管理させる(PAYMETHODテーブルとORDERHEADERテーブルの間に
ちぐはぐが生じないようにする)ためにはORDERHEADERテーブルに上記の
外部キーの設定を行うことが望ましいのですが、話を簡単にするために
今回はその作業は割愛します。)



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆

ではさっそく、上記のテーブルをデータベースに組み込みましょう。
データベースの名前はSTRUSHOPでしたね。
以下のようにMySQLのコマンド・ライン・クライアントを起動して作業を行い
ましょう。

(1) 「スタート」ボタン→「すべてのプログラム」→「MySQL」→
「MySQL Server 5.0」→「MySQL Command Line Client」
を選択します。

(2) rootのパスワードを聞いてきますので

rootpass

を入力しましょう。

(3) 続いて、STRUSHOPデータベースを使用(接続)するために以下の
コマンドを入力します。

use STRUSHOP


(4) 以下のコマンドで(先ほど保管したファイルを使って)テーブルを作成
しましょう。

source C:\JavaWorkSpace\PAYMETHOD.sql

(5) 最後に、MySQLのコマンド・ライン・クライアントを終了しましょう。

quit



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆

では、このテーブルがちゃんと作成されていることをEclipseのDBViewerで
確認しておきましょう。

(1) EclipseでDBViewerパースペクティブを開きます。

(2) 「DBツリー・ビュー」の中のSTRUSHOPを右クリックし、「接続」を
選択します。

(3) STRUSHOP配下のstrushop配下のTABLE配下にpaymethodがあればOKです。


続いて、このPAYMETHODテーブルに次の操作でテスト用のデータを追加しましょう。

(4) 「SQL実行・ビュー」に以下のSQLを入力してください。

--------------------------------------------------------
insert into PAYMETHOD values (0, 'クレジットカード');
/
insert into PAYMETHOD values (1, '銀行振込');
/
--------------------------------------------------------

入力が終わったら、「全てのSQLを実行」ボタン(緑色の右向き矢印
というより三角形のボタン)をクリックしましょう。
(なお、自動コミットになっていることを確認しておいて下さい。
自動コミットになっていなければ、自分でコミットすること。)

(5) STRUSHOP配下のstrushop配下のTABLE配下にpaymethodをダブル・クリック
することによってPAYMETHODテーブルの中身を表示し、正しくデータ(レコード)
が追加されていることを確認して下さい。

(6) 最後に「DBツリー・ビュー」の中のSTRUSHOPを右クリックし、「切断」を
選択します。

(7) Java EEパースペクティブを開きましょう。



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆

これらの作業によって、注文関連のクラスに「支払い方法」の文字列データを
持たせることが可能になりますので、各クラス(OrderとOrderDbManager)を
編集しましょう。

まずjp.co.flsi.lecture.struts.dbパッケージのOrder.javaファイルを
下記のように編集しましょう。

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

import java.io.Serializable;
import java.util.Date;
import java.util.Vector;

public class Order implements Serializable {
   private int orderNumber;
   private Date orderDate;
   private String userType;
   private String userId;
   private int payMethod;
   private boolean payment;
   private short delivery;
   private Vector<OrderItem> orderItems;
   private boolean orderComplete;
   private String payMethodName;

   public Order() {
      setOrderNumber(0);        // 0は未設定を意味するものとする。
      setPayMethod(0);          // デフォルトはクレジット・カード払い
      setPayment(false);        // デフォルトは未払い。
      setDelivery((short)0);    // デフォルトは未配達。
      setOrderComplete(false);  // デフォルトは注文前
      orderItems = new Vector<OrderItem>();
   }

   public void setOrderNumber(int orderNumber) {
      this.orderNumber = orderNumber;
   }

   public int getOrderNumber() {
      return orderNumber;
   }

   public void setOrderDate(Date orderDate) {
      this.orderDate = orderDate;
   }

   public Date getOrderDate() {
      return orderDate;
   }

   public void setUserType(String userType) {
      this.userType = userType;
   }

   public String getUserType() {
      return userType;
   }

   public void setUserId(String userId) {
      this.userId = userId;
   }

   public String getUserId() {
      return userId;
   }

   public void setPayMethod(int payMethod) {
      this.payMethod = payMethod;
   }

   public int getPayMethod() {
      return payMethod;
   }

   public void setPayment(boolean payment) {
      this.payment = payment;
   }

   public boolean isPayment() {
      return payment;
   }

   public void setDelivery(short delivery) {
      this.delivery = delivery;
   }

   public short getDelivery() {
      return delivery;
   }

   public void setOrderItems(Vector<OrderItem> orderItems) {
      this.orderItems = orderItems;
   }

   public Vector<OrderItem> getOrderItems() {
      return orderItems;
   }

   public void addOrderItem(OrderItem anOrderItem) {
      for (int i = 0; i < this.orderItems.size(); i++) {
         if (this.orderItems.get(i).getItemNum().equals(anOrderItem.getItemNum())) {
            int totalQuantity = this.orderItems.get(i).getOrderQuantity() + anOrderItem.getOrderQuantity();
            this.orderItems.get(i).setOrderQuantity(totalQuantity);
            return;
         }
      }
      this.orderItems.add(anOrderItem);
   }

   public void removeOrderItem(OrderItem anOrderItem) {
      for (int i = this.orderItems.size() - 1; i >= 0; i--) {
         if (this.orderItems.get(i).getItemNum().equals(anOrderItem.getItemNum())) {
            this.orderItems.remove(i);
         }
      }
   }

   public void setOrderComplete(boolean orderComplete) {
      this.orderComplete = orderComplete;
   }

   public boolean isOrderComplete() {
      return orderComplete;
   }

   public void setPayMethodName(String payMethodName) {
      this.payMethodName = payMethodName;
   }

   public String getPayMethodName() {
      return payMethodName;
   }

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

つまり、payMethodNameというフィールドを持たせ、そのsetter、getterを
用意しています。



また、jp.co.flsi.lecture.struts.dbパッケージのOrderDbManager.javaファイル
を下記のように編集しましょう。

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

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

import jp.co.flsi.lecture.reflect.ValueLogStringMaker;
import org.apache.log4j.Logger;

public class OrderDbManager extends DbManager  {
   private static Logger logger = Logger.getLogger(OrderDbManager.class);
   private String selectMaxONumSql = "SELECT MAX(O_NUM) FROM ORDERHEADER";
   private String insHeaderSql = "INSERT INTO ORDERHEADER  VALUES (?, ?, ?, ?, ?, ?, ?)";
   private String insItemSql = "INSERT INTO ORDERITEM  VALUES (?, ?, ?, ?)";

   private static final String selectOrderNumberSql = "SELECT * FROM ORDERHEADER, PAYMETHOD WHERE O_NUM = ? AND NUM = PAYMETHOD";
   private static final String selectAllOrdersSql = "SELECT * FROM ORDERHEADER, PAYMETHOD WHERE NUM = PAYMETHOD";


   public boolean insertData(Order anOrder) throws StruShopDbException {
      logger.info("Start ...............");
      ValueLogStringMaker stringMaker = new ValueLogStringMaker();
      logger.info("Method parameter: <<<<<" + stringMaker.getValues("user", anOrder));
      logger.info(">>>>>");
      try {
         conn.setAutoCommit(false);
         Statement selectSt = conn.createStatement();
         PreparedStatement insHeaderPs = conn.prepareStatement(insHeaderSql);
         PreparedStatement insItemPs = conn.prepareStatement(insItemSql);
         ResultSet rs = selectSt.executeQuery(selectMaxONumSql);
         int newOrderNumber = 1;
         if (rs.next()) newOrderNumber = rs.getInt(1) + 1;
         insHeaderPs.setInt(1, newOrderNumber);
         insHeaderPs.setDate(2, new java.sql.Date((new Date()).getTime()));
         insHeaderPs.setString(3, anOrder.getUserType());
         insHeaderPs.setString(4, anOrder.getUserId());
         insHeaderPs.setInt(5, anOrder.getPayMethod());
         if (anOrder.isPayment()) {  // paymentの値がtrueなら
            insHeaderPs.setInt(6, 1);  // 支払い済み
         }
         else { // paymentの値がfalseなら
            insHeaderPs.setInt(6, 0);  // 未払い
         }
         insHeaderPs.setInt(7, 0);  // 未配達
         insHeaderPs.executeUpdate();
         int seqNum = 1;
         for (OrderItem oi : anOrder.getOrderItems()) {
            insItemPs.setInt(1, newOrderNumber);
            insItemPs.setInt(2, seqNum);
            insItemPs.setString(3, oi.getItemNum());
            insItemPs.setInt(4, oi.getOrderQuantity());
            insItemPs.executeUpdate();
            seqNum++;
         }
         selectSt.close();
         insHeaderPs.close();
         insItemPs.close();
         conn.commit();
      }
      catch (SQLException e) {
         try {
            conn.rollback();
            logger.info("Rollback executed.");
         }
         catch (Exception ex) {
            logger.info("Rollback failed.", ex);
         }
         logger.error(e, e);
         throw new StruShopDbException("Error: insertData() failed!", e);
      }
      catch (Throwable e) {
         try {
            conn.rollback();
            logger.info("Rollback executed.");
         }
         catch (Exception ex) {
            logger.info("Rollback failed.", ex);
         }
         logger.error(e, e);
         return false;
      }
      finally {
         logger.info("End ...............");
      }
      logger.info("Method return: <<<<< true");
      logger.info(">>>>>");
      return true;
   }


   public Vector<Order> getDataByNumber(int orderNumber) throws StruShopDbException {
      logger.info("Start ...............");
      ValueLogStringMaker stringMaker = new ValueLogStringMaker();
      logger.info("Method parameter: <<<<<" + stringMaker.getValues("orderNumber", orderNumber));
      logger.info(">>>>>");
      Vector<Order> orderList = new Vector<Order>();
      try {
         PreparedStatement selectPs = null;
         ResultSet rs;
         if (orderNumber == 0) {  // orderNumberが0(未指定)の場合
            selectPs = conn.prepareStatement(selectAllOrdersSql);
         }
         else {
            selectPs = conn.prepareStatement(selectOrderNumberSql);
            selectPs.setInt(1, orderNumber);
         }
         rs = selectPs.executeQuery();
         int payment = 0;
         while (rs.next()) {
            Order order = new Order();
            order.setOrderNumber(rs.getInt("O_NUM"));
            order.setOrderDate(rs.getDate("O_DATE"));
            order.setUserType(rs.getString("U_TYPE"));
            order.setUserId(rs.getString("USERID"));
            order.setPayMethod(rs.getInt("PAYMETHOD"));
            order.setPayMethodName(rs.getString("NAME"));
            payment = rs.getInt("PAYMENT");
            if (payment == 1) {  // 支払い済みの場合
               order.setPayment(true);
            }
            else {  // 未払いの場合
               order.setPayment(false);
            }
            order.setDelivery(rs.getShort("DELIVERY"));

            orderList.add(order);
         }
         selectPs.close();
      }
      catch (SQLException e) {
         logger.error(e, e);
         throw new StruShopDbException("Error: getDataByNumber() failed!", e);
      }
      catch (Throwable e) {
         logger.error(e, e);
      }
      finally {
         logger.info("End ...............");
      }
      logger.info("Method return: <<<<<" + stringMaker.getValues("orderList", orderList));
      logger.info(">>>>>");
      return orderList;
   }

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

変更したのはSQL文
   private static final String selectOrderNumberSql = "SELECT * FROM ORDERHEADER, PAYMETHOD WHERE O_NUM = ? AND NUM = PAYMETHOD";
   private static final String selectAllOrdersSql = "SELECT * FROM ORDERHEADER, PAYMETHOD WHERE NUM = PAYMETHOD";

            payment = rs.getInt("PAYMENT");
の行だけですね。



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆

では、これで「支払い方法」の文字列を表示可能になりましたので、JSPの該当箇所
を編集しましょう。

まず、(StrutsShopプロジェクトのWebContent配下のtiles-parts配下の)orderList.jsp
の中のpayMethodをpayMethodNameに書き換えましょう。すなわち、orderList.jsp
の中身全体としては下記のようになります。

--------------------------------------------------------
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-nested" prefix="nested" %>

注文番号をクリックすると、その注文の詳細ページが開き、支払いや配達の状況の設定/変更ができます。<br>
<table border="1" width="100%">
<tr>
  <th>注文番号</th>
  <th>注文日</th>
  <th>顧客番号</th>
  <th>支払い方法</th>
  <th>支払い状況</th>
  <th>配達状況</th>
</tr>
<logic:iterate id="order" name="orderList" scope="request">
<tr>
   <td>
      <html:link action="/orderdetail" paramId="selectedOrderNumber" paramName="order" paramProperty="orderNumber" >
         <bean:write name="order" property="orderNumber" />
      </html:link>
   </td>
   <td><bean:write name="order" property="orderDate" /></td>
   <td><bean:write name="order" property="userId" /></td>
   <td><bean:write name="order" property="payMethodName" /></td>
   <td><bean:write name="order" property="payment" /></td>
   <td><bean:write name="order" property="delivery" /></td>
</tr>
</logic:iterate>
</table>
--------------------------------------------------------


また、同様にorderDetail.jspファイルの中のpayMethodをpayMethodNameに書き換え
ましょう。すなわち、orderDetail.jspファイルの中身全体としては下記のように
なります。

--------------------------------------------------------
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-nested" prefix="nested" %>

<table border="1" width="100%">
<tr>
  <td>
    <table border="0" width="100%">
    <tr>
      <td align="center">
       <b>注文の詳細</b>
      </td>
    </tr>
    <tr>
      <td>
        <br>
        <center>
          <table>
          <tr>
            <td>注文番号:</td>
            <td><bean:write name="ORDERSET" property="orderNumber"/></td>
          </tr>
          <tr>
            <td>注文日:</td>
            <td><bean:write name="ORDERSET" property="orderDate"/></td>
          </tr>
          <tr>
            <td>顧客番号:</td>
            <td><bean:write name="ORDERSET" property="userId"/></td>
          </tr>
          <tr>
            <td>支払い方法:</td>
            <td><bean:write name="ORDERSET" property="payMethodName"/></td>
          </tr>
          <tr>
            <td>支払い状況:</td>
            <td><bean:write name="ORDERSET" property="payment"/></td>
          </tr>
          <tr>
            <td>配送状況:</td>
            <td><bean:write name="ORDERSET" property="delivery"/></td>
          </tr>
          </table>
        </center>
      </td>
    </tr>
    </table>
  </td>
</tr>
</table>
--------------------------------------------------------



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆

では、今の段階で一度テストをしてみましょう。

(1) 「サーバー」ビューの中の「ローカル・ホストのTomcat v5.5サーバー」を
右クリックし、「開始」を選択します。しばらくして、

ローカル・ホストのTomcat v5.5サーバー[始動済み,同期済み]

というように、後ろに「始動済み」の表示が出たら、Tomcatの起動が完了しています。

(2) Webブラウザー(Internet Explorer)を起動して、URL

http://localhost:8080/StrutsShop/tiles-parts/index.jsp

または、

http://localhost:8080/StrutsShop/tiles-parts/

を入力しましょう。

(3) 注文のリストが表示されますので、その中のどれかの注文番号(たとえば 1)を
クリックしましょう。

注文の詳細のWebページが開きますね。

どうですか、支払い方法が期待通りに「銀行振込」や「クレジットカード」の
文字列になっていますね。



なお、この(データベースに文字列を持たせる)方法だと、「データベース
への追加作業だけでなくアプリケーション側の変更も必要になって面倒では
ないか?」と思うかもしれませんが、アプリケーション側の変更は最初の
一回だけであり、今後(「コンビニでの支払い」が追加されたり、
「お財布携帯による支払い」が追加されたり、「デビットカードによる
支払い」が追加されたりというふうに)時代とともに支払い方法が段々
と追加されていってもデータベースへのレコードの追加だけで済みます。
しかもアプリケーション側の変更はもう必要ありませんので、アプリケー
ションの運用を続行したままデータベースへのレコードの追加を行うこと
ができます。



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆

┌───────────────────────────┐
 Bean(クラス)に文字列を持たせる方法
└───────────────────────────┘

では、続いて「支払い状況」についても文字列表示に変えてみましょう。
今度はBeanに直接文字列を持たせるようにします。
編集するBeanは、やはりOrderクラスです。

では、jp.co.flsi.lecture.struts.dbパッケージのOrder.javaファイルを下記の
ように編集しましょう。

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

import java.io.Serializable;
import java.util.Date;
import java.util.Vector;

public class Order implements Serializable {
   private int orderNumber;
   private Date orderDate;
   private String userType;
   private String userId;
   private int payMethod;
   private boolean payment;
   private short delivery;
   private Vector<OrderItem> orderItems;
   private boolean orderComplete;
   private String payMethodName;
   private String paymentName;

   public Order() {
      setOrderNumber(0);        // 0は未設定を意味するものとする。
      setPayMethod(0);          // デフォルトはクレジット・カード払い
      setPayment(false);        // デフォルトは未払い。
      setDelivery((short)0);    // デフォルトは未配達。
      setOrderComplete(false);  // デフォルトは注文前
      orderItems = new Vector<OrderItem>();
   }

   public void setOrderNumber(int orderNumber) {
      this.orderNumber = orderNumber;
   }

   public int getOrderNumber() {
      return orderNumber;
   }

   public void setOrderDate(Date orderDate) {
      this.orderDate = orderDate;
   }

   public Date getOrderDate() {
      return orderDate;
   }

   public void setUserType(String userType) {
      this.userType = userType;
   }

   public String getUserType() {
      return userType;
   }

   public void setUserId(String userId) {
      this.userId = userId;
   }

   public String getUserId() {
      return userId;
   }

   public void setPayMethod(int payMethod) {
      this.payMethod = payMethod;
   }

   public int getPayMethod() {
      return payMethod;
   }

   public void setPayment(boolean payment) {
      this.payment = payment;
      if (payment) {
         setPaymentName("支払い済み");
      }
      else {
         setPaymentName("未払い");
      }
   }

   public boolean isPayment() {
      return payment;
   }

   public void setDelivery(short delivery) {
      this.delivery = delivery;
   }

   public short getDelivery() {
      return delivery;
   }

   public void setOrderItems(Vector<OrderItem> orderItems) {
      this.orderItems = orderItems;
   }

   public Vector<OrderItem> getOrderItems() {
      return orderItems;
   }

   public void addOrderItem(OrderItem anOrderItem) {
      for (int i = 0; i < this.orderItems.size(); i++) {
         if (this.orderItems.get(i).getItemNum().equals(anOrderItem.getItemNum())) {
            int totalQuantity = this.orderItems.get(i).getOrderQuantity() + anOrderItem.getOrderQuantity();
            this.orderItems.get(i).setOrderQuantity(totalQuantity);
            return;
         }
      }
      this.orderItems.add(anOrderItem);
   }

   public void removeOrderItem(OrderItem anOrderItem) {
      for (int i = this.orderItems.size() - 1; i >= 0; i--) {
         if (this.orderItems.get(i).getItemNum().equals(anOrderItem.getItemNum())) {
            this.orderItems.remove(i);
         }
      }
   }

   public void setOrderComplete(boolean orderComplete) {
      this.orderComplete = orderComplete;
   }

   public boolean isOrderComplete() {
      return orderComplete;
   }

   public void setPayMethodName(String payMethodName) {
      this.payMethodName = payMethodName;
   }

   public String getPayMethodName() {
      return payMethodName;
   }

   private void setPaymentName(String paymentName) {
      this.paymentName = paymentName;
   }

   public String getPaymentName() {
      return paymentName;
   }

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

つまり、paymentNameというフィールドを追加し、そのsetter、getterを
用意していますが、このときsetterすなわちsetPaymentName()というメソッド
をprivate指定にしていることに注意して下さい。
これはpaymentNameフィールドの値を外部からは勝手に変えられないようにし、
代わりに、paymentフィールドの値を変えたらそれに合わせてpaymentNameフィー
ルドの値も自動的に変わるようにするためです。
というわけで、paymentNameフィールドの値はpaymentフィールドのsetter
すなわちsetPayment()メソッドで変えるように編集しています。
つまり、setPayment()メソッドの中に
      if (payment) {
         setPaymentName("支払い済み");
      }
      else {
         setPaymentName("未払い");
      }
というコードを組み込んでいますね。



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆

では、これで「支払い状況」の文字列を表示可能になりましたので、JSPの該当箇所
を編集しましょう。

まず、(StrutsShopプロジェクトのWebContent配下のtiles-parts配下の)orderList.jsp
の中のpaymentをpaymentNameに書き換えましょう。すなわち、orderList.jsp
の中身全体としては下記のようになります。

--------------------------------------------------------
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-nested" prefix="nested" %>

注文番号をクリックすると、その注文の詳細ページが開き、支払いや配達の状況の設定/変更ができます。<br>
<table border="1" width="100%">
<tr>
  <th>注文番号</th>
  <th>注文日</th>
  <th>顧客番号</th>
  <th>支払い方法</th>
  <th>支払い状況</th>
  <th>配達状況</th>
</tr>
<logic:iterate id="order" name="orderList" scope="request">
<tr>
   <td>
      <html:link action="/orderdetail" paramId="selectedOrderNumber" paramName="order" paramProperty="orderNumber" >
         <bean:write name="order" property="orderNumber" />
      </html:link>
   </td>
   <td><bean:write name="order" property="orderDate" /></td>
   <td><bean:write name="order" property="userId" /></td>
   <td><bean:write name="order" property="payMethodName" /></td>
   <td><bean:write name="order" property="paymentName" /></td>
   <td><bean:write name="order" property="delivery" /></td>
</tr>
</logic:iterate>
</table>
--------------------------------------------------------


また、同様にorderDetail.jspファイルの中のpaymentをpaymentNameに書き換え
ましょう。すなわち、orderDetail.jspファイルの中身全体としては下記のように
なります。

--------------------------------------------------------
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-nested" prefix="nested" %>

<table border="1" width="100%">
<tr>
  <td>
    <table border="0" width="100%">
    <tr>
      <td align="center">
       <b>注文の詳細</b>
      </td>
    </tr>
    <tr>
      <td>
        <br>
        <center>
          <table>
          <tr>
            <td>注文番号:</td>
            <td><bean:write name="ORDERSET" property="orderNumber"/></td>
          </tr>
          <tr>
            <td>注文日:</td>
            <td><bean:write name="ORDERSET" property="orderDate"/></td>
          </tr>
          <tr>
            <td>顧客番号:</td>
            <td><bean:write name="ORDERSET" property="userId"/></td>
          </tr>
          <tr>
            <td>支払い方法:</td>
            <td><bean:write name="ORDERSET" property="payMethodName"/></td>
          </tr>
          <tr>
            <td>支払い状況:</td>
            <td><bean:write name="ORDERSET" property="paymentName"/></td>
          </tr>
          <tr>
            <td>配送状況:</td>
            <td><bean:write name="ORDERSET" property="delivery"/></td>
          </tr>
          </table>
        </center>
      </td>
    </tr>
    </table>
  </td>
</tr>
</table>
--------------------------------------------------------



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆

では、今の段階で再度テストをしてみましょう。

(1) 「サーバー」ビューの中の「ローカル・ホストのTomcat v5.5サーバー」を
右クリックし、「開始」を選択します。しばらくして、

ローカル・ホストのTomcat v5.5サーバー[始動済み,同期済み]

というように、後ろに「始動済み」の表示が出たら、Tomcatの起動が完了しています。

(2) Webブラウザー(Internet Explorer)を起動して、URL

http://localhost:8080/StrutsShop/tiles-parts/index.jsp

または、

http://localhost:8080/StrutsShop/tiles-parts/

を入力しましょう。

(3) 注文のリストが表示されますので、その中のどれかの注文番号(たとえば 1)を
クリックしましょう。

注文の詳細のWebページが開きますね。

どうですか、支払い状況が期待通りに「未払い」や「支払い済み」の
文字列になっていますね。



なお、この(Bean(クラス)に文字列を持たせる)方法だと、文字列の情報が
特定のメソッドの中に一元化されているので、今後(たとえば「メーカーに手配中」
とか「メーカーから直送中」、「メーカーから配達済み」といった状況の)
文字列の追加が行われるときにも、変更箇所が一箇所で済み、簡単だと思う
かもしれません。
しかし、これはあくまでアプリケーション側の変更であるために、変更する
たびにアプリケーションの運用を停止してデプロイし直してから運用を再開
するという面倒さが発生します。
また、データベースに一元化するのと違って、文字列データがどこで管理
されているのかわかりにくいという問題もあります。
という訳で、好ましい方法ではありません。



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆

┌───────────────────────────┐
 JSPファイルに直接文字列を持たせる方法
└───────────────────────────┘

では、続いて「配達状況」についても文字列表示に変えてみましょう。
今度は、JSPファイルに直接文字列を書き込むやり方をとります。

ではまず、(StrutsShopプロジェクトのWebContent配下のtiles-parts配下の)orderList.jsp
を下記のように編集しましょう。

--------------------------------------------------------
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-nested" prefix="nested" %>

注文番号をクリックすると、その注文の詳細ページが開き、支払いや配達の状況の設定/変更ができます。<br>
<table border="1" width="100%">
<tr>
  <th>注文番号</th>
  <th>注文日</th>
  <th>顧客番号</th>
  <th>支払い方法</th>
  <th>支払い状況</th>
  <th>配達状況</th>
</tr>
<logic:iterate id="order" name="orderList" scope="request">
<tr>
   <td>
      <html:link action="/orderdetail" paramId="selectedOrderNumber" paramName="order" paramProperty="orderNumber" >
         <bean:write name="order" property="orderNumber" />
      </html:link>
   </td>
   <td><bean:write name="order" property="orderDate" /></td>
   <td><bean:write name="order" property="userId" /></td>
   <td><bean:write name="order" property="payMethodName" /></td>
   <td><bean:write name="order" property="paymentName" /></td>
   <td>
      <logic:equal name="order" property="delivery" value="0">未配達</logic:equal>
      <logic:equal name="order" property="delivery" value="1">配達済み</logic:equal>
      <logic:equal name="order" property="delivery" value="2">配達中</logic:equal>
   </td>
</tr>
</logic:iterate>
</table>
--------------------------------------------------------

上のソースでは、以前あった
   <td><bean:write name="order" property="delivery" /></td>
という行を
   <td>
      <logic:equal name="order" property="delivery" value="0">未配達</logic:equal>
      <logic:equal name="order" property="delivery" value="1">配達済み</logic:equal>
      <logic:equal name="order" property="delivery" value="2">配達中</logic:equal>
   </td>
に書き換えています。

ここで、logic:equalというタグでは、name属性にBeanの名前を指定し、property属性に
そのBeanのプロパティーの名前を指定し、value属性には比較したい値を指定します。
そうすると、logic:equalタグは、指定されたBeanのプロパティーの値を調べ、それが
value属性に指定した値と一致するときには、<logic:equal>と</logic:equal>の間の
文字列を書き出してくれます。

したがって、ここではorderのdeliveryプロパティーの値が0のときは「未配達」という
文字列を、1のときは「配達済み」という文字列を、2のときは「配達中」という
文字列を書き出してくれることになります。

以前(vol.211などで)紹介したlogic:matchタグとちょっと似ていますが、違いは
わかりますね。



では、続いてorderDetail.jspファイルについても同様の変更を行いましょう。
orderDetail.jspファイルを下記のように編集して下さい。

--------------------------------------------------------
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-nested" prefix="nested" %>

<table border="1" width="100%">
<tr>
  <td>
    <table border="0" width="100%">
    <tr>
      <td align="center">
       <b>注文の詳細</b>
      </td>
    </tr>
    <tr>
      <td>
        <br>
        <center>
          <table>
          <tr>
            <td>注文番号:</td>
            <td><bean:write name="ORDERSET" property="orderNumber"/></td>
          </tr>
          <tr>
            <td>注文日:</td>
            <td><bean:write name="ORDERSET" property="orderDate"/></td>
          </tr>
          <tr>
            <td>顧客番号:</td>
            <td><bean:write name="ORDERSET" property="userId"/></td>
          </tr>
          <tr>
            <td>支払い方法:</td>
            <td><bean:write name="ORDERSET" property="payMethodName"/></td>
          </tr>
          <tr>
            <td>支払い状況:</td>
            <td><bean:write name="ORDERSET" property="paymentName"/></td>
          </tr>
          <tr>
            <td>配送状況:</td>
            <td>
               <logic:equal name="ORDERSET" property="delivery" value="0">未配達</logic:equal>
               <logic:equal name="ORDERSET" property="delivery" value="1">配達済み</logic:equal>
               <logic:equal name="ORDERSET" property="delivery" value="2">配達中</logic:equal>
            </td>
          </tr>
          </table>
        </center>
      </td>
    </tr>
    </table>
  </td>
</tr>
</table>
--------------------------------------------------------



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆

では、再度テストをしてみましょう。

(1) 「サーバー」ビューの中の「ローカル・ホストのTomcat v5.5サーバー」を
右クリックし、「開始」を選択します。しばらくして、

ローカル・ホストのTomcat v5.5サーバー[始動済み,同期済み]

というように、後ろに「始動済み」の表示が出たら、Tomcatの起動が完了しています。

(2) Webブラウザー(Internet Explorer)を起動して、URL

http://localhost:8080/StrutsShop/tiles-parts/index.jsp

または、

http://localhost:8080/StrutsShop/tiles-parts/

を入力しましょう。

(3) 注文のリストが表示されますので、その中のどれかの注文番号(たとえば 1)を
クリックしましょう。

注文の詳細のWebページが開きますね。

どうですか、配達状況の欄に期待通りの文字列が表示されますね。

でも、現時点では「配達状況」が「未配達」のデータしか作られていない
はずだから、他の「配達済み」や「配達中」の文字列は確認できないですね。

では、これからこれらの状況を設定変更できるアプリケーションのコーディング
をしていきましょう。



なお、この(JSPファイルに直接文字列を持たせる)方法だと、文字列の情報を
複数のファイル(今回は2つのJSPファイルだけで済んだが、本格的なもっと
複雑なアプリケーションではずっと多くのファイルが変更対象になる)に
重複して書き込まなければならないため煩雑だし、間違いをおかす機会も
増えることになります。
さらに、これはあくまでアプリケーション側の変更であるために、変更する
たびにアプリケーションの運用を停止してデプロイし直してから運用を再開
するという面倒さが発生します。
また、データベースに一元化するのと違って、文字列データがどこで管理
されているのかわかりにくいという問題もあります。
という訳で、好ましい方法ではありません。



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆

では、これからこれらの状況を設定変更できるアプリケーションの実装をして
いきましょう。より正確には、以前お話したvol.216の

(2) 確定した注文については、状況をリスト表示し、料金支払い状況や配達状況
をいつでも確認/変更できるようにします。

に対する実装を行っていきます。



(次回に続く)



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