2.5.4. Strutsのサンプル

2.5.4.1. 実行手順

  1. サンプルプロジェクト struts-sample.zip をインポートします。
  2. 右クリック > サーバで実行 を選択します。
  3. http://Webサーバ名(ドメイン省略不可):ポート番号/struts-sample/ にアクセスします。

2.5.4.2. StrutsによるWebアプリケーション

フレームワーク

フレームワークは、Webアプリケーションを作成する上で必要となる共通的な機能や構造を提供します。 アプリケーションの共通的なメイン部分が提供されており、開発者はアプリケーション固有のロジックをフレームワークに組み込むことで、Webアプリケーションを作成することができます。


図2.5.4.2-1

フレームワークは、Web アプリケーションの画面制御や、エラーのハンドリングをしてくれるため、Webアプリケーションの開発工数を削減できます。 また、フレームワークに沿って、開発したアプリケーションは再利用性が高まります。

「MVCモデル2」Web アプリケーションのスケルトンです。 MVCモデル2とは下記のMVCとモデル2の考え方を組み合わせた物として提案されています。


図2.5.4.2-2

Strutsの仕組み

Strutsは定義ファイル(struts-config.xml)を設定することで、リクエストによる処理の振り分け、画面遷移の制御等を行います。

Strutsには以下の主要機能があります。
※ Modelに当たる処理はStrutsより制御できるようにStrutsの用意した特定クラスを継承する必要があります。 継承するクラスはアプリケーションクラスを作成するためのActionServletクラス、入力データの妥当性をチェックするためのActionFormクラス(ActionServletクラスが呼ばれる前に呼ばれます)等があります。

2.5.4.3. StrutsによるWebアプリケーションの開発

開発の流れ
サンプルWebアプリケーション

Strutsを使用したサンプルアプリケーション(StrutsSample)の開発手順を記述します。

1. シナリオ作成

Strutsを用いたサンプルWebアプリケーションを作成します。

サンプルの処理概要は

2. 処理概要をMVCに当てはめる


図2.5.4.3-1

※ MVCのC(Controller)に当たる処理は定義ファイルをを元にStrutsが行います。 ※ 表示データ編集処理は同一のものです。

サンプルの処理概要を3つの処理(A,B,C)に分けてMVCモデルに当てはめていきます。

ログオン処理(A)

注文データ入力処理(B)

注文データDB登録処理(C)

3. 各処理部品の概要

MVCに当てはめた各部品を作成していきます。

サンプルWebアプリケーションのファイル構成は次のようになります。

/struts-sample
|-- logon.jsp ログオン画面
|-- order.jsp 発注画面
|-- orderlist.jsp 発注一覧表示画面
|-- entryEnd.jsp 発注完了画面
|-- entryResult.jsp 発注結果表示画面
|-- index.html 初期表示画面(ログオン画面を呼び出します)
|-- /WEB-INF
|-- web.xml WebAPの定義ファイル
|-- struts-config.xml Strutsの定義ファイル
|-- strutsタグlib用tld
|-- /src/jp/co/nec/WebOTX/StrutsSample
| |-- DBOrderData.java 発注データDB登録処理
| |-- EditShowData.java 表示データ編集処理
| |-- LogonAction.java ログオンAction
| |-- LogonForm.java ログオンForm
| |-- OrderAction.java 発注Action
| |-- ShowAction.java データ表示Action
| |-- /lib/struts.jar Struts本体
|--/classes 上記のソースファイル(*.java)の実行ファイル(*.class)が格納される。
|-- ApplicationResources.properties 文字列リソースファイル(英語)
|-- ApplicationResources_ja.properties 文字列リソースファイル(日本語)
|-- /dbmng
|-- dbmng.html DBのテーブル作成/データ設定/削除/表示処理へのリンク
|-- dbtbladd.jsp DBにサンプルで使用するテーブルを作成する。
|-- dbtbldel.jsp 作成したテーブルを削除する。
|-- dbtblset.jsp 作成したテーブルに初期データを設定する。
|-- dbtblview.jsp DBより在庫データ、発注データを表示する。

サンプルWebアプリケーションの処理概要図は以下の通りです。


図2.5.4.3-2

画面の作成
1. 初期表示画面


図2.5.4.3-3

1) StrutsSampleの初期表示画面です。

2) 「ログオン画面へ」を選択するとログオン画面に遷移します。

2. ログオン画面


図2.5.4.3-4

1) サンプル実行時に起動される画面で、ユーザ名、パスワードを入力します。

表2.5.4.3-1
ユーザ名 パスワード
User_1 Pass_1
User_2 Pass_2

2) 「発注開始」ボタンをクリックすると、ログオンAction(LogonAction.class)にリクエストを送信します。

3) 「発注中止」ボタンをクリックすると、発注処理終了画面(entryEnd.jsp)に遷移し発注処理を中断します。

4) 使用しているStrutsの機能

errorタグを使用しエラーメッセージを表示した場合の画面を次に示します。


図2.5.4.3-5

ログオン画面(logon.jsp)のソースファイルを次に表示します。

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib uri="WEB-INF/struts-bean.tld"  prefix="bean" %>
<%@ taglib uri="WEB-INF/struts-html.tld"  prefix="html" %>

<html:html locale="true">
<head>  <title><bean:message key="logon.wtitle"/></title>  <html:base/>  </head>
<body bgcolor="#B0FFB0">
<html:errors/><br><br>
<CENTER><DIV style="background-color:#363562; width:90%; border-style :outset" align=center>
    <FONT size=42 color=white face="arial"><bean:message key="system.title"/></FONT>
</DIV></CENTER>
<form name="form1" METHOD="POST" ACTION="logon.do">
    <div align="center"><center>
    <table width="458" >
        <tr><td COLSPAN="3" width="450" align="right"/></tr>
        <tr>
          <td COLSPAN="3" width="450" align="left">
            <strong><bean:message key="word.user"/></strong>/<strong><bean:message key="word.pass"/></strong>
                    <bean:message key="logon.message1"/>
          </td>
        </tr>
        <tr>
          <td width="27" height="25"></td>
          <th width=103 height=25 nowrap bgcolor="#FFA477">
              <FONT color=green><bean:message key="word.user"/></FONT>
          </th>
          <td width=328 height=25 bgcolor="#FFE0C1"><input type="text" name="username"/></td>
        </tr>
        <tr>
          <td width="27" height="25"></td>
          <th  width=103 height=25 nowrap bgcolor="#FFA477">
              <FONT color=green><bean:message key="word.pass"/></font>
          </td>
          <td width="328" bgcolor="#FFE0C1" height="25"><input type="text" name="password"/></td>
        </tr>
        <tr>
          <td width="27" ></td>
          <td COLSPAN="2" valign="top" width="431" nowrap >
            <table border="0"  width="100%" height="65">
              <tr aligen="center">
                <td width="45%" aligen="rigth"><input type="submit"
                     value="<bean:message key="logon.button1"/>"/></td>
              </tr>
            </table>
          </td>
        </tr>
        <tr>
    </table>
    </center></div>
</form>
<form name="form2" method="POST" action="entryEnd.jsp">
    <div align="right">
        <input type="submit" value="<bean:message key="logon.button2"/>"/>
    </div>
</form>

<hr>
</body>
</html:html>
3. 発注画面


図2.5.4.3-6

1) ログオンAction(LogonAction.class)で生成されたログオン情報、表示データを元に画面を表示します。

2) 「Next/Before Page」ボタンをクリックすると、次/前ページの表示をデータ表示Action(ShowAction.class)にリクエストします。

3) 注文数に値が入力された場合、注文数(注文データ)の保存をデータ表示Action(ShowAction.class)にリクエストします。

4) 「注文状況一覧」ボタンをクリックすると、注文データ一覧の表示をデータ表示Action(ShowAction.class)にリクエストします。

5) 「発注を行います」ボタンをクリックすると、発注のリクエストを発注Action処理(OrderAction.class)に送信します。

6) 「発注中止ボタン」をクリックすると、発注処理終了画面(entryEnd.jsp)に遷移し発注処理を中断します。

7) 使用しているStrutsの機能

発注画面(order.jsp)のソースファイルを次に表示します。

<%@ page import="java.util.Hashtable" contentType="text/html;charset=UTF-8"%>
<%@ taglib uri="WEB-INF/struts-bean.tld"  prefix="bean" %>
<%@ taglib uri="WEB-INF/struts-html.tld"  prefix="html" %>

<html:html locale="true">
<head>
  <title><bean:message key="order.wtitle"/></title>
  <SCRIPT LANGUAGE="JavaScript">
    function fncchange(f){
        f.submit();
    }
  </SCRIPT>
  <html:base/>
</head>
<body bgcolor="#B0FFB0">

<html:errors/><br><br>

<CENTER><DIV style="background-color:#363562; width:90%; border-style :outset" align=center>
    <font size=42 color=white face="arial"><bean:message key="system.title"/></font>
</DIV></CENTER>
<br>

<%
    boolean errChk     = false;
    String _shop       = null;
    String _clerk      = null;
    String _orderno    = null;
    int    _shownum    = 0;
    int    _ordernum   = 0;

    String[] logonInfo = (String[])pageContext.getAttribute( "AttrLogOnInfo", pageContext.SESSION_SCOPE );
    if( logonInfo == null ) {
        errChk = true;
    } else {
        _shop       = logonInfo[0];
        _clerk      = logonInfo[1];
        _orderno    = logonInfo[2];
    }

    Integer _objInteger    = (Integer)pageContext.getAttribute( "AttrShowNum", pageContext.SESSION_SCOPE );
    if( _objInteger == null ) {
        errChk = true;
    } else {
        _shownum = _objInteger.intValue();
    }
    String[] _showproduct  = (String[])pageContext.getAttribute( "AttrShowProduct", pageContext.SESSION_SCOPE );
    String[] _showprodname = (String[])pageContext.getAttribute( "AttrShowProdName", pageContext.SESSION_SCOPE );
    Long[] _showprice      = (Long[])pageContext.getAttribute( "AttrShowPrice", pageContext.SESSION_SCOPE );
    Long[] _showstoks      = (Long[])pageContext.getAttribute( "AttrShowStoks", pageContext.SESSION_SCOPE );
    Hashtable _orderdata   = (Hashtable)pageContext.getAttribute("AttrOrderData", pageContext.SESSION_SCOPE );
    if( _showproduct == null || _showprodname == null || _showprice == null ||
        _showstoks == null   || _orderdata == null ) {
        errChk = true;
    }

%>
                                                                                                    <%
if( errChk ) {                                                                                      %>
  <center><bean:message key="error.system.paramerr"/></center>                                      <%
} else {                                                                                            %>
  <center><div align="center">
  <table border="0" width="678">
    <tr><td width="10%" nowrap><small><strong><bean:message key="word.orderno"/></strong></small></td>
        <td width="90%"><small><strong>:</strong><%=_orderno%></small></td></tr>
    <tr><td width="10%" nowrap><small><strong><bean:message key="word.branch"/></strong></small></td>
        <td width="90%"><small><strong>:</strong><%=_shop%></small></td></tr>
    <tr><td width="10%" nowrap><small><strong><bean:message key="word.charge"/></strong></small></td>
        <td width="90%"><small><strong>:</strong><%=_clerk%></small></td></tr>
  </table><br>
  <table border="0" width="678">
    <tr >
      <form name="orderform1" method="POST" action="show.do">
        <td width="70%" nowrap>
          <input type="submit" value="<< Before Page"><input type="hidden" name="REQ_KIND" value="BEFOR">
        </td>
      </form>
      <form name="orderform2" method="POST" action="show.do">
        <td width="30%" nowrap>
          <input type="submit" value="Next Page    >>"><input type="hidden" name="REQ_KIND" value="NEXT">
        </td>
      </form>
    </tr>

    <tr>
      <td COLSPAN="2" width="670" >
        <table border="0" width="100%">
          <tr>
            <th nowrap width="20%" bgcolor="#FF8F20"><bean:message key="word.product"/></th>
            <th nowrap width="20%" bgcolor="#FF8F20"><bean:message key="word.prdname"/></th>
            <th nowrap width="15%" bgcolor="#FF8F20"><bean:message key="word.price"/></th>
            <th nowrap width="10%" bgcolor="#FF8F20"><bean:message key="word.stoks"/></th>
            <th nowrap width="10%" bgcolor="#FF8F20"><bean:message key="word.ordernum"/></th>
            <th nowrap width="15%" bgcolor="#FF8F20"><bean:message key="word.subtotal"/></th>
          </tr>
<%        for(int cnt=0; cnt < _shownum; cnt++) {
              _objInteger = (Integer)_orderdata.get(_showproduct[cnt]);
              if( _objInteger != null ) {
                  _ordernum = _objInteger.intValue();
              } else {
                  _ordernum = 0;
              }                                                                                 %>
              <tr>
                <td nowrap width="20%" bgcolor="#FFE9D2" align="center"><%=_showproduct[cnt]%></td>
                <td nowrap width="20%" bgcolor="#FFE9D2"><%=_showprodname[cnt]%></td>
                <td nowrap width="15%" bgcolor="#FFE9D2" align="right"><%=_showprice[cnt]%></td>
                <td nowrap width="10%" bgcolor="#FFE9D2" align="right"><%=_showstoks[cnt]%></td>
                <form name="orderform3" method="POST" action="show.do">
                    <td nowrap width="10%" bgcolor="#FFE9D2">
                      <div align="center"><p><input NAME="REQ_VALUE2" TYPE="text" SIZE="3" align="right" 
                                              value="<%=_ordernum%>"  onChange="fncchange(this.form)"></div>
                    </td>
                    <td nowrap width="15%" bgcolor="#FFE9D2" align="right">
                        <%=new Long(_ordernum*_showprice[cnt].longValue())%></td>
                    <td nowrap width="0%">
                        <input name="REQ_KIND" type="hidden" value="SETORDER"></td>
                    <td nowrap width="0%">
                        <input name="REQ_VALUE1" type="hidden" value="<%=_showproduct[cnt]%>"></td>
                </form>
              </tr>                                                                             <%
          }                                                                                     %>
        </table>
      </td>
    </tr>
    <tr height="16"><td></td></tr>
      <tr>
        <td COLSPAN="2" >
          <table border="0" width="100%" height="16">
            <td nowrap width="25%" method="POST" height="16">
              <form name="orderform4" action="order.do">
                <input type="submit" size="150" value="<bean:message key="order.button1"/>"/>
              </form>
            </td>
            <td nowrap width="75%" height="16" align="left">
              <form name="orderform5" method="POST" action="show.do">
                <input type="submit" size="150" value="<bean:message key="order.button2"/>"/>
                <input type="hidden" name="REQ_KIND" value="ORDERLIST">
              </form>
            </td>
          </table>
        </td>
      </tr>
  </table>
  </div></center>                                                                                 <%
}                                                                                                 %>
<form name="form2" METHOD="POST" ACTION="entryEnd.jsp">
    <div align="right">
        <input type="submit" value="<bean:message key="logon.button2"/>"/>
    </div>
</form>

<hr align="center">
</body>
</html:html>
4. 発注一覧表示画面


図2.5.4.3-7

1) データ表示Action(ShowAction.class)で生成された一覧データを元に画面を表示します。

2) 「戻る」ボタンクリックでデータ表示Action(ShowAction.class)に発注画面表示をリクエストします。

3) 使用しているStruts機能

発注一覧表示画面(orderlist.jsp)のソースを次に表示します。

<%@ page import="java.util.Hashtable" contentType="text/html;charset=UTF-8"%>
<%@ taglib uri="WEB-INF/struts-bean.tld"  prefix="bean" %>
<%@ taglib uri="WEB-INF/struts-html.tld"  prefix="html" %>

<html:html locale="true">
<head>
  <title><bean:message key="order.wtitle"/></title>
  <SCRIPT LANGUAGE="JavaScript">
    function fncchange(f){
        f.submit();
    }
  </SCRIPT>
  <html:base/>
</head>
<body bgcolor="#B0FFB0">

<html:errors/><br><br>

<CENTER><DIV style="background-color:#363562; width:90%; border-style :outset" align=center>
    <font size=42 color=white face="arial"><bean:message key="system.title"/></font>
</DIV></CENTER>
<br>

<%
    boolean errChk    = false;
    String  _shop     = null;
    String  _clerk    = null;
    String  _orderno  = null;
    int     _ordernum = 0;
    int     _shownum  = 0;

    String[] logonInfo = (String[])pageContext.getAttribute( "AttrLogOnInfo", pageContext.SESSION_SCOPE );
    if( logonInfo == null ) {
        errChk = true;
    } else {
        _shop       = logonInfo[0];
        _clerk      = logonInfo[1];
        _orderno    = logonInfo[2];
    }

    Integer _objInteger    = (Integer)pageContext.getAttribute( "AttrShowNum", pageContext.SESSION_SCOPE );
    String[] _showproduct  = (String[])pageContext.getAttribute( "AttrShowProduct", pageContext.SESSION_SCOPE );
    String[] _showprodname = (String[])pageContext.getAttribute( "AttrShowProdName", pageContext.SESSION_SCOPE );
    Long[] _showprice      = (Long[])pageContext.getAttribute( "AttrShowPrice", pageContext.SESSION_SCOPE );
    Long[] _showstoks      = (Long[])pageContext.getAttribute( "AttrShowStoks", pageContext.SESSION_SCOPE );
    Hashtable _orderdata   = (Hashtable)pageContext.getAttribute("AttrOrderData", pageContext.SESSION_SCOPE );
    if( _objInteger == null || _showproduct == null || _showprodname == null ||
        _showprice == null  || _showstoks == null   || _orderdata == null ) {
        errChk = true;
    } else {
        _shownum = _objInteger.intValue();
    }
%>

                                                                                                    <%
if( errChk ) {                                                                                      %>
    <center><bean:message key="error.system.paramerr"/></center>
    <form name="form2" METHOD="POST" ACTION="entryEnd.jsp">
        <div align="right">
          <input type="submit" value="<bean:message key="logon.button2"/>"/>
        </div>
    </form>
                                                                                                    <%
} else {                                                                                            %>
    <center><div align="center">
    <table border="0" width="678">
        <tr>
          <td width="10%" nowrap><small><strong><bean:message key="word.orderno"/></strong></small></td>
          <td width="90%"><small><strong>:</strong><%=_orderno%></small></td>
        </tr>
        <tr>
          <td width="10%" nowrap><small><strong><bean:message key="word.branch"/></strong></small></td>
          <td width="90%"><small><strong>:</strong><%=_shop%></small></td>
        </tr>
        <tr>
          <td width="10%" nowrap><small><strong><bean:message key="word.charge"/></strong></small></td>
          <td width="90%"><small><strong>:</strong><%=_clerk%></small></td>
        </tr>
    </table><br>
    <table border="0" width="678">
        <tr>
          <td COLSPAN="2" width="670" >
            <table border="0" width="100%">
              <tr>
                <th nowrap width="20%" bgcolor="#FF8F20"><bean:message key="word.product"/></th>
                <th nowrap width="20%" bgcolor="#FF8F20"><bean:message key="word.prdname"/></th>
                <th nowrap width="15%" bgcolor="#FF8F20"><bean:message key="word.price"/></th>
                <th nowrap width="10%" bgcolor="#FF8F20"><bean:message key="word.stoks"/></th>
                <th nowrap width="10%" bgcolor="#FF8F20"><bean:message key="word.ordernum"/></th>
                <th nowrap width="15%" bgcolor="#FF8F20"><bean:message key="word.subtotal"/></th>
              </tr>
                                                                                                    <%
              for(int cnt=0; cnt < _shownum; cnt++) {
                  _objInteger = (Integer)_orderdata.get(_showproduct[cnt]);
                  if( _objInteger != null ) {
                      _ordernum = _objInteger.intValue();
                  } else {
                      _ordernum = 0;
                  }                                                                                 %>
                  <tr>
                    <td nowrap width="20%" bgcolor="#FFE9D2" align="center"><%=_showproduct[cnt]%></td>
                    <td nowrap width="20%" bgcolor="#FFE9D2"><%=_showprodname[cnt]%></td>
                    <td nowrap width="15%" bgcolor="#FFE9D2" align="right"><%=_showprice[cnt]%></td>
                    <td nowrap width="10%" bgcolor="#FFE9D2" align="right"><%=_showstoks[cnt]%></td>
                    <td nowrap width="10%" bgcolor="#FFE9D2" align="right"><%=_ordernum%></td>
                    <td nowrap width="15%" bgcolor="#FFE9D2" align="right"><%=new Long(_ordernum*_showprice[cnt].longValue())%></td>
                  </tr>                                                                             <%
              }                                                                                     %>
            </table>
          </td>
        </tr>
        <tr height="16"><td></td></tr>
        <tr>
          <td COLSPAN="2" >
            <table border="0" width="100%" height="16">
              <td nowrap width="75%" height="16" align="center">
                <form name="form13" method="POST" action="show.do">
                  <input type="submit" size="150" value="<bean:message key="orderlist.button1"/>"/>
                  <input type="hidden" name="REQ_KIND" value="RESHOW">
                </form>
              </td>
            </table>
          </td>
        </tr>
    </table>
    </div></center>                                                                                <%
}                                                                                                   %>

<br>
<hr align="center">
</body>
</html:html>
5. 発注結果表示画面


図2.5.4.3-8

1) 発注に失敗したデータの一覧を表示します。

2) 「Order Page」ボタンをクリックするとデータ表示Action(ShowDataAction.class)に発注画面表示をリクエストし、処理を継続します。

3) 「EntryEnd Page」ボタンをクリックすると発注完了画面(entryEnd.jsp)に遷移します。

4) 使用しているStrutsの機能

発注結果表示画面(entryResult.jsp)のソースを次に表示します。

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ page import="java.util.*" %>
<%@ taglib uri="WEB-INF/struts-bean.tld"  prefix="bean" %>
<%@ taglib uri="WEB-INF/struts-html.tld"  prefix="html" %>

<html:html locale="true">
<head>
<title><bean:message key="end.wtitle"/></title>
<html:base/>
</head>
<body bgcolor="#B0FFB0">

<CENTER><DIV style="background-color:#363562; width:90%; border-style :outset" align=center>
    <FONT size=42 color=white face="arial"><bean:message key="system.title"/></FONT>
</DIV></CENTER><br>
<center>
<html:errors/>
</center>

<center>
  <table border="0" width="678" >
    <tr>
      <td width="25%" height="18"></td>
      <td width="75%" height="18" align="right"></td>
    </tr>

    <tr>
      <td width="20%" ></td>
      <td valign="top" width="80%" nowrap >
        <table border="0"  width="100%" height="16">
          <td nowrap width="35%" height="16">
            <form name="form1" action="order.jsp">
                <input type="submit" border="0" width="125" value="Order Page"/>
            </form>
          </td>
          <td nowrap width="65%" height="16">
            <form name="form2" action="entryEnd.jsp">
                <input type="submit" border="0" width="125" value="Entry End Page"/>
            </form>
          </td>
        </table>
      </td>
    </tr>
  </table>
</center>

<hr>
</body>
</html:html>
6. 発注完了画面


図2.5.4.3-9

1) 発注処理に使用した一時データ(ログオン情報、注文データ等)を削除します。

2) 「LogOn Page」ボタンをクリックするとログオン画面(logon.jsp)に遷移します

3) 「Index Page」ボタンをクリックすると初期表示画面(index.html)に遷移します

4) 使用しているStrutsの機能

発注完了画面(entryEnd.jsp)のソースを次に表示します。

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ taglib uri="WEB-INF/struts-bean.tld"  prefix="bean" %>
<%@ taglib uri="WEB-INF/struts-html.tld"  prefix="html" %>

<html:html locale="true">
<head>
<title><bean:message key="end.wtitle"/></title>
<html:base/>
</head>
<body bgcolor="#B0FFB0">

<html:errors/><br><br>

<%
    // Attribute Info clear
    pageContext.removeAttribute( "AttrLogOnInfo",    pageContext.SESSION_SCOPE );
    pageContext.removeAttribute( "AttrShowNum",      pageContext.SESSION_SCOPE );
    pageContext.removeAttribute( "AttrShowProduct",  pageContext.SESSION_SCOPE );
    pageContext.removeAttribute( "AttrShowProdName", pageContext.SESSION_SCOPE );
    pageContext.removeAttribute( "AttrShowPrice",    pageContext.SESSION_SCOPE );
    pageContext.removeAttribute( "AttrShowStoks",    pageContext.SESSION_SCOPE );
    pageContext.removeAttribute( "AttrOrderData",    pageContext.SESSION_SCOPE );
    pageContext.removeAttribute( "AttrTotalRec",     pageContext.SESSION_SCOPE );
    pageContext.removeAttribute( "AttrNowPage",      pageContext.SESSION_SCOPE );
%>

<CENTER><DIV style="background-color:#363562; width:90%; border-style :outset" align=center>
    <FONT size=42 color=white face="arial"><bean:message key="system.title"/></FONT>
</DIV></CENTER><br>

<center>
  <table border="0" width="678" height="184">
    <tr>
      <td width="20%" height="18"></td>
      <td width="80%" height="18" align="right"></td>
    </tr>

    <tr><td></td><td><bean:message key="end.message1"/></td></tr>

    <tr>
      <td width="20%" ></td>
      <td valign="top" width="80%" nowrap >
        <table border="0"  width="100%" height="16">
          <td nowrap width="35%" height="16">
            <form name="form1" action="logon.jsp">
                <input type="submit" border="0" width="125" value="LogOn Page"/>
            </form>
          </td>
          <td nowrap width="65%" height="16">
            <form name="form2" action="index.html">
                <input type="submit" border="0" width="125" value="Index Page"/>
            </form>
          </td>
        </table>
      </td>
    </tr>
  </table>
</center>

<hr>
</body>
</html:html>
アプリケーションクラスの作成

StrutsのActionServletで受信したリクエストの振り分け先としてActionクラスを継承したアプリケーションクラスを作成します。 またFormクラスを継承したクラスはアプリケーションクラスが呼び出される前に入力をチェックするために呼び出されます。

1. ログオンForm

1) ログオン画面でユーザ名、パスワードが入力されている(nullでない)かチェックします。

2) 入力の確認ができたらログオンAction(LogonAction.class)に遷移します。

3) 使用しているStrutsの機能

ログオンForm(LogonForm.class)のソースを次に表示します。

package jp.co.nec.WebOTX.StrutsSample;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;

/**
 * Form bean for the user profile page.  This form has the following fields,
 * with default values in square brackets:
 * <ul>
 * <li><b>password</b> - Entered password value
 * <li><b>username</b> - Entered username value
 * </ul>
 *
 * @author Craig R. McClanahan
 * @version $Revision: 1.3 $ $Date$
 */

public final class LogonForm extends ActionForm {

    // --------------------------------------------------- Instance Variables

    /**
     * The password.
     */
    private String password = null;

    /**
     * The username.
     */
    private String username = null;

    // ----------------------------------------------------------- Properties
    /**
     * Return the password.
     */
    public String getPassword() {
        return (this.password);
    }

    /**
     * Set the password.
     *
     * @param password The new password
     */
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * Return the username.
     */
    public String getUsername() {
        return (this.username);
    }

    /**
     * Set the username.
     *
     * @param username The new username
     */
    public void setUsername(String username) {
        this.username = username;
    }
    // --------------------------------------------------------- Public Methods

    /**
     * Reset all properties to their default values.
     * @param mapping The mapping used to select this instance
     * @param request The servlet request we are processing
     */
    public void reset(ActionMapping mapping, HttpServletRequest request) {
        this.password = null;
        this.username = null;
    }

    /**
     * Validate the properties that have been set from this HTTP request,
     * and return an <code>ActionErrors</code> object that encapsulates any
     * validation errors that have been found.  If no errors are found, return
     * <code>null</code> or an <code>ActionErrors</code> object with no
     * recorded error messages.
     *
     * @param mapping The mapping used to select this instance
     * @param request The servlet request we are processing
     */
    public ActionErrors validate(ActionMapping mapping,
                                 HttpServletRequest request) {
        ActionErrors errors = new ActionErrors();
        if ((username == null) || (username.length() < 1))
            errors.add("username", new ActionError("error.username.required"));
        if ((password == null) || (password.length() < 1))
            errors.add("password", new ActionError("error.password.required"));

        return errors;
    }
}
2. ログオンAction

1) ログオン画面で指定されたログオン情報を元に発注番号を生成、保存します。

2) 表示データ編集処理(EditShowData.class)にて発注画面(order.jsp)で表示するデータを生成します

3) 使用しているStrutsの機能

ログオンAction(LogonAction.class)のソースを次に表示します。

package jp.co.nec.WebOTX.StrutsSample;

import java.io.*;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import java.util.Locale;
import java.util.Hashtable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.*;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
//import org.apache.struts.util.AppException;
import org.apache.struts.util.MessageResources;
//import org.apache.commons.beanutils.PropertyUtils;

import java.sql.*;
import java.util.Vector;

public final class LogonAction extends Action {
    // ----------------------------------------------------- Instance Variables

    /**
     * The <code>Log</code> instance for this application.
     */
//    private Log log =
//        LogFactory.getLog("struts.sample");

    // --------------------------------------------------------- Public Methods

    /**
     * Process the specified HTTP request, and create the corresponding HTTP
     * response (or forward to another web component that will create it).
     * Return an <code>ActionForward</code> instance describing where and how
     * control should be forwarded, or <code>null</code> if the response has
     * already been completed.
     *
     * @param mapping The ActionMapping used to select this instance
     * @param actionForm The optional ActionForm bean for this request (if any)
     * @param request The HTTP request we are processing
     * @param response The HTTP response we are creating
     *
     * @exception Exception if business logic throws an exception
     */
    public ActionForward perform(ActionMapping mapping,
//    public ActionForward execute(ActionMapping mapping,    
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
        throws IOException, ServletException {

        // Extract attributes we will need
        Locale locale = getLocale(request);
        MessageResources messages = getResources();

        // Validate the request parameters specified by the user
        ActionErrors errors = new ActionErrors();

        GenericServlet pservlet = (GenericServlet)getServlet();
        ServletContext servcon = pservlet.getServletContext();
        HttpSession session = request.getSession();


        String user = request.getParameter("username");
        String pass = request.getParameter("password");

        String[] dbInfo = null;  // DB接続情報
        String dbDriver = null;  // JDBCドライバ名
        String dbUrl    = null;  // DBへのURL
        String dbUserid = null;  // ユーザ名
        String dbPasswd = null;  // パスワード

        dbInfo = (String[])session.getAttribute( "AttrDBInfo" );
        if( dbInfo == null ) {
            dbInfo = new String[4];

            dbInfo[0] = dbDriver = servcon.getInitParameter( "dbDriver" );
            dbInfo[1] = dbUrl    = servcon.getInitParameter( "dbURL" );
            dbInfo[2] = dbUserid = servcon.getInitParameter( "dbUserId" );
            dbInfo[3] = dbPasswd = servcon.getInitParameter( "dbPassword" );

            session.setAttribute( "AttrDBInfo", dbInfo );
        } else {
            dbDriver = dbInfo[0];
            dbUrl    = dbInfo[1];
            dbUserid = dbInfo[2];
            dbPasswd = dbInfo[3];
        }

        Connection conn = null;
        Statement  stmt = null;
        ResultSet  rset = null;

        // 在庫テーブルのコネクション生成
        try {
            Class.forName( dbDriver );
            conn = DriverManager.getConnection( dbUrl, dbUserid, dbPasswd );
            stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
        } catch (Exception e) {  //SQLException / ClassNotFoundException / Exception
            try {  // DB Objectクローズ
                if( stmt != null ) {  stmt.close();  }
                if( conn != null ) {  conn.close();  }
            } catch(SQLException se) {  }
            throw new ServletException(e.toString());
        }

        Vector UserInfo = new Vector();
        try {
            String sqlStr = "SELECT * FROM WEBCONT_USERINFO";
            rset = stmt.executeQuery( sqlStr );
            for( ; rset.next()==true; ) {
                String userinfo[] = new String[3];
                userinfo[0] = rset.getString( 1 ).trim();
                userinfo[1] = rset.getString( 2 ).trim();
                userinfo[2] = rset.getString( 3 ).trim();
                UserInfo.add( userinfo );
            }
            rset.close();
        } catch (Exception e) {  //SQLException
            throw new ServletException(e.toString());
        }

        boolean boo = false;
        String logoninfo[] = new String[3];
        for( int cnt = 0; cnt < UserInfo.size(); cnt++ ) {
            String userinfo[] = (String[])UserInfo.get( cnt );
            if( userinfo[0].equals(user) && userinfo[1].equals(pass) ) {
                logoninfo[0] = userinfo[2];
                logoninfo[1] = userinfo[0];
                Timestamp times = new Timestamp(System.currentTimeMillis());
                DateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmss");
                logoninfo[2] = userinfo[2] + "-" +  userinfo[0] + "-" + fmt.format(times);
                boo = true;
                session.setAttribute( "AttrLogOnInfo", logoninfo );
            }
        }

        if( !boo ) {
            errors.add(ActionErrors.GLOBAL_ERROR,
                           new ActionError("error.logon.err", "logon error(user or pass)" ));
            saveErrors(request, errors);
            return (new ActionForward(mapping.getInput()));
        }

        session.setAttribute( "AttrOrderData", new Hashtable() );

        try {
            EditShowData edShowData = new EditShowData( servcon, request );
            session.setAttribute( "AttrNowPage", new Integer(1));
            edShowData.getShowData( request );
        } catch (IOException ie) {
            errors.add(ActionErrors.GLOBAL_ERROR,
                           new ActionError("error.logon.dberr", ie.toString() ));
            saveErrors(request, errors);
            return (new ActionForward(mapping.getInput()));
        }

        // Forward control to the specified success URI
        return mapping.findForward( "success" );
    }
}
3. データ表示Action

1) 発注画面表示が要求された場合、表示ページ数を元に表示データ編集処理(EditShowData.class)にて表示データを生成します

2) 次/前ページの表示を要求された場合、表示ページ数を更新して表示データ編集処理(EditShowData.class)にて発注画面(order.jsp)表示データを生成します

3) 注文数が入力された場合、注文数を製品コードをキーに注文データとして保存します。また注文数に0が設定された場合、該当するデータを削除します

4) 注文状況一覧が入力された場合、表示データ編集処理(EditShowData.class)にて注文データを元に表示する一覧データを生成します

5) 使用しているStrutsの機能

データ表示Action(ShowDataAction.class)のソースを次に表示します。

package jp.co.nec.WebOTX.StrutsSample;

import java.io.*;
import java.util.Hashtable;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.*;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
//import org.apache.struts.util.AppException;
import org.apache.struts.util.MessageResources;
//import org.apache.commons.beanutils.PropertyUtils;

/**
 * Implementation of <strong>Action</strong> that validates a user logon.
 *
 * @author Craig R. McClanahan
 * @version $Revision: 1.3 $ $Date$
 */
public final class ShowAction extends Action {

    // ----------------------------------------------------- Instance Variables

    /**
     * The <code>Log</code> instance for this application.
     */

    // --------------------------------------------------------- Public Methods

    /**
     * Process the specified HTTP request, and create the corresponding HTTP
     * response (or forward to another web component that will create it).
     * Return an <code>ActionForward</code> instance describing where and how
     * control should be forwarded, or <code>null</code> if the response has
     * already been completed.
     *
     * @param mapping The ActionMapping used to select this instance
     * @param actionForm The optional ActionForm bean for this request (if any)
     * @param request The HTTP request we are processing
     * @param response The HTTP response we are creating
     *
     * @exception Exception if business logic throws an exception
     */
    public ActionForward perform(ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
        throws IOException, ServletException {

        // Extract attributes we will need
        Locale locale = getLocale(request);
        MessageResources messages = getResources();

        // Validate the request parameters specified by the user
        ActionErrors errors = new ActionErrors();

        GenericServlet pservlet = (GenericServlet)getServlet();
        ServletContext servcon = pservlet.getServletContext();
        HttpSession session = request.getSession();
        String reqKind   = request.getParameter("REQ_KIND");

        if( reqKind.equals("SETORDER")) {
            String reqValue1 = request.getParameter("REQ_VALUE1");
            String reqValue2 = request.getParameter("REQ_VALUE2");
            Integer objInteger = null;

            if( reqValue1 == null || reqValue2 == null ) {
                errors.add(ActionErrors.GLOBAL_ERROR,
                               new ActionError("error.show.paramerr", reqValue1, reqValue2));
                saveErrors(request, errors);
                return (new ActionForward(mapping.getInput()));
            }

            try {
                objInteger = new Integer( reqValue2 );
            } catch(Exception e) {
                errors.add(ActionErrors.GLOBAL_ERROR,
                               new ActionError("error.show.numerr", reqValue2));
                saveErrors(request, errors);
                return (new ActionForward(mapping.getInput()));
            }

            Hashtable orderData = (Hashtable)session.getAttribute("AttrOrderData");
            if( orderData == null ) {
                orderData = new Hashtable();
            }

            if( objInteger.intValue() == 0 ) {
                orderData.remove( reqValue1 );
            } else {
                orderData.put( reqValue1, objInteger );
            }
            session.setAttribute("AttrOrderData", orderData);
        } else if( reqKind.equals("NEXT")) {
            Integer nowPage  = (Integer)session.getAttribute("AttrNowPage");
            Long totalRec = (Long)session.getAttribute("AttrTotalRec");
            int nowRec = ((nowPage.intValue()-1)*5)+1;
            if( (nowRec + 5) <= totalRec.intValue() ) {
                // 次のページに表示するデータ有
                nowPage = new Integer(nowPage.intValue()+1);
                // 表示ページ数更新
                session.setAttribute( "AttrNowPage", nowPage );
            }

            try {
                EditShowData edShowData = new EditShowData( servcon,request );
                edShowData.getShowData( request );
            } catch (IOException ie) {
                errors.add(ActionErrors.GLOBAL_ERROR,
                           new ActionError("error.show.dberr", ie.toString() ));
                saveErrors(request, errors);
                return (new ActionForward(mapping.getInput()));
            }
        } else if( reqKind.equals("BEFOR")) {
            Integer objInteger = (Integer)session.getAttribute("AttrNowPage");
            int nowPage = objInteger.intValue();
            if( (nowPage - 1) >= 1 ) {
                // 戻るページ有
                nowPage = nowPage - 1;
                // 表示ページ数更新
                session.setAttribute( "AttrNowPage", new Integer(nowPage) );
            }

            try {
                EditShowData edShowData = new EditShowData( servcon, request );
                edShowData.getShowData( request );
            } catch (IOException ie) {
                errors.add(ActionErrors.GLOBAL_ERROR,
                           new ActionError("error.show.dberr", ie.toString() ));
                saveErrors(request, errors);
                return (new ActionForward(mapping.getInput()));
            }
        } else if( reqKind.equals("ORDERLIST")) {
            try {
                EditShowData edShowData = new EditShowData( servcon, request );
                edShowData.getListData( request );
            } catch (IOException ie) {
                errors.add(ActionErrors.GLOBAL_ERROR,
                           new ActionError("error.show.dberr", ie.toString() ));
                saveErrors(request, errors);
                return (new ActionForward(mapping.getInput()));
            }

            // 一覧表示画面へ
            return (mapping.findForward("orderlist"));
        } else if( reqKind.equals("RESHOW")) {
            try {
                EditShowData edShowData = new EditShowData( servcon, request );
                edShowData.getShowData( request );
            } catch (IOException ie) {
                errors.add(ActionErrors.GLOBAL_ERROR,
                           new ActionError("error.show.dberr", ie.toString() ));
                saveErrors(request, errors);
                return (new ActionForward(mapping.getInput()));
            }
        } else {
            errors.add(ActionErrors.GLOBAL_ERROR,
                           new ActionError("error.show.kinderr", reqKind));
            saveErrors(request, errors);
            return (new ActionForward(mapping.getInput()));
        }

        // Forward control to the specified success URI
        return mapping.findForward( "success" );
    }
}
4. 発注処理Action

1) 注文データを発注データDB登録処理(DBOrderData.class)にてデータベースに登録します。

2) 発注処理が正常に終了した場合表示する画面を発注終了画面(entryEnd.jsp)に遷移します。 正常に終了しないデータがあった場合ActionErrorsオブジェクトにエラーになった商品データ一覧を作成し、発注結果表示画面(entryResult.jsp)に遷移します。

3) 使用しているStrutsの機能

発注処理Action(OrderAction.class)のソースを次に表示します。

package jp.co.nec.WebOTX.StrutsSample;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import java.io.*;
import java.util.Locale;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.*;
//import org.apache.commons.logging.Log;
//import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
//import org.apache.struts.util.AppException;
import org.apache.struts.util.MessageResources;
//import org.apache.commons.beanutils.PropertyUtils;

/**
 * Implementation of <strong>Action</strong> that validates a user logon.
 *
 * @author Craig R. McClanahan
 * @version $Revision: 1.3 $ $Date$
 */
public final class OrderAction extends Action {

    // ----------------------------------------------------- Instance Variables

    /**
     * The <code>Log</code> instance for this application.
     */
//    private Log log =
//        LogFactory.getLog("struts.sample");

    // --------------------------------------------------------- Public Methods

    /**
     * Process the specified HTTP request, and create the corresponding HTTP
     * response (or forward to another web component that will create it).
     * Return an <code>ActionForward</code> instance describing where and how
     * control should be forwarded, or <code>null</code> if the response has
     * already been completed.
     *
     * @param mapping The ActionMapping used to select this instance
     * @param actionForm The optional ActionForm bean for this request (if any)
     * @param request The HTTP request we are processing
     * @param response The HTTP response we are creating
     *
     * @exception Exception if business logic throws an exception
     */
    public ActionForward perform(ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
        throws IOException, ServletException {

        // Extract attributes we will need
        Locale locale = getLocale(request);
        MessageResources messages = getResources();

        // Validate the request parameters specified by the user
        ActionErrors errors = new ActionErrors();

        GenericServlet pservlet = (GenericServlet)getServlet();
        ServletContext servcon = pservlet.getServletContext();
        HttpSession session = request.getSession();

        try{
            DBOrderData dbOrder = new DBOrderData( servcon, request );
            dbOrder.errorData.clear();
            dbOrder.entryData( request );

            if( dbOrder.errorData.size() > 0 ) {
                session.setAttribute("AttrOrderData", dbOrder.errorData);
                Enumeration enu = dbOrder.errorData.keys();
                for( ; enu.hasMoreElements() ; ) {
                    String  keyname  = (String)enu.nextElement();
                    Integer ordernum = (Integer)dbOrder.errorData.get(keyname);

                    errors.add(ActionErrors.GLOBAL_ERROR,
                           new ActionError("error.order.orderNum", keyname, ordernum));
                    saveErrors(request, errors);
                }
                return mapping.findForward("result");
            }
        } catch(Exception e) {
            errors.add(ActionErrors.GLOBAL_ERROR,
                       new ActionError("error.order.dberr", e.toString()));
            saveErrors(request, errors);
            return mapping.findForward("end");
        }

        // Forward control to the specified success URI
        return mapping.findForward("end");

    }
}
ビジネスロジックの作成
1. 表示データ編集処理

1) 呼び出し元で指定されたページ数を元に発注画面(order.jsp)に表示するデータを生成、保存します。

2) 注文データを元に注文状況一覧画面(orderlist.jsp)に表示するデータ一覧を生成、保存します。

表示データ編集処理(EditShowData.class)のソースを次に表示します。

package jp.co.nec.WebOTX.StrutsSample;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.*;

import java.io.*;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Arrays;
import java.sql.*;
import java.sql.Date.*;
import java.sql.SQLException;

public final class EditShowData {

    // ----------------------------------------------------- Instance Variables

    /**
     * The <code>Log</code> instance for this application.
     */
    String[] dbInfo = null;  // DB接続情報
    String dbDriver = null;  // JDBCドライバ名
    String dbUrl    = null;  // DBへのURL
    String dbUserid = null;  // ユーザ名
    String dbPasswd = null;  // パスワード

    public EditShowData( ServletContext servcon,
                              HttpServletRequest request )
            throws IOException {

        initDBInfo( servcon, request );
    }

    // --------------------------------------------------------- Public Methods

    public void initDBInfo( ServletContext servcon,
                            HttpServletRequest request )
            throws IOException {

        Connection conn = null;
        Statement  stmt = null;
        ResultSet  rset = null;
        HttpSession session = request.getSession();

        // DB情報の取得
        dbInfo = (String[])session.getAttribute( "AttrDBInfo" );
        if( dbInfo == null ) {
            dbInfo = new String[4];

            dbInfo[0] = dbDriver = servcon.getInitParameter( "dbDriver" );
            dbInfo[1] = dbUrl    = servcon.getInitParameter( "dbURL" );
            dbInfo[2] = dbUserid = servcon.getInitParameter( "dbUserId" );
            dbInfo[3] = dbPasswd = servcon.getInitParameter( "dbPassword" );
            session.setAttribute( "AttrDBInfo", dbInfo );
        } else {
            dbDriver = dbInfo[0];
            dbUrl    = dbInfo[1];
            dbUserid = dbInfo[2];
            dbPasswd = dbInfo[3];
        }

        Long totalRec = (Long)session.getAttribute("AttrTotalRec");
        if( totalRec != null ) {
            return;
        }

        // 在庫テーブルのコネクション生成
        try {
            Class.forName( dbDriver );
            conn = DriverManager.getConnection( dbUrl, dbUserid, dbPasswd );
            stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
        } catch (Exception e) {  //SQLException / ClassNotFound / Exception
            try {  // DB Objectクローズ
                if( stmt != null ) {  stmt.close();  }
                if( conn != null ) {  conn.close();  }
            } catch(SQLException se) {  }
            throw new IOException(e.toString());
        }

        try {
            // 在庫テーブルのレコード数抽出
            rset = stmt.executeQuery("SELECT COUNT(*) from WEBCONT_WAREHOUSE");
            rset.next();
            long recNum = rset.getLong(1);
            session.setAttribute("AttrTotalRec", new Long(recNum));
        } catch (SQLException e) {
            throw new IOException(e.toString());
        } finally {
            try {
                // DB Objectクローズ
                rset.close();
                stmt.close();
                conn.close();
            } catch(SQLException se) {  }
        }
    }

    public void getShowData( HttpServletRequest request )
            throws IOException {

        Connection conn = null;
        Statement  stmt = null;
        ResultSet  rset = null;
        HttpSession session = request.getSession();

        // 在庫テーブルのコネクション生成
        try {
            Class.forName( dbDriver );
            conn = DriverManager.getConnection( dbUrl, dbUserid, dbPasswd );
            stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
        } catch (Exception e) {  //SQLException / ClassNotFound / Exception
            try {  // DB Objectクローズ
                if( stmt != null ) {  stmt.close();  }
                if( conn != null ) {  conn.close();  }
            } catch(SQLException se) {  }
            throw new IOException(e.toString());
        }

        Integer nowPage  = null;  // 現在表示ページ
        int     startRec = 0;     // 表示開始レコード

        // 表示開始レコード算出
        nowPage = (Integer)session.getAttribute("AttrNowPage");
        if( nowPage == null ) {
            nowPage = new Integer(1);
        }
        startRec = 1 + ((nowPage.intValue()-1) * 5);

        String rset_c1     = null;  // 製品CD
        String rset_c2     = null;  // 製品名
        long   rset_c3     = 0;     // 単価
        long   rset_c4     = 0;     // 在庫数
        int    cnt         = 0;     // カウンタ
        String attrName    = null;
        Integer orderNum   = null;

        String[] product  = new String[5];
        String[] prodname = new String[5];
        Long[]   price    = new Long[5];
        Long[]   stoks    = new Long[5];

        try {
            // 在庫テーブルの抽出
            rset = stmt.executeQuery( "SELECT * from WEBCONT_WAREHOUSE" );
            // 開始レコードの設定
            if (startRec == 1) {
                rset.beforeFirst();
            } else {
                rset.absolute(startRec-1);
            }

            // 表示データクリア
            session.removeAttribute( "AttrShowNum" );
            session.removeAttribute( "AttrShowProduct" );
            session.removeAttribute( "AttrShowProdName" );
            session.removeAttribute( "AttrShowPrice" );
            session.removeAttribute( "AttrShowStoks" );

            for( cnt = 0; cnt < 5 && (rset.next()==true); cnt++) {

                // 在庫データの取得
                rset_c1 = rset.getString(1);
                rset_c1 = rset_c1.trim();
                rset_c2 = rset.getString(2);
                rset_c2 = rset_c2.trim();
                rset_c3 = rset.getLong(3);
                rset_c4 = rset.getLong(4);

                // 在庫データの設定
                product[cnt] = rset_c1;
                prodname[cnt] = rset_c2;
                price[cnt] = new Long(rset_c3);
                stoks[cnt] = new Long(rset_c4);
            }

            session.setAttribute( "AttrShowNum", new Integer(cnt));
            session.setAttribute( "AttrShowProduct", product );
            session.setAttribute( "AttrShowProdName", prodname );
            session.setAttribute( "AttrShowPrice", price );
            session.setAttribute( "AttrShowStoks", stoks );
        } catch (SQLException e) {
            throw new IOException(e.toString());
        } finally {
            try {
                // DB Objectクローズ
                rset.close();
                stmt.close();
                conn.close();
            } catch(SQLException se) {  }
        }

        return;
    }


    public void getListData( HttpServletRequest request )
            throws IOException {

        Connection conn = null;
        Statement  stmt = null;
        ResultSet  rset = null;
        HttpSession session = request.getSession();

        // 在庫テーブルのコネクション生成
        try {
            Class.forName( dbDriver );
            conn = DriverManager.getConnection( dbUrl, dbUserid, dbPasswd );
            stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
        } catch (Exception e) {  //SQLException / ClassNotFound / Exception
            try {  // DB Objectクローズ
                if( stmt != null ) {  stmt.close();  }
                if( conn != null ) {  conn.close();  }
            } catch(SQLException se) {}

            throw new IOException(e.toString());
        }

        Hashtable orderData = (Hashtable)session.getAttribute( "AttrOrderData" );
        int orderNum  = orderData.size();

        // 現在表示データ保存
        Integer  rbkNum      = (Integer)session.getAttribute( "AttrShowNum" );
        String[] rbkProduct  = (String[])session.getAttribute( "AttrShowProduct" );
        String[] rbkProdName = (String[])session.getAttribute( "AttrShowProdName" );
        Long[]   rbkPrice    = (Long[])session.getAttribute( "AttrShowPrice" );
        Long[]   rbkStoks    = (Long[])session.getAttribute( "AttrShowStoks" );

        // 表示データクリア
        session.removeAttribute( "AttrShowNum" );
        session.removeAttribute( "AttrShowProduct" );
        session.removeAttribute( "AttrShowProdName" );
        session.removeAttribute( "AttrShowPrice" );
        session.removeAttribute( "AttrShowStoks" );

        Enumeration enu = orderData.keys();
        String[] sortprod = new String[orderNum];
        String[] product  = new String[orderNum];
        String[] prodname = new String[orderNum];
        Long[]   price    = new Long[orderNum];
        Long[]   stoks    = new Long[orderNum];
        int    cnt        = 0;     // カウンタ
        String sqlStr     = null;
        String rset_c1    = null;  // 製品CD
        String rset_c2    = null;  // 製品名
        long   rset_c3    = 0;     // 単価
        long   rset_c4    = 0;     // 在庫数
        int orderCnt      = 0;

        try {
            for( cnt = 0; cnt < orderNum; cnt++) {
                sortprod[cnt] = (String)enu.nextElement();
            }
            Arrays.sort(sortprod);
            for( cnt = 0; cnt < orderNum; cnt++) {
                rset_c1 = sortprod[cnt];
                sqlStr = "SELECT * FROM WEBCONT_WAREHOUSE WHERE PRODUCT_ID LIKE '" + rset_c1 +"'";
                rset = stmt.executeQuery( sqlStr );
                if ( !rset.first() ) {
                    continue;
                }
                // 在庫データの取得
                rset_c1 = rset_c1.trim();
                rset_c2 = rset.getString(2);
                rset_c2 = rset_c2.trim();
                rset_c3 = rset.getLong(3);
                rset_c4 = rset.getLong(4);
                // 在庫データの設定
                product[orderCnt]  = rset_c1;
                prodname[orderCnt] = rset_c2;
                price[orderCnt]    = new Long(rset_c3);
                stoks[orderCnt]    = new Long(rset_c4);
                orderCnt++;
            }

            // 表示データの更新
            session.setAttribute( "AttrShowNum", new Integer(orderCnt));
            session.setAttribute( "AttrShowProduct", product );
            session.setAttribute( "AttrShowProdName", prodname );
            session.setAttribute( "AttrShowPrice", price );
            session.setAttribute( "AttrShowStoks", stoks );

            // DB Objectクローズ
            if( rset != null ) rset.close();
        } catch (SQLException e) {
            // 現在表示データの復帰
            session.setAttribute( "AttrShowNum",      rbkNum );
            session.setAttribute( "AttrShowProduct",  rbkProduct );
            session.setAttribute( "AttrShowProdName", rbkProdName );
            session.setAttribute( "AttrShowPrice",    rbkPrice );
            session.setAttribute( "AttrShowStoks",    rbkStoks );
            throw new IOException(e.getMessage());
        } finally {
            try {  // DB Objectクローズ
                stmt.close();
                conn.close();
            } catch(SQLException se) {  }
        }

        return;
    }
}
2. 発注データDB登録処理

1) 注文データを元に発注済データの登録と在庫管理テーブルの更新を行います。

在庫データ − 注文データ ⇒更新⇒ 在庫データ
注文データ ⇒追加⇒ 発注済データ

発注データDB登録処理(DBOrderData.class)のソースを次に表示します。

package jp.co.nec.WebOTX.StrutsSample;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.*;

import java.io.*;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Arrays;
import java.sql.*;
import java.sql.Date.*;
import java.sql.SQLException;

public final class DBOrderData {

    // ----------------------------------------------------- Instance Variables
    /**
     * The <code>Log</code> instance for this application.
     */
    String[] dbInfo = null;  // DB接続情報
    String dbDriver = null;  // JDBCドライバ名
    String dbUrl    = null;  // DBへのURL
    String dbUserid = null;  // ユーザ名
    String dbPasswd = null;  // パスワード
    Hashtable errorData = new Hashtable();

    public DBOrderData( ServletContext servcon,
                            HttpServletRequest request )
            throws IOException {

        initDBInfo( servcon, request );
    }

    // --------------------------------------------------------- Public Methods

    public void initDBInfo( ServletContext servcon,
                            HttpServletRequest request )
            throws IOException {

        Connection conn = null;
        Statement  stmt = null;
        ResultSet  rset = null;

        HttpSession session = request.getSession();

        // DB情報の取得
        dbInfo = (String[])session.getAttribute( "AttrDBInfo" );
        if( dbInfo == null ) {
            dbInfo = new String[4];

            dbInfo[0] = dbDriver = servcon.getInitParameter( "dbDriver" );
            dbInfo[1] = dbUrl    = servcon.getInitParameter( "dbURL" );
            dbInfo[2] = dbUserid = servcon.getInitParameter( "dbUserId" );
            dbInfo[3] = dbPasswd = servcon.getInitParameter( "dbPassword" );
            session.setAttribute( "AttrDBInfo", dbInfo );
        } else {
            dbDriver = dbInfo[0];
            dbUrl    = dbInfo[1];
            dbUserid = dbInfo[2];
            dbPasswd = dbInfo[3];
        }
    }

    public void entryData( HttpServletRequest request )
            throws IOException {

        Connection conn = null;
        Statement  stmt = null;
        ResultSet  rset = null;
        PreparedStatement  od_stmt = null;
        HttpSession session = request.getSession();

        // 在庫テーブルのコネクション生成
        try {
            Class.forName( dbDriver );
            conn = DriverManager.getConnection( dbUrl, dbUserid, dbPasswd );
            stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
        } catch (Exception e) {  //SQLException / ClassNotFound / Exception
            try {
                // DB Objectクローズ
                if( stmt != null ) {  stmt.close();  }
                if( conn != null ) {  conn.close();  }
            } catch(SQLException se) { }
            throw new IOException(e.toString());
        }

        Hashtable orderData = (Hashtable)session.getAttribute("AttrOrderData");
        if( orderData == null ) {
            return;
        }

        String rset_c1     = null;  // 製品CD
        String rset_c2     = null;  // 製品名
        long   rset_c3     = 0;     // 単価
        long   rset_c4     = 0;     // 在庫数
        long   sub_total   = 0;     // 小計
        Timestamp  nowtim  = null;  // 日時刻
        Integer orderNum   = null;  // 注文数
        String sqlStr      = null;  // 実行SQL文

        String[] logonInfo = (String[])session.getAttribute("AttrLogOnInfo");
        if( logonInfo == null ) {
            throw new IOException("not found logon data");
        }

        Enumeration enu = orderData.keys();

        try {
            for( ; enu.hasMoreElements(); ) {
                rset_c1 = (String)enu.nextElement();
                // 在庫データより該当データを抽出
                sqlStr = "SELECT * FROM WEBCONT_WAREHOUSE WHERE PRODUCT_ID LIKE '" + rset_c1 +"'";

                // 自動コミットを解除
                conn.setAutoCommit( false );

                // 在庫テーブルの抽出
                rset = stmt.executeQuery( sqlStr );
                rset.beforeFirst();

                if( rset.next() != true ) {
                    // 自動コミットを復活
                    conn.setAutoCommit( true );
                    continue;
                }

                // 発注データ有無チェック
                if( orderData.get( rset_c1 ) == null ) {
                    // 自動コミットを復活
                    conn.setAutoCommit( true );
                    continue;
                }

                rset_c2 = rset.getString(2);
                rset_c2 = rset_c2.trim();
                rset_c3 = rset.getLong(3);
                rset_c4 = rset.getLong(4);

                orderNum = (Integer)orderData.get( rset_c1 );
                rset_c4 = rset_c4 - orderNum.longValue();
                if( rset_c4 < 0 ) {
                    errorData.put( rset_c1, orderNum );

                    // 自動コミットを復活
                    conn.setAutoCommit( true );
                    continue;
                }

                // 検索結果クローズ
                rset.close();

                // 在庫テーブルの在庫数更新
                sqlStr = "UPDATE WEBCONT_WAREHOUSE SET STOCK_NUM='" + 
                          new Long(rset_c4).toString() + 
                         "' WHERE PRODUCT_ID='" + rset_c1 + "'";
                stmt.executeQuery( sqlStr );

                // 発注済みデータの登録
                sqlStr = "INSERT INTO WEBCONT_ORDER(ORDER_SHOP," + "ORDER_CLERK," + 
                                               "ORDER_NO," + "ORDER_DATE," + 
                                               "PRODUCT_ID," + "PRODUCT_NAME," + 
                                               "UNIT_PRICE," + "ORDER_NUM,SUB_TOTAL)" + 
                                " values (?,?,?,?,?,?,?,?,?)";
                // INSERT (注文店/注文者/注文番号/注文日付/製品CD/製品名/単価/注文数/小計)
                od_stmt = conn.prepareStatement( sqlStr );

                sub_total    = orderNum.longValue() * rset_c3; // 小計計算
                nowtim = new Timestamp(System.currentTimeMillis());
                od_stmt.setString( 1, logonInfo[0] );        // 発注店設定
                od_stmt.setString( 2, logonInfo[1] );        // 発注者設定
                od_stmt.setString( 3, logonInfo[2] );        // 発注番号設定
                od_stmt.setTimestamp( 4, nowtim );           // 注文日設定
                od_stmt.setString( 5, rset_c1 );             // 製品CD設定
                od_stmt.setString( 6, rset_c2 );             // 製品名設定
                od_stmt.setLong( 7, rset_c3 );               // 単価設定
                od_stmt.setLong( 8, orderNum.longValue() );  // 注文数設定
                od_stmt.setLong( 9, sub_total );             // 小計設定
                // 設定実行
                od_stmt.execute();

                // ステートメントクローズ
                od_stmt.close();

                // コミットを行う
                conn.commit();

                // 自動コミットを復活
                conn.setAutoCommit( true );

                // 発注済みデータを発注データより削除
                orderData.remove( rset_c1 );
            }

        } catch (Exception e) {
            try {
                conn.rollback();
            } catch(SQLException e2) {
                throw new IOException("DBOrder rollback NG");
            }
            throw new IOException(e.toString());
        } finally {
            try {
                // 自動コミットを復活
                conn.setAutoCommit( true );

                // DB Objectクローズ
                stmt.close();
                conn.close();
            } catch(SQLException se) { }
        }

        return;
    }
}
2.1. データベースへのアクセス

ユーザ情報、発注データを保存するためにデータベースを使用します。今回はOracleとそのJDBCドライバを使用しデータの読み書きを行います。 JDBC ドライバのファイル(今回はclasses12.zip)をテスト用サーバのクラスパスに登録しておく必要があります。

try {
  Class.forName( "DBのドライバ名" ); // (1)
  Connection conn = DriverManager.getConnection("DBのURL","DBのユーザ名", "DBのパスワード" ); // (2)
  Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); // (3)
} catch (SQLException e) {
:
(1)でJDBCドライバを読み込みます
(2)でコネクションを生成します。
(3)でステートメントを作成し、以後ステートメントに対してSQLを発行します。

サンプルで使用するOracleDBのテーブル情報は以下の通り。

表2.5.4.3-2 在庫管理テーブル
製品ID 製品名 単価 在庫数
PRODUCT_ID PRODUCT_NAME UNIT_PRICE STOCK_NUM
char(32) char(32) number number
表2.5.4.3-3 発注済データテーブル
発注店 担当者 発注番号 発注日 製品ID 製品名 単価 注文数 小計
ORDER_SHOP ORDER_CLERK ORDER_NO ORDER_DATE PRODUCT_ID PRODUCT_NAME UNIT_PRICE ORDER_NUM SUB_TOTAL
char(32) char(32) char(64) Date char(10) char(32) number Number number
表2.5.4.3-4 ユーザ情報テーブル
ユーザ名 パスワード 担当店
INFO_USER INFO_PASS INFO_SHOP
char(32) char(32) char(32)
定義ファイルの作成

Struts定義ファイル(struts-config.xml)を作成します。 HTTPからのリクエストを振り分ける、またレスポンスとして処理するファイルを決定するために、 struts-config.xmlファイルを設定する必要があります。

今回のサンプルWebアプリケーションの定義ファイルは次のようになります。

例) struts-config.xmlの設定例

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

<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>
  <!-- ========== Form Bean Definitions =================================== -->
  <form-beans>
    <!-- Logon form bean -->
    <form-bean      name="logonForm"
                    type="jp.co.nec.WebOTX.StrutsSample.LogonForm"/>
  </form-beans>

  <!-- ========== Global Forward Definitions ============================== -->
  <global-forwards>
        <forward name="success"              path="/order.jsp"/>
        <forward name="end"                  path="/entryEnd.jsp"/>
  </global-forwards>

  <!-- ========== Action Mapping Definitions ============================== -->
  <action-mappings>
    <action    path="/logon"
               type="jp.co.nec.WebOTX.StrutsSample.LogonAction"
               name="logonForm"
               scope="request"
               input="/logon.jsp">
      <forward name="success"              path="/order.jsp"/>
    </action>

    <action    path="/show"
               type="jp.co.nec.WebOTX.StrutsSample.ShowAction"
               scope="request"
               input="/order.jsp">
      <forward name="success"              path="/order.jsp"/>
      <forward name="orderlist"            path="/orderlist.jsp"/>
    </action>

    <action    path="/order"
               type="jp.co.nec.WebOTX.StrutsSample.OrderAction"
               scope="request"
               input="/order.jsp">
      <forward name="success"              path="/order.jsp"/>
      <forward name="result"               path="/entryResult.jsp"/>
    </action>

  </action-mappings>

    <message-resources parameter="jp.co.nec.WebOTX.StrutsSample.ApplicationResources"/>  

</struts-config>

各要素について解説します。

<form-bean> : 画面からの入力値をチェックするためのActionFormクラスを敬称したクラスを設定します。
<form-bean> : ユーザ名、パスワードの入力をチェックするLogonFormクラス(tyoe属性)を登録し、名前(name属性)をつけます。名前は<action>で指定されます。
<global-forwards> : Actionクラスを継承したアプリケーションクラスの処理終了時、次に表示する画面を設定します。
<forward> : アプリケーションクラス終了時に”success”を指定(name属性)すると発注画面(path属性)に、”end”を指定(name属性)すると発注完了画面(path属性)に、それぞれ遷移します。ただし<action>内に同名の<forward>設定があった場合、そちらが優先されます。
<action-mapping> : リクエストを振り分ける情報を設定します。
<action> : ActionServlet.classにリクエスト(URLがlogon.do、show.do、order.do)が来た場合、それぞれLogonAction.class、ShowAction.class、OrderAction.classに振り分ける(path属性、type属性)。 使用するFormクラスがある場合は指定する(name属性)。 エラーが発生した場合など、遷移先のリクエスト元画面を定義(input属性)しておく。
<forward> : アプリケーションクラス終了時、遷移先の画面を指定する。(<grobal-forwards>と同様)

WebAPの定義ファイル(web.xml)ファイルを作成します。 ここではポイントとなるServletのマッピングについて記述します。

web.xmlの設定

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

<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
    <context-param>
        <param-name>dbURL</param-name>
        <param-value>jdbc:oracle:thin:@servername:1521:orcl</param-value>
    </context-param>
    <context-param>
        <param-name>dbDriver</param-name>
        <param-value>oracle.jdbc.driver.OracleDriver</param-value>
    </context-param>
    <context-param>
        <param-name>dbUserId</param-name>
        <param-value>scott</param-value>
    </context-param>
    <context-param>
        <param-name>dbPassword</param-name>
        <param-value>tiger</param-value>
    </context-param>

    <!-- Standard Action Servlet Configuration (with debugging) -->
    <servlet>
      <servlet-name>action</servlet-name>
      <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
      <init-param>
        <param-name>config</param-name>
        <param-value>/WEB-INF/struts-config.xml</param-value>
      </init-param>
      <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
      </init-param>
      <init-param>
        <param-name>detail</param-name>
        <param-value>0</param-value>
      </init-param>
      <init-param>
        <param-name>validate</param-name>
        <param-value>true</param-value>
      </init-param>
      <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>action</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

    <!-- The Usual Welcome File List -->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
    </welcome-file-list>

    <!-- Struts Tag Library Descriptors -->
    <taglib>
        <taglib-uri>http://struts-bean</taglib-uri>
        <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
    </taglib>
    <taglib>
        <taglib-uri>http://struts-html</taglib-uri>
        <taglib-location>/WEB-INF/struts-html.tld</taglib-location>
    </taglib>
    <taglib>
        <taglib-uri>http://struts-logic</taglib-uri>
        <taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
    </taglib>
    <taglib>
        <taglib-uri>http://struts-template</taglib-uri>
        <taglib-location>/WEB-INF/struts-template.tld</taglib-location>
    </taglib>

</web-app>

<servlet-mapping>の設定によりURLの最後が.doでリクエストされた場合、全てStrutsのActionServletクラスが受信することになります。 ActionServletクラスは.doの前の部分とStruts定義ファイル(struts-config.xml)を使用し、振り分け先のアプリケーションクラスを決定します。

warの配備

Webブラウザより運用管理コンソールを呼び出します。

http://localhost:5858/manager/

と入力してください。

ユーザ名、パスワードを要求された場合、admin/adminadmin を入力してください。 運用管理コンソールが表示されたら、画面左のツリーより「アプリケーション」を選択します。 アプリケーションの配備画面が表示されます。 「コンポーネントタイプ」から「Webコンポーネント」を選択し、「ファイル」に struts-sample.war を指定します。 「詳細項目の表示」をクリックし、詳細項目表示後、「コンポーネント名」に「struts」を指定、「コンテキストルート」に「/struts」を指定して配備を実行してください。

以上でWebアプリケーション「struts-example」が配備されます。

Webアプリケーションの動作確認

ブラウザより http://localhost/struts/ にアクセスします。

ログオン画面の表示確認

ログオン画面が表示されることを確認します。

ログオン失敗の確認

ログオンに失敗した場合の処理を確認します。
何も入力せずに発注開始を選択した場合
→ ログオン画面に戻り、エラーメッセージが画面上部に表示されていること
StrutsのTagを使用したエラーの表示
誤ったユーザ名/パスワードを入力した場合
→ ログオン画面に戻り、エラーメッセージが画面上部に表示されていること
StrutsのTagを使用したエラーの表示

ログオン成功の確認

ユーザ名(User_1)、パスワード(Pass_1)を入力し発注開始を選択
発注画面が表示されることを確認します。

発注画面表示の確認

発注画面が表示されることを確認します。

発注商品選択の確認

商品を選択し、注文数を入力します。小計が計算され表示されることを確認します。

発注データ一覧画面

発注データ一覧画面を表示し、注文した商品の一覧が表示されることを確認します。

発注処理の確認

発注処理を実行し、発注完了画面が表示されることを確認します。
DBに発注データが登録され、在庫データが更新されていることを確認します。(dbtblview.jspを使用)

発注処理で在庫データ不足により発注に失敗した商品があった場合、発注結果表示画面がが表示されることを確認します。

発注を継続する場合、発注画面が表示されることを確認します。
発注を中止した場合、発注完了画面が表示されることを確認します。

発注完了画面が表示されることを確認します。

発注完了画面は発注処理が正常に終了した場合、発注処理を途中で中断した場合に表示されます。
データソースの利用

DBへのコネクション生成は時間のかかる処理です。 このコネクションをあらかじめ生成して、データソースとしてJNDIに登録しておき、使用時に呼び出すことで、生成にかかる時間を短縮することができます。 プログラム中でコネクションを使用するときは、JNDIからコネクション(データソース)を取得(lookup)することで、コネクションを取得します。

2.5.4.4. 注意事項

サンプルを実行する前に、DBの設定が必要です。詳細は2.5.2.2. 各サンプルの初期設定 を参照してください。

「ログオン画面へ」のリンクをクリックすると、「java.lang.NoClassDefFoundError」が発生するなら、以下の操作を行ってください。