1. StrutsによるWebアプリケーション
1.1. フレームワーク

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

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

1.2. Strutsとは

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

1.3. Strutsの仕組み

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

2. StrutsによるWebアプリケーションの開発
2.1. 開発の流れ

  • シナリオ作成 :作成するWebAPの処理概要を作成します。
  • MVCに当てはめる :処理概要をMVCモデルに当てはめます。
  • 処理部品の作成 :MVCモデルに当てはめた各処理を作成します。
  • 定義ファイル作成 :各処理を制御(リクエスト振り分け、画面遷移等)する定義ファイルを作成します。
  • 2.2. サンプルWebアプリケーション

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

    2.2.1. シナリオ作成

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

    サンプルの処理概要は

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

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

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

    ログオン処理(A)

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

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

    2.2.3. 各処理部品の概要

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

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

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

    2.3. 画面の作成
    2.3.1. 初期表示画面

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

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

    2.3.2. ログオン画面

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

    ユーザ名パスワード
    User_1Pass_1
    User_2Pass_2

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

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

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

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

    ログオン画面(logon.jsp)のソースファイルを次に表示します。
    000: <%@ page language="java" contentType="text/html;charset=UTF-8"%>
    001: <%@ taglib uri="WEB-INF/struts-bean.tld"  prefix="bean" %>
    002: <%@ taglib uri="WEB-INF/struts-html.tld"  prefix="html" %>
    003: 
    004: <html:html locale="true">
    005: <head>  <title><bean:message key="logon.wtitle"/></title>  <html:base/>  </head>
    006: <body bgcolor="#B0FFB0">
    007: <html:errors/><br><br>
    008: <CENTER><DIV style="background-color:#363562; width:90%; border-style :outset" align=center>
    009:     <FONT size=42 color=white face="arial"><bean:message key="system.title"/></FONT>
    010: </DIV></CENTER>
    011: <form name="form1" METHOD="POST" ACTION="logon.do">
    012:     <div align="center"><center>
    013:     <table width="458" >
    014:         <tr><td COLSPAN="3" width="450" align="right"/></tr>
    015:         <tr>
    016:           <td COLSPAN="3" width="450" align="left">
    017:             <strong><bean:message key="word.user"/></strong>/<strong><bean:message key="word.pass"/></strong>
    018:                     <bean:message key="logon.message1"/>
    019:           </td>
    020:         </tr>
    021:         <tr>
    022:           <td width="27" height="25"></td>
    023:           <th width=103 height=25 nowrap bgcolor="#FFA477">
    024:               <FONT color=green><bean:message key="word.user"/></FONT>
    025:           </th>
    026:           <td width=328 height=25 bgcolor="#FFE0C1"><input type="text" name="username"/></td>
    027:         </tr>
    028:         <tr>
    029:           <td width="27" height="25"></td>
    030:           <th  width=103 height=25 nowrap bgcolor="#FFA477">
    031:               <FONT color=green><bean:message key="word.pass"/></font>
    032:           </td>
    033:           <td width="328" bgcolor="#FFE0C1" height="25"><input type="text" name="password"/></td>
    034:         </tr>
    035:         <tr>
    036:           <td width="27" ></td>
    037:           <td COLSPAN="2" valign="top" width="431" nowrap >
    038:             <table border="0"  width="100%" height="65">
    039:               <tr aligen="center">
    040:                 <td width="45%" aligen="rigth"><input type="submit"
    041:                      value="<bean:message key="logon.button1"/>"/></td>
    042:               </tr>
    043:             </table>
    044:           </td>
    045:         </tr>
    046:         <tr>
    047:     </table>
    048:     </center></div>
    049: </form>
    050: <form name="form2" method="POST" action="entryEnd.jsp">
    051:     <div align="right">
    052:         <input type="submit" value="<bean:message key="logon.button2"/>"/>
    053:     </div>
    054: </form>
    055: 
    056: <hr>
    057: </body>
    058: </html:html>
    <EOF>

    2.3.3. 発注画面

    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)のソースファイルを次に表示します。
    000: <%@ page import="java.util.Hashtable" contentType="text/html;charset=UTF-8"%>
    001: <%@ taglib uri="WEB-INF/struts-bean.tld"  prefix="bean" %>
    002: <%@ taglib uri="WEB-INF/struts-html.tld"  prefix="html" %>
    003: 
    004: <html:html locale="true">
    005: <head>
    006:   <title><bean:message key="order.wtitle"/></title>
    007:   <SCRIPT LANGUAGE="JavaScript">
    008:     function fncchange(f){
    009:         f.submit();
    010:     }
    011:   </SCRIPT>
    012:   <html:base/>
    013: </head>
    014: <body bgcolor="#B0FFB0">
    015: 
    016: <html:errors/><br><br>
    017: 
    018: <CENTER><DIV style="background-color:#363562; width:90%; border-style :outset" align=center>
    019:     <font size=42 color=white face="arial"><bean:message key="system.title"/></font>
    020: </DIV></CENTER>
    021: <br>
    022: 
    023: <%
    024:     boolean errChk     = false;
    025:     String _shop       = null;
    026:     String _clerk      = null;
    027:     String _orderno    = null;
    028:     int    _shownum    = 0;
    029:     int    _ordernum   = 0;
    030: 
    031:     String[] logonInfo = (String[])pageContext.getAttribute( "AttrLogOnInfo", pageContext.SESSION_SCOPE );
    032:     if( logonInfo == null ) {
    033:         errChk = true;
    034:     } else {
    035:         _shop       = logonInfo[0];
    036:         _clerk      = logonInfo[1];
    037:         _orderno    = logonInfo[2];
    038:     }
    039: 
    040:     Integer _objInteger    = (Integer)pageContext.getAttribute( "AttrShowNum", pageContext.SESSION_SCOPE );
    041:     if( _objInteger == null ) {
    042:         errChk = true;
    043:     } else {
    044:         _shownum = _objInteger.intValue();
    045:     }
    046:     String[] _showproduct  = (String[])pageContext.getAttribute( "AttrShowProduct", pageContext.SESSION_SCOPE );
    047:     String[] _showprodname = (String[])pageContext.getAttribute( "AttrShowProdName", pageContext.SESSION_SCOPE );
    048:     Long[] _showprice      = (Long[])pageContext.getAttribute( "AttrShowPrice", pageContext.SESSION_SCOPE );
    049:     Long[] _showstoks      = (Long[])pageContext.getAttribute( "AttrShowStoks", pageContext.SESSION_SCOPE );
    050:     Hashtable _orderdata   = (Hashtable)pageContext.getAttribute("AttrOrderData", pageContext.SESSION_SCOPE );
    051:     if( _showproduct == null || _showprodname == null || _showprice == null ||
    052:         _showstoks == null   || _orderdata == null ) {
    053:         errChk = true;
    054:     }
    055: 
    056: %>
    057:                                                                                                     <%
    058: if( errChk ) {                                                                                      %>
    059:   <center><bean:message key="error.system.paramerr"/></center>                                      <%
    060: } else {                                                                                            %>
    061:   <center><div align="center">
    062:   <table border="0" width="678">
    063:     <tr><td width="10%" nowrap><small><strong><bean:message key="word.orderno"/></strong></small></td>
    064:         <td width="90%"><small><strong>:</strong><%=_orderno%></small></td></tr>
    065:     <tr><td width="10%" nowrap><small><strong><bean:message key="word.branch"/></strong></small></td>
    066:         <td width="90%"><small><strong>:</strong><%=_shop%></small></td></tr>
    067:     <tr><td width="10%" nowrap><small><strong><bean:message key="word.charge"/></strong></small></td>
    068:         <td width="90%"><small><strong>:</strong><%=_clerk%></small></td></tr>
    069:   </table><br>
    070:   <table border="0" width="678">
    071:     <tr >
    072:       <form name="orderform1" method="POST" action="show.do">
    073:         <td width="70%" nowrap>
    074:           <input type="submit" value="<< Before Page"><input type="hidden" name="REQ_KIND" value="BEFOR">
    075:         </td>
    076:       </form>
    077:       <form name="orderform2" method="POST" action="show.do">
    078:         <td width="30%" nowrap>
    079:           <input type="submit" value="Next Page    >>"><input type="hidden" name="REQ_KIND" value="NEXT">
    080:         </td>
    081:       </form>
    082:     </tr>
    083: 
    084:     <tr>
    085:       <td COLSPAN="2" width="670" >
    086:         <table border="0" width="100%">
    087:           <tr>
    088:             <th nowrap width="20%" bgcolor="#FF8F20"><bean:message key="word.product"/></th>
    089:             <th nowrap width="20%" bgcolor="#FF8F20"><bean:message key="word.prdname"/></th>
    090:             <th nowrap width="15%" bgcolor="#FF8F20"><bean:message key="word.price"/></th>
    091:             <th nowrap width="10%" bgcolor="#FF8F20"><bean:message key="word.stoks"/></th>
    092:             <th nowrap width="10%" bgcolor="#FF8F20"><bean:message key="word.ordernum"/></th>
    093:             <th nowrap width="15%" bgcolor="#FF8F20"><bean:message key="word.subtotal"/></th>
    094:           </tr>
    095: <%        for(int cnt=0; cnt < _shownum; cnt++) {
    096:               _objInteger = (Integer)_orderdata.get(_showproduct[cnt]);
    097:               if( _objInteger != null ) {
    098:                   _ordernum = _objInteger.intValue();
    099:               } else {
    100:                   _ordernum = 0;
    101:               }                                                                                 %>
    102:               <tr>
    103:                 <td nowrap width="20%" bgcolor="#FFE9D2" align="center"><%=_showproduct[cnt]%></td>
    104:                 <td nowrap width="20%" bgcolor="#FFE9D2"><%=_showprodname[cnt]%></td>
    105:                 <td nowrap width="15%" bgcolor="#FFE9D2" align="right"><%=_showprice[cnt]%></td>
    106:                 <td nowrap width="10%" bgcolor="#FFE9D2" align="right"><%=_showstoks[cnt]%></td>
    107:                 <form name="orderform3" method="POST" action="show.do">
    108:                     <td nowrap width="10%" bgcolor="#FFE9D2">
    109:                       <div align="center"><p><input NAME="REQ_VALUE2" TYPE="text" SIZE="3" align="right" 
    110:                                               value="<%=_ordernum%>"  onChange="fncchange(this.form)"></div>
    111:                     </td>
    112:                     <td nowrap width="15%" bgcolor="#FFE9D2" align="right">
    113:                         <%=new Long(_ordernum*_showprice[cnt].longValue())%></td>
    114:                     <td nowrap width="0%">
    115:                         <input name="REQ_KIND" type="hidden" value="SETORDER"></td>
    116:                     <td nowrap width="0%">
    117:                         <input name="REQ_VALUE1" type="hidden" value="<%=_showproduct[cnt]%>"></td>
    118:                 </form>
    119:               </tr>                                                                             <%
    120:           }                                                                                     %>
    121:         </table>
    122:       </td>
    123:     </tr>
    124:     <tr height="16"><td></td></tr>
    125:       <tr>
    126:         <td COLSPAN="2" >
    127:           <table border="0" width="100%" height="16">
    128:             <td nowrap width="25%" method="POST" height="16">
    129:               <form name="orderform4" action="order.do">
    130:                 <input type="submit" size="150" value="<bean:message key="order.button1"/>"/>
    131:               </form>
    132:             </td>
    133:             <td nowrap width="75%" height="16" align="left">
    134:               <form name="orderform5" method="POST" action="show.do">
    135:                 <input type="submit" size="150" value="<bean:message key="order.button2"/>"/>
    136:                 <input type="hidden" name="REQ_KIND" value="ORDERLIST">
    137:               </form>
    138:             </td>
    139:           </table>
    140:         </td>
    141:       </tr>
    142:   </table>
    143:   </div></center>                                                                                 <%
    144: }                                                                                                 %>
    145: <form name="form2" METHOD="POST" ACTION="entryEnd.jsp">
    146:     <div align="right">
    147:         <input type="submit" value="<bean:message key="logon.button2"/>"/>
    148:     </div>
    149: </form>
    150: 
    151: <hr align="center">
    152: </body>
    153: </html:html>
    <EOF>

    2.3.4. 発注一覧表示画面

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

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

    3) 使用しているStruts機能

    発注一覧表示画面(orderlist.jsp)のソースを次に表示します。
    000: <%@ page import="java.util.Hashtable" contentType="text/html;charset=UTF-8"%>
    001: <%@ taglib uri="WEB-INF/struts-bean.tld"  prefix="bean" %>
    002: <%@ taglib uri="WEB-INF/struts-html.tld"  prefix="html" %>
    003: 
    004: <html:html locale="true">
    005: <head>
    006:   <title><bean:message key="order.wtitle"/></title>
    007:   <SCRIPT LANGUAGE="JavaScript">
    008:     function fncchange(f){
    009:         f.submit();
    010:     }
    011:   </SCRIPT>
    012:   <html:base/>
    013: </head>
    014: <body bgcolor="#B0FFB0">
    015: 
    016: <html:errors/><br><br>
    017: 
    018: <CENTER><DIV style="background-color:#363562; width:90%; border-style :outset" align=center>
    019:     <font size=42 color=white face="arial"><bean:message key="system.title"/></font>
    020: </DIV></CENTER>
    021: <br>
    022: 
    023: <%
    024:     boolean errChk    = false;
    025:     String  _shop     = null;
    026:     String  _clerk    = null;
    027:     String  _orderno  = null;
    028:     int     _ordernum = 0;
    029:     int     _shownum  = 0;
    030: 
    031:     String[] logonInfo = (String[])pageContext.getAttribute( "AttrLogOnInfo", pageContext.SESSION_SCOPE );
    032:     if( logonInfo == null ) {
    033:         errChk = true;
    034:     } else {
    035:         _shop       = logonInfo[0];
    036:         _clerk      = logonInfo[1];
    037:         _orderno    = logonInfo[2];
    038:     }
    039: 
    040:     Integer _objInteger    = (Integer)pageContext.getAttribute( "AttrShowNum", pageContext.SESSION_SCOPE );
    041:     String[] _showproduct  = (String[])pageContext.getAttribute( "AttrShowProduct", pageContext.SESSION_SCOPE );
    042:     String[] _showprodname = (String[])pageContext.getAttribute( "AttrShowProdName", pageContext.SESSION_SCOPE );
    043:     Long[] _showprice      = (Long[])pageContext.getAttribute( "AttrShowPrice", pageContext.SESSION_SCOPE );
    044:     Long[] _showstoks      = (Long[])pageContext.getAttribute( "AttrShowStoks", pageContext.SESSION_SCOPE );
    045:     Hashtable _orderdata   = (Hashtable)pageContext.getAttribute("AttrOrderData", pageContext.SESSION_SCOPE );
    046:     if( _objInteger == null || _showproduct == null || _showprodname == null ||
    047:         _showprice == null  || _showstoks == null   || _orderdata == null ) {
    048:         errChk = true;
    049:     } else {
    050:         _shownum = _objInteger.intValue();
    051:     }
    052: %>
    053: 
    054:                                                                                                     <%
    055: if( errChk ) {                                                                                      %>
    056:     <center><bean:message key="error.system.paramerr"/></center>
    057:     <form name="form2" METHOD="POST" ACTION="entryEnd.jsp">
    058:         <div align="right">
    059:           <input type="submit" value="<bean:message key="logon.button2"/>"/>
    060:         </div>
    061:     </form>
    062:                                                                                                     <%
    063: } else {                                                                                            %>
    064:     <center><div align="center">
    065:     <table border="0" width="678">
    066:         <tr>
    067:           <td width="10%" nowrap><small><strong><bean:message key="word.orderno"/></strong></small></td>
    068:           <td width="90%"><small><strong>:</strong><%=_orderno%></small></td>
    069:         </tr>
    070:         <tr>
    071:           <td width="10%" nowrap><small><strong><bean:message key="word.branch"/></strong></small></td>
    072:           <td width="90%"><small><strong>:</strong><%=_shop%></small></td>
    073:         </tr>
    074:         <tr>
    075:           <td width="10%" nowrap><small><strong><bean:message key="word.charge"/></strong></small></td>
    076:           <td width="90%"><small><strong>:</strong><%=_clerk%></small></td>
    077:         </tr>
    078:     </table><br>
    079:     <table border="0" width="678">
    080:         <tr>
    081:           <td COLSPAN="2" width="670" >
    082:             <table border="0" width="100%">
    083:               <tr>
    084:                 <th nowrap width="20%" bgcolor="#FF8F20"><bean:message key="word.product"/></th>
    085:                 <th nowrap width="20%" bgcolor="#FF8F20"><bean:message key="word.prdname"/></th>
    086:                 <th nowrap width="15%" bgcolor="#FF8F20"><bean:message key="word.price"/></th>
    087:                 <th nowrap width="10%" bgcolor="#FF8F20"><bean:message key="word.stoks"/></th>
    088:                 <th nowrap width="10%" bgcolor="#FF8F20"><bean:message key="word.ordernum"/></th>
    089:                 <th nowrap width="15%" bgcolor="#FF8F20"><bean:message key="word.subtotal"/></th>
    090:               </tr>
    091:                                                                                                     <%
    092:               for(int cnt=0; cnt < _shownum; cnt++) {
    093:                   _objInteger = (Integer)_orderdata.get(_showproduct[cnt]);
    094:                   if( _objInteger != null ) {
    095:                       _ordernum = _objInteger.intValue();
    096:                   } else {
    097:                       _ordernum = 0;
    098:                   }                                                                                 %>
    099:                   <tr>
    100:                     <td nowrap width="20%" bgcolor="#FFE9D2" align="center"><%=_showproduct[cnt]%></td>
    101:                     <td nowrap width="20%" bgcolor="#FFE9D2"><%=_showprodname[cnt]%></td>
    102:                     <td nowrap width="15%" bgcolor="#FFE9D2" align="right"><%=_showprice[cnt]%></td>
    103:                     <td nowrap width="10%" bgcolor="#FFE9D2" align="right"><%=_showstoks[cnt]%></td>
    104:                     <td nowrap width="10%" bgcolor="#FFE9D2" align="right"><%=_ordernum%></td>
    105:                     <td nowrap width="15%" bgcolor="#FFE9D2" align="right"><%=new Long(_ordernum*_showprice[cnt].longValue())%></td>
    106:                   </tr>                                                                             <%
    107:               }                                                                                     %>
    108:             </table>
    109:           </td>
    110:         </tr>
    111:         <tr height="16"><td></td></tr>
    112:         <tr>
    113:           <td COLSPAN="2" >
    114:             <table border="0" width="100%" height="16">
    115:               <td nowrap width="75%" height="16" align="center">
    116:                 <form name="form13" method="POST" action="show.do">
    117:                   <input type="submit" size="150" value="<bean:message key="orderlist.button1"/>"/>
    118:                   <input type="hidden" name="REQ_KIND" value="RESHOW">
    119:                 </form>
    120:               </td>
    121:             </table>
    122:           </td>
    123:         </tr>
    124:     </table>
    125:     </div></center>                                                                                <%
    126: }                                                                                                   %>
    127: 
    128: <br>
    129: <hr align="center">
    130: </body>
    131: </html:html>
    <EOF>

    2.3.5. 発注結果表示画面

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

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

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

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

    発注結果表示画面(entryResult.jsp)のソースを次に表示します。
    000: <%@ page language="java" contentType="text/html;charset=UTF-8"%>
    001: <%@ page import="java.util.*" %>
    002: <%@ taglib uri="WEB-INF/struts-bean.tld"  prefix="bean" %>
    003: <%@ taglib uri="WEB-INF/struts-html.tld"  prefix="html" %>
    004: 
    005: <html:html locale="true">
    006: <head>
    007: <title><bean:message key="end.wtitle"/></title>
    008: <html:base/>
    009: </head>
    010: <body bgcolor="#B0FFB0">
    011: 
    012: <CENTER><DIV style="background-color:#363562; width:90%; border-style :outset" align=center>
    013:     <FONT size=42 color=white face="arial"><bean:message key="system.title"/></FONT>
    014: </DIV></CENTER><br>
    015: <center>
    016: <html:errors/>
    017: </center>
    018: 
    019: <center>
    020:   <table border="0" width="678" >
    021:     <tr>
    022:       <td width="25%" height="18"></td>
    023:       <td width="75%" height="18" align="right"></td>
    024:     </tr>
    025: 
    026:     <tr>
    027:       <td width="20%" ></td>
    028:       <td valign="top" width="80%" nowrap >
    029:         <table border="0"  width="100%" height="16">
    030:           <td nowrap width="35%" height="16">
    031:             <form name="form1" action="order.jsp">
    032:                 <input type="submit" border="0" width="125" value="Order Page"/>
    033:             </form>
    034:           </td>
    035:           <td nowrap width="65%" height="16">
    036:             <form name="form2" action="entryEnd.jsp">
    037:                 <input type="submit" border="0" width="125" value="Entry End Page"/>
    038:             </form>
    039:           </td>
    040:         </table>
    041:       </td>
    042:     </tr>
    043:   </table>
    044: </center>
    045: 
    046: <hr>
    047: </body>
    048: </html:html>
    <EOF>

    2.3.6. 発注完了画面

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

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

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

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

    発注完了画面(entryEnd.jsp)のソースを次に表示します。
    000: <%@ page language="java" contentType="text/html;charset=UTF-8"%>
    001: <%@ taglib uri="WEB-INF/struts-bean.tld"  prefix="bean" %>
    002: <%@ taglib uri="WEB-INF/struts-html.tld"  prefix="html" %>
    003: 
    004: <html:html locale="true">
    005: <head>
    006: <title><bean:message key="end.wtitle"/></title>
    007: <html:base/>
    008: </head>
    009: <body bgcolor="#B0FFB0">
    010: 
    011: <html:errors/><br><br>
    012: 
    013: <%
    014:     // Attribute Info clear
    015:     pageContext.removeAttribute( "AttrLogOnInfo",    pageContext.SESSION_SCOPE );
    016:     pageContext.removeAttribute( "AttrShowNum",      pageContext.SESSION_SCOPE );
    017:     pageContext.removeAttribute( "AttrShowProduct",  pageContext.SESSION_SCOPE );
    018:     pageContext.removeAttribute( "AttrShowProdName", pageContext.SESSION_SCOPE );
    019:     pageContext.removeAttribute( "AttrShowPrice",    pageContext.SESSION_SCOPE );
    020:     pageContext.removeAttribute( "AttrShowStoks",    pageContext.SESSION_SCOPE );
    021:     pageContext.removeAttribute( "AttrOrderData",    pageContext.SESSION_SCOPE );
    022:     pageContext.removeAttribute( "AttrTotalRec",     pageContext.SESSION_SCOPE );
    023:     pageContext.removeAttribute( "AttrNowPage",      pageContext.SESSION_SCOPE );
    024: %>
    025: 
    026: <CENTER><DIV style="background-color:#363562; width:90%; border-style :outset" align=center>
    027:     <FONT size=42 color=white face="arial"><bean:message key="system.title"/></FONT>
    028: </DIV></CENTER><br>
    029: 
    030: <center>
    031:   <table border="0" width="678" height="184">
    032:     <tr>
    033:       <td width="20%" height="18"></td>
    034:       <td width="80%" height="18" align="right"></td>
    035:     </tr>
    036: 
    037:     <tr><td></td><td><bean:message key="end.message1"/></td></tr>
    038: 
    039:     <tr>
    040:       <td width="20%" ></td>
    041:       <td valign="top" width="80%" nowrap >
    042:         <table border="0"  width="100%" height="16">
    043:           <td nowrap width="35%" height="16">
    044:             <form name="form1" action="logon.jsp">
    045:                 <input type="submit" border="0" width="125" value="LogOn Page"/>
    046:             </form>
    047:           </td>
    048:           <td nowrap width="65%" height="16">
    049:             <form name="form2" action="index.html">
    050:                 <input type="submit" border="0" width="125" value="Index Page"/>
    051:             </form>
    052:           </td>
    053:         </table>
    054:       </td>
    055:     </tr>
    056:   </table>
    057: </center>
    058: 
    059: <hr>
    060: </body>
    061: </html:html>
    <EOF>

    2.4. アプリケーションクラスの作成

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

    2.4.1. ログオンForm

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

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

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

    ログオンForm(LogonForm.class)のソースを次に表示します。
    000: 
    001: package jp.co.nec.WebOTX.StrutsSample;
    002: 
    003: import javax.servlet.http.HttpServletRequest;
    004: import org.apache.struts.action.ActionError;
    005: import org.apache.struts.action.ActionErrors;
    006: import org.apache.struts.action.ActionForm;
    007: import org.apache.struts.action.ActionMapping;
    008: 
    009: /**
    010:  * Form bean for the user profile page.  This form has the following fields,
    011:  * with default values in square brackets:
    012:  * <ul>
    013:  * <li><b>password</b> - Entered password value
    014:  * <li><b>username</b> - Entered username value
    015:  * </ul>
    016:  *
    017:  * @author Craig R. McClanahan
    018:  * @version $Revision: 1.2 $ $Date: 2001/04/14 12:53:08 $
    019:  */
    020: 
    021: public final class LogonForm extends ActionForm {
    022: 
    023:     // --------------------------------------------------- Instance Variables
    024: 
    025:     /**
    026:      * The password.
    027:      */
    028:     private String password = null;
    029: 
    030:     /**
    031:      * The username.
    032:      */
    033:     private String username = null;
    034: 
    035:     // ----------------------------------------------------------- Properties
    036:     /**
    037:      * Return the password.
    038:      */
    039:     public String getPassword() {
    040:         return (this.password);
    041:     }
    042: 
    043:     /**
    044:      * Set the password.
    045:      *
    046:      * @param password The new password
    047:      */
    048:     public void setPassword(String password) {
    049:         this.password = password;
    050:     }
    051: 
    052:     /**
    053:      * Return the username.
    054:      */
    055:     public String getUsername() {
    056:         return (this.username);
    057:     }
    058: 
    059:     /**
    060:      * Set the username.
    061:      *
    062:      * @param username The new username
    063:      */
    064:     public void setUsername(String username) {
    065:         this.username = username;
    066:     }
    067:     // --------------------------------------------------------- Public Methods
    068: 
    069:     /**
    070:      * Reset all properties to their default values.
    071:      * @param mapping The mapping used to select this instance
    072:      * @param request The servlet request we are processing
    073:      */
    074:     public void reset(ActionMapping mapping, HttpServletRequest request) {
    075:         this.password = null;
    076:         this.username = null;
    077:     }
    078: 
    079:     /**
    080:      * Validate the properties that have been set from this HTTP request,
    081:      * and return an <code>ActionErrors</code> object that encapsulates any
    082:      * validation errors that have been found.  If no errors are found, return
    083:      * <code>null</code> or an <code>ActionErrors</code> object with no
    084:      * recorded error messages.
    085:      *
    086:      * @param mapping The mapping used to select this instance
    087:      * @param request The servlet request we are processing
    088:      */
    089:     public ActionErrors validate(ActionMapping mapping,
    090:                                  HttpServletRequest request) {
    091:         ActionErrors errors = new ActionErrors();
    092:         if ((username == null) || (username.length() < 1))
    093:             errors.add("username", new ActionError("error.username.required"));
    094:         if ((password == null) || (password.length() < 1))
    095:             errors.add("password", new ActionError("error.password.required"));
    096: 
    097:         return errors;
    098:     }
    099: }
    <EOF>

    2.4.2. ログオンAction

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

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

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

    ログオンAction(LogonAction.class)のソースを次に表示します。
    000: 
    001: package jp.co.nec.WebOTX.StrutsSample;
    002: 
    003: import java.io.*;
    004: import java.sql.Timestamp;
    005: import java.text.DateFormat;
    006: import java.text.SimpleDateFormat;
    007: 
    008: import java.util.Locale;
    009: import java.util.Hashtable;
    010: import javax.servlet.http.HttpServletRequest;
    011: import javax.servlet.http.HttpSession;
    012: import javax.servlet.http.HttpServletResponse;
    013: import javax.servlet.*;
    014: import org.apache.struts.action.Action;
    015: import org.apache.struts.action.ActionError;
    016: import org.apache.struts.action.ActionErrors;
    017: import org.apache.struts.action.ActionForm;
    018: import org.apache.struts.action.ActionForward;
    019: import org.apache.struts.action.ActionMapping;
    020: //import org.apache.struts.util.AppException;
    021: import org.apache.struts.util.MessageResources;
    022: //import org.apache.commons.beanutils.PropertyUtils;
    023: 
    024: import java.sql.*;
    025: import java.util.Vector;
    026: 
    027: public final class LogonAction extends Action {
    028:     // ----------------------------------------------------- Instance Variables
    029: 
    030:     /**
    031:      * The <code>Log</code> instance for this application.
    032:      */
    033: //    private Log log =
    034: //        LogFactory.getLog("struts.sample");
    035: 
    036:     // --------------------------------------------------------- Public Methods
    037: 
    038:     /**
    039:      * Process the specified HTTP request, and create the corresponding HTTP
    040:      * response (or forward to another web component that will create it).
    041:      * Return an <code>ActionForward</code> instance describing where and how
    042:      * control should be forwarded, or <code>null</code> if the response has
    043:      * already been completed.
    044:      *
    045:      * @param mapping The ActionMapping used to select this instance
    046:      * @param actionForm The optional ActionForm bean for this request (if any)
    047:      * @param request The HTTP request we are processing
    048:      * @param response The HTTP response we are creating
    049:      *
    050:      * @exception Exception if business logic throws an exception
    051:      */
    052:     public ActionForward perform(ActionMapping mapping,
    053: //    public ActionForward execute(ActionMapping mapping,    
    054:                                  ActionForm form,
    055:                                  HttpServletRequest request,
    056:                                  HttpServletResponse response)
    057:         throws IOException, ServletException {
    058: 
    059:         // Extract attributes we will need
    060:         Locale locale = getLocale(request);
    061:         MessageResources messages = getResources();
    062: 
    063:         // Validate the request parameters specified by the user
    064:         ActionErrors errors = new ActionErrors();
    065: 
    066:         GenericServlet pservlet = (GenericServlet)getServlet();
    067:         ServletContext servcon = pservlet.getServletContext();
    068:         HttpSession session = request.getSession();
    069: 
    070: 
    071:         String user = request.getParameter("username");
    072:         String pass = request.getParameter("password");
    073: 
    074:         String[] dbInfo = null;  // DB接続情報
    075:         String dbDriver = null;  // JDBCドライバ名
    076:         String dbUrl    = null;  // DBへのURL
    077:         String dbUserid = null;  // ユーザ名
    078:         String dbPasswd = null;  // パスワード
    079: 
    080:         dbInfo = (String[])session.getAttribute( "AttrDBInfo" );
    081:         if( dbInfo == null ) {
    082:             dbInfo = new String[4];
    083: 
    084:             dbInfo[0] = dbDriver = servcon.getInitParameter( "dbDriver" );
    085:             dbInfo[1] = dbUrl    = servcon.getInitParameter( "dbURL" );
    086:             dbInfo[2] = dbUserid = servcon.getInitParameter( "dbUserId" );
    087:             dbInfo[3] = dbPasswd = servcon.getInitParameter( "dbPassword" );
    088: 
    089:             session.setAttribute( "AttrDBInfo", dbInfo );
    090:         } else {
    091:             dbDriver = dbInfo[0];
    092:             dbUrl    = dbInfo[1];
    093:             dbUserid = dbInfo[2];
    094:             dbPasswd = dbInfo[3];
    095:         }
    096: 
    097:         Connection conn = null;
    098:         Statement  stmt = null;
    099:         ResultSet  rset = null;
    100: 
    101:         // 在庫テーブルのコネクション生成
    102:         try {
    103:             Class.forName( dbDriver );
    104:             conn = DriverManager.getConnection( dbUrl, dbUserid, dbPasswd );
    105:             stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
    106:         } catch (Exception e) {  //SQLException / ClassNotFoundException / Exception
    107:             try {  // DB Objectクローズ
    108:                 if( stmt != null ) {  stmt.close();  }
    109:                 if( conn != null ) {  conn.close();  }
    110:             } catch(SQLException se) {  }
    111:             throw new ServletException(e.toString());
    112:         }
    113: 
    114:         Vector UserInfo = new Vector();
    115:         try {
    116:             String sqlStr = "SELECT * FROM WEBCONT_USERINFO";
    117:             rset = stmt.executeQuery( sqlStr );
    118:             for( ; rset.next()==true; ) {
    119:                 String userinfo[] = new String[3];
    120:                 userinfo[0] = rset.getString( 1 ).trim();
    121:                 userinfo[1] = rset.getString( 2 ).trim();
    122:                 userinfo[2] = rset.getString( 3 ).trim();
    123:                 UserInfo.add( userinfo );
    124:             }
    125:             rset.close();
    126:         } catch (Exception e) {  //SQLException
    127:             throw new ServletException(e.toString());
    128:         }
    129: 
    130:         boolean boo = false;
    131:         String logoninfo[] = new String[3];
    132:         for( int cnt = 0; cnt < UserInfo.size(); cnt++ ) {
    133:             String userinfo[] = (String[])UserInfo.get( cnt );
    134:             if( userinfo[0].equals(user) && userinfo[1].equals(pass) ) {
    135:                 logoninfo[0] = userinfo[2];
    136:                 logoninfo[1] = userinfo[0];
    137:                 Timestamp times = new Timestamp(System.currentTimeMillis());
    138:                 DateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmss");
    139:                 logoninfo[2] = userinfo[2] + "-" +  userinfo[0] + "-" + fmt.format(times);
    140:                 boo = true;
    141:                 session.setAttribute( "AttrLogOnInfo", logoninfo );
    142:             }
    143:         }
    144: 
    145:         if( !boo ) {
    146:             errors.add(ActionErrors.GLOBAL_ERROR,
    147:                            new ActionError("error.logon.err", "logon error(user or pass)" ));
    148:             saveErrors(request, errors);
    149:             return (new ActionForward(mapping.getInput()));
    150:         }
    151: 
    152:         session.setAttribute( "AttrOrderData", new Hashtable() );
    153: 
    154:         try {
    155:             EditShowData edShowData = new EditShowData( servcon, request );
    156:             session.setAttribute( "AttrNowPage", new Integer(1));
    157:             edShowData.getShowData( request );
    158:         } catch (IOException ie) {
    159:             errors.add(ActionErrors.GLOBAL_ERROR,
    160:                            new ActionError("error.logon.dberr", ie.toString() ));
    161:             saveErrors(request, errors);
    162:             return (new ActionForward(mapping.getInput()));
    163:         }
    164: 
    165:         // Forward control to the specified success URI
    166:         return mapping.findForward( "success" );
    167:     }
    168: }
    <EOF>

    2.4.3. データ表示Action

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

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

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

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

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

    データ表示Action(ShowDataAction.class)のソースを次に表示します。
    000: 
    001: package jp.co.nec.WebOTX.StrutsSample;
    002: 
    003: import java.io.*;
    004: import java.util.Hashtable;
    005: import java.sql.Timestamp;
    006: import java.text.DateFormat;
    007: import java.text.SimpleDateFormat;
    008: 
    009: import java.util.Locale;
    010: import javax.servlet.http.HttpServletRequest;
    011: import javax.servlet.http.HttpSession;
    012: import javax.servlet.http.HttpServletResponse;
    013: import javax.servlet.*;
    014: import org.apache.struts.action.Action;
    015: import org.apache.struts.action.ActionError;
    016: import org.apache.struts.action.ActionErrors;
    017: import org.apache.struts.action.ActionForm;
    018: import org.apache.struts.action.ActionForward;
    019: import org.apache.struts.action.ActionMapping;
    020: //import org.apache.struts.util.AppException;
    021: import org.apache.struts.util.MessageResources;
    022: //import org.apache.commons.beanutils.PropertyUtils;
    023: 
    024: /**
    025:  * Implementation of <strong>Action</strong> that validates a user logon.
    026:  *
    027:  * @author Craig R. McClanahan
    028:  * @version $Revision: 1.10 $ $Date: 2002/07/05 22:09:20 $
    029:  */
    030: public final class ShowAction extends Action {
    031: 
    032:     // ----------------------------------------------------- Instance Variables
    033: 
    034:     /**
    035:      * The <code>Log</code> instance for this application.
    036:      */
    037: 
    038:     // --------------------------------------------------------- Public Methods
    039: 
    040:     /**
    041:      * Process the specified HTTP request, and create the corresponding HTTP
    042:      * response (or forward to another web component that will create it).
    043:      * Return an <code>ActionForward</code> instance describing where and how
    044:      * control should be forwarded, or <code>null</code> if the response has
    045:      * already been completed.
    046:      *
    047:      * @param mapping The ActionMapping used to select this instance
    048:      * @param actionForm The optional ActionForm bean for this request (if any)
    049:      * @param request The HTTP request we are processing
    050:      * @param response The HTTP response we are creating
    051:      *
    052:      * @exception Exception if business logic throws an exception
    053:      */
    054:     public ActionForward perform(ActionMapping mapping,
    055:                                  ActionForm form,
    056:                                  HttpServletRequest request,
    057:                                  HttpServletResponse response)
    058:         throws IOException, ServletException {
    059: 
    060:         // Extract attributes we will need
    061:         Locale locale = getLocale(request);
    062:         MessageResources messages = getResources();
    063: 
    064:         // Validate the request parameters specified by the user
    065:         ActionErrors errors = new ActionErrors();
    066: 
    067:         GenericServlet pservlet = (GenericServlet)getServlet();
    068:         ServletContext servcon = pservlet.getServletContext();
    069:         HttpSession session = request.getSession();
    070:         String reqKind   = request.getParameter("REQ_KIND");
    071: 
    072:         if( reqKind.equals("SETORDER")) {
    073:             String reqValue1 = request.getParameter("REQ_VALUE1");
    074:             String reqValue2 = request.getParameter("REQ_VALUE2");
    075:             Integer objInteger = null;
    076: 
    077:             if( reqValue1 == null || reqValue2 == null ) {
    078:                 errors.add(ActionErrors.GLOBAL_ERROR,
    079:                                new ActionError("error.show.paramerr", reqValue1, reqValue2));
    080:                 saveErrors(request, errors);
    081:                 return (new ActionForward(mapping.getInput()));
    082:             }
    083: 
    084:             try {
    085:                 objInteger = new Integer( reqValue2 );
    086:             } catch(Exception e) {
    087:                 errors.add(ActionErrors.GLOBAL_ERROR,
    088:                                new ActionError("error.show.numerr", reqValue2));
    089:                 saveErrors(request, errors);
    090:                 return (new ActionForward(mapping.getInput()));
    091:             }
    092: 
    093:             Hashtable orderData = (Hashtable)session.getAttribute("AttrOrderData");
    094:             if( orderData == null ) {
    095:                 orderData = new Hashtable();
    096:             }
    097: 
    098:             if( objInteger.intValue() == 0 ) {
    099:                 orderData.remove( reqValue1 );
    100:             } else {
    101:                 orderData.put( reqValue1, objInteger );
    102:             }
    103:             session.setAttribute("AttrOrderData", orderData);
    104:         } else if( reqKind.equals("NEXT")) {
    105:             Integer nowPage  = (Integer)session.getAttribute("AttrNowPage");
    106:             Long totalRec = (Long)session.getAttribute("AttrTotalRec");
    107:             int nowRec = ((nowPage.intValue()-1)*5)+1;
    108:             if( (nowRec + 5) <= totalRec.intValue() ) {
    109:                 // 次のページに表示するデータ有
    110:                 nowPage = new Integer(nowPage.intValue()+1);
    111:                 // 表示ページ数更新
    112:                 session.setAttribute( "AttrNowPage", nowPage );
    113:             }
    114: 
    115:             try {
    116:                 EditShowData edShowData = new EditShowData( servcon,request );
    117:                 edShowData.getShowData( request );
    118:             } catch (IOException ie) {
    119:                 errors.add(ActionErrors.GLOBAL_ERROR,
    120:                            new ActionError("error.show.dberr", ie.toString() ));
    121:                 saveErrors(request, errors);
    122:                 return (new ActionForward(mapping.getInput()));
    123:             }
    124:         } else if( reqKind.equals("BEFOR")) {
    125:             Integer objInteger = (Integer)session.getAttribute("AttrNowPage");
    126:             int nowPage = objInteger.intValue();
    127:             if( (nowPage - 1) >= 1 ) {
    128:                 // 戻るページ有
    129:                 nowPage = nowPage - 1;
    130:                 // 表示ページ数更新
    131:                 session.setAttribute( "AttrNowPage", new Integer(nowPage) );
    132:             }
    133: 
    134:             try {
    135:                 EditShowData edShowData = new EditShowData( servcon, request );
    136:                 edShowData.getShowData( request );
    137:             } catch (IOException ie) {
    138:                 errors.add(ActionErrors.GLOBAL_ERROR,
    139:                            new ActionError("error.show.dberr", ie.toString() ));
    140:                 saveErrors(request, errors);
    141:                 return (new ActionForward(mapping.getInput()));
    142:             }
    143:         } else if( reqKind.equals("ORDERLIST")) {
    144:             try {
    145:                 EditShowData edShowData = new EditShowData( servcon, request );
    146:                 edShowData.getListData( request );
    147:             } catch (IOException ie) {
    148:                 errors.add(ActionErrors.GLOBAL_ERROR,
    149:                            new ActionError("error.show.dberr", ie.toString() ));
    150:                 saveErrors(request, errors);
    151:                 return (new ActionForward(mapping.getInput()));
    152:             }
    153: 
    154:             // 一覧表示画面へ
    155:             return (mapping.findForward("orderlist"));
    156:         } else if( reqKind.equals("RESHOW")) {
    157:             try {
    158:                 EditShowData edShowData = new EditShowData( servcon, request );
    159:                 edShowData.getShowData( request );
    160:             } catch (IOException ie) {
    161:                 errors.add(ActionErrors.GLOBAL_ERROR,
    162:                            new ActionError("error.show.dberr", ie.toString() ));
    163:                 saveErrors(request, errors);
    164:                 return (new ActionForward(mapping.getInput()));
    165:             }
    166:         } else {
    167:             errors.add(ActionErrors.GLOBAL_ERROR,
    168:                            new ActionError("error.show.kinderr", reqKind));
    169:             saveErrors(request, errors);
    170:             return (new ActionForward(mapping.getInput()));
    171:         }
    172: 
    173:         // Forward control to the specified success URI
    174:         return mapping.findForward( "success" );
    175:     }
    176: }
    <EOF>

    2.4.4. 発注処理Action

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

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

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

    発注処理Action(OrderAction.class)のソースを次に表示します。
    000: 
    001: package jp.co.nec.WebOTX.StrutsSample;
    002: 
    003: import java.sql.Timestamp;
    004: import java.text.DateFormat;
    005: import java.text.SimpleDateFormat;
    006: 
    007: import java.io.*;
    008: import java.util.Locale;
    009: import java.util.*;
    010: import javax.servlet.http.HttpServletRequest;
    011: import javax.servlet.http.HttpSession;
    012: import javax.servlet.http.HttpServletResponse;
    013: import javax.servlet.*;
    014: //import org.apache.commons.logging.Log;
    015: //import org.apache.commons.logging.LogFactory;
    016: import org.apache.struts.action.Action;
    017: import org.apache.struts.action.ActionError;
    018: import org.apache.struts.action.ActionErrors;
    019: import org.apache.struts.action.ActionForm;
    020: import org.apache.struts.action.ActionForward;
    021: import org.apache.struts.action.ActionMapping;
    022: //import org.apache.struts.util.AppException;
    023: import org.apache.struts.util.MessageResources;
    024: //import org.apache.commons.beanutils.PropertyUtils;
    025: 
    026: /**
    027:  * Implementation of <strong>Action</strong> that validates a user logon.
    028:  *
    029:  * @author Craig R. McClanahan
    030:  * @version $Revision: 1.10 $ $Date: 2002/07/05 22:09:20 $
    031:  */
    032: public final class OrderAction extends Action {
    033: 
    034:     // ----------------------------------------------------- Instance Variables
    035: 
    036:     /**
    037:      * The <code>Log</code> instance for this application.
    038:      */
    039: //    private Log log =
    040: //        LogFactory.getLog("struts.sample");
    041: 
    042:     // --------------------------------------------------------- Public Methods
    043: 
    044:     /**
    045:      * Process the specified HTTP request, and create the corresponding HTTP
    046:      * response (or forward to another web component that will create it).
    047:      * Return an <code>ActionForward</code> instance describing where and how
    048:      * control should be forwarded, or <code>null</code> if the response has
    049:      * already been completed.
    050:      *
    051:      * @param mapping The ActionMapping used to select this instance
    052:      * @param actionForm The optional ActionForm bean for this request (if any)
    053:      * @param request The HTTP request we are processing
    054:      * @param response The HTTP response we are creating
    055:      *
    056:      * @exception Exception if business logic throws an exception
    057:      */
    058:     public ActionForward perform(ActionMapping mapping,
    059:                                  ActionForm form,
    060:                                  HttpServletRequest request,
    061:                                  HttpServletResponse response)
    062:         throws IOException, ServletException {
    063: 
    064:         // Extract attributes we will need
    065:         Locale locale = getLocale(request);
    066:         MessageResources messages = getResources();
    067: 
    068:         // Validate the request parameters specified by the user
    069:         ActionErrors errors = new ActionErrors();
    070: 
    071:         GenericServlet pservlet = (GenericServlet)getServlet();
    072:         ServletContext servcon = pservlet.getServletContext();
    073:         HttpSession session = request.getSession();
    074: 
    075:         try{
    076:             DBOrderData dbOrder = new DBOrderData( servcon, request );
    077:             dbOrder.errorData.clear();
    078:             dbOrder.entryData( request );
    079: 
    080:             if( dbOrder.errorData.size() > 0 ) {
    081:                 session.setAttribute("AttrOrderData", dbOrder.errorData);
    082:                 Enumeration enu = dbOrder.errorData.keys();
    083:                 for( ; enu.hasMoreElements() ; ) {
    084:                     String  keyname  = (String)enu.nextElement();
    085:                     Integer ordernum = (Integer)dbOrder.errorData.get(keyname);
    086: 
    087:                     errors.add(ActionErrors.GLOBAL_ERROR,
    088:                            new ActionError("error.order.orderNum", keyname, ordernum));
    089:                     saveErrors(request, errors);
    090:                 }
    091:                 return mapping.findForward("result");
    092:             }
    093:         } catch(Exception e) {
    094:             errors.add(ActionErrors.GLOBAL_ERROR,
    095:                        new ActionError("error.order.dberr", e.toString()));
    096:             saveErrors(request, errors);
    097:             return mapping.findForward("end");
    098:         }
    099: 
    100:         // Forward control to the specified success URI
    101:         return mapping.findForward("end");
    102: 
    103:     }
    104: }
    <EOF>

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

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

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

    表示データ編集処理(EditShowData.class)のソースを次に表示します。
    000: 
    001: package jp.co.nec.WebOTX.StrutsSample;
    002: 
    003: import javax.servlet.http.HttpServletRequest;
    004: import javax.servlet.http.HttpSession;
    005: import javax.servlet.http.HttpServletResponse;
    006: import javax.servlet.*;
    007: 
    008: import java.io.*;
    009: import java.util.Hashtable;
    010: import java.util.Enumeration;
    011: import java.util.Arrays;
    012: import java.sql.*;
    013: import java.sql.Date.*;
    014: import java.sql.SQLException;
    015: 
    016: public final class EditShowData {
    017: 
    018:     // ----------------------------------------------------- Instance Variables
    019: 
    020:     /**
    021:      * The <code>Log</code> instance for this application.
    022:      */
    023:     String[] dbInfo = null;  // DB接続情報
    024:     String dbDriver = null;  // JDBCドライバ名
    025:     String dbUrl    = null;  // DBへのURL
    026:     String dbUserid = null;  // ユーザ名
    027:     String dbPasswd = null;  // パスワード
    028: 
    029:     public EditShowData( ServletContext servcon,
    030:                               HttpServletRequest request )
    031:             throws IOException {
    032: 
    033:         initDBInfo( servcon, request );
    034:     }
    035: 
    036:     // --------------------------------------------------------- Public Methods
    037: 
    038:     public void initDBInfo( ServletContext servcon,
    039:                             HttpServletRequest request )
    040:             throws IOException {
    041: 
    042:         Connection conn = null;
    043:         Statement  stmt = null;
    044:         ResultSet  rset = null;
    045:         HttpSession session = request.getSession();
    046: 
    047:         // DB情報の取得
    048:         dbInfo = (String[])session.getAttribute( "AttrDBInfo" );
    049:         if( dbInfo == null ) {
    050:             dbInfo = new String[4];
    051: 
    052:             dbInfo[0] = dbDriver = servcon.getInitParameter( "dbDriver" );
    053:             dbInfo[1] = dbUrl    = servcon.getInitParameter( "dbURL" );
    054:             dbInfo[2] = dbUserid = servcon.getInitParameter( "dbUserId" );
    055:             dbInfo[3] = dbPasswd = servcon.getInitParameter( "dbPassword" );
    056:             session.setAttribute( "AttrDBInfo", dbInfo );
    057:         } else {
    058:             dbDriver = dbInfo[0];
    059:             dbUrl    = dbInfo[1];
    060:             dbUserid = dbInfo[2];
    061:             dbPasswd = dbInfo[3];
    062:         }
    063: 
    064:         Long totalRec = (Long)session.getAttribute("AttrTotalRec");
    065:         if( totalRec != null ) {
    066:             return;
    067:         }
    068: 
    069:         // 在庫テーブルのコネクション生成
    070:         try {
    071:             Class.forName( dbDriver );
    072:             conn = DriverManager.getConnection( dbUrl, dbUserid, dbPasswd );
    073:             stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
    074:         } catch (Exception e) {  //SQLException / ClassNotFound / Exception
    075:             try {  // DB Objectクローズ
    076:                 if( stmt != null ) {  stmt.close();  }
    077:                 if( conn != null ) {  conn.close();  }
    078:             } catch(SQLException se) {  }
    079:             throw new IOException(e.toString());
    080:         }
    081: 
    082:         try {
    083:             // 在庫テーブルのレコード数抽出
    084:             rset = stmt.executeQuery("SELECT COUNT(*) from WEBCONT_WAREHOUSE");
    085:             rset.next();
    086:             long recNum = rset.getLong(1);
    087:             session.setAttribute("AttrTotalRec", new Long(recNum));
    088:         } catch (SQLException e) {
    089:             throw new IOException(e.toString());
    090:         } finally {
    091:             try {
    092:                 // DB Objectクローズ
    093:                 rset.close();
    094:                 stmt.close();
    095:                 conn.close();
    096:             } catch(SQLException se) {  }
    097:         }
    098:     }
    099: 
    100:     public void getShowData( HttpServletRequest request )
    101:             throws IOException {
    102: 
    103:         Connection conn = null;
    104:         Statement  stmt = null;
    105:         ResultSet  rset = null;
    106:         HttpSession session = request.getSession();
    107: 
    108:         // 在庫テーブルのコネクション生成
    109:         try {
    110:             Class.forName( dbDriver );
    111:             conn = DriverManager.getConnection( dbUrl, dbUserid, dbPasswd );
    112:             stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
    113:         } catch (Exception e) {  //SQLException / ClassNotFound / Exception
    114:             try {  // DB Objectクローズ
    115:                 if( stmt != null ) {  stmt.close();  }
    116:                 if( conn != null ) {  conn.close();  }
    117:             } catch(SQLException se) {  }
    118:             throw new IOException(e.toString());
    119:         }
    120: 
    121:         Integer nowPage  = null;  // 現在表示ページ
    122:         int     startRec = 0;     // 表示開始レコード
    123: 
    124:         // 表示開始レコード算出
    125:         nowPage = (Integer)session.getAttribute("AttrNowPage");
    126:         if( nowPage == null ) {
    127:             nowPage = new Integer(1);
    128:         }
    129:         startRec = 1 + ((nowPage.intValue()-1) * 5);
    130: 
    131:         String rset_c1     = null;  // 製品CD
    132:         String rset_c2     = null;  // 製品名
    133:         long   rset_c3     = 0;     // 単価
    134:         long   rset_c4     = 0;     // 在庫数
    135:         int    cnt         = 0;     // カウンタ
    136:         String attrName    = null;
    137:         Integer orderNum   = null;
    138: 
    139:         String[] product  = new String[5];
    140:         String[] prodname = new String[5];
    141:         Long[]   price    = new Long[5];
    142:         Long[]   stoks    = new Long[5];
    143: 
    144:         try {
    145:             // 在庫テーブルの抽出
    146:             rset = stmt.executeQuery( "SELECT * from WEBCONT_WAREHOUSE" );
    147:             // 開始レコードの設定
    148:             if (startRec == 1) {
    149:                 rset.beforeFirst();
    150:             } else {
    151:                 rset.absolute(startRec-1);
    152:             }
    153: 
    154:             // 表示データクリア
    155:             session.removeAttribute( "AttrShowNum" );
    156:             session.removeAttribute( "AttrShowProduct" );
    157:             session.removeAttribute( "AttrShowProdName" );
    158:             session.removeAttribute( "AttrShowPrice" );
    159:             session.removeAttribute( "AttrShowStoks" );
    160: 
    161:             for( cnt = 0; cnt < 5 && (rset.next()==true); cnt++) {
    162: 
    163:                 // 在庫データの取得
    164:                 rset_c1 = rset.getString(1);
    165:                 rset_c1 = rset_c1.trim();
    166:                 rset_c2 = rset.getString(2);
    167:                 rset_c2 = rset_c2.trim();
    168:                 rset_c3 = rset.getLong(3);
    169:                 rset_c4 = rset.getLong(4);
    170: 
    171:                 // 在庫データの設定
    172:                 product[cnt] = rset_c1;
    173:                 prodname[cnt] = rset_c2;
    174:                 price[cnt] = new Long(rset_c3);
    175:                 stoks[cnt] = new Long(rset_c4);
    176:             }
    177: 
    178:             session.setAttribute( "AttrShowNum", new Integer(cnt));
    179:             session.setAttribute( "AttrShowProduct", product );
    180:             session.setAttribute( "AttrShowProdName", prodname );
    181:             session.setAttribute( "AttrShowPrice", price );
    182:             session.setAttribute( "AttrShowStoks", stoks );
    183:         } catch (SQLException e) {
    184:             throw new IOException(e.toString());
    185:         } finally {
    186:             try {
    187:                 // DB Objectクローズ
    188:                 rset.close();
    189:                 stmt.close();
    190:                 conn.close();
    191:             } catch(SQLException se) {  }
    192:         }
    193: 
    194:         return;
    195:     }
    196: 
    197: 
    198:     public void getListData( HttpServletRequest request )
    199:             throws IOException {
    200: 
    201:         Connection conn = null;
    202:         Statement  stmt = null;
    203:         ResultSet  rset = null;
    204:         HttpSession session = request.getSession();
    205: 
    206:         // 在庫テーブルのコネクション生成
    207:         try {
    208:             Class.forName( dbDriver );
    209:             conn = DriverManager.getConnection( dbUrl, dbUserid, dbPasswd );
    210:             stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
    211:         } catch (Exception e) {  //SQLException / ClassNotFound / Exception
    212:             try {  // DB Objectクローズ
    213:                 if( stmt != null ) {  stmt.close();  }
    214:                 if( conn != null ) {  conn.close();  }
    215:             } catch(SQLException se) {}
    216: 
    217:             throw new IOException(e.toString());
    218:         }
    219: 
    220:         Hashtable orderData = (Hashtable)session.getAttribute( "AttrOrderData" );
    221:         int orderNum  = orderData.size();
    222: 
    223:         // 現在表示データ保存
    224:         Integer  rbkNum      = (Integer)session.getAttribute( "AttrShowNum" );
    225:         String[] rbkProduct  = (String[])session.getAttribute( "AttrShowProduct" );
    226:         String[] rbkProdName = (String[])session.getAttribute( "AttrShowProdName" );
    227:         Long[]   rbkPrice    = (Long[])session.getAttribute( "AttrShowPrice" );
    228:         Long[]   rbkStoks    = (Long[])session.getAttribute( "AttrShowStoks" );
    229: 
    230:         // 表示データクリア
    231:         session.removeAttribute( "AttrShowNum" );
    232:         session.removeAttribute( "AttrShowProduct" );
    233:         session.removeAttribute( "AttrShowProdName" );
    234:         session.removeAttribute( "AttrShowPrice" );
    235:         session.removeAttribute( "AttrShowStoks" );
    236: 
    237:         Enumeration enu = orderData.keys();
    238:         String[] sortprod = new String[orderNum];
    239:         String[] product  = new String[orderNum];
    240:         String[] prodname = new String[orderNum];
    241:         Long[]   price    = new Long[orderNum];
    242:         Long[]   stoks    = new Long[orderNum];
    243:         int    cnt        = 0;     // カウンタ
    244:         String sqlStr     = null;
    245:         String rset_c1    = null;  // 製品CD
    246:         String rset_c2    = null;  // 製品名
    247:         long   rset_c3    = 0;     // 単価
    248:         long   rset_c4    = 0;     // 在庫数
    249:         int orderCnt      = 0;
    250: 
    251:         try {
    252:             for( cnt = 0; cnt < orderNum; cnt++) {
    253:                 sortprod[cnt] = (String)enu.nextElement();
    254:             }
    255:             Arrays.sort(sortprod);
    256:             for( cnt = 0; cnt < orderNum; cnt++) {
    257:                 rset_c1 = sortprod[cnt];
    258:                 sqlStr = "SELECT * FROM WEBCONT_WAREHOUSE WHERE PRODUCT_ID LIKE '" + rset_c1 +"'";
    259:                 rset = stmt.executeQuery( sqlStr );
    260:                 if ( !rset.first() ) {
    261:                     continue;
    262:                 }
    263:                 // 在庫データの取得
    264:                 rset_c1 = rset_c1.trim();
    265:                 rset_c2 = rset.getString(2);
    266:                 rset_c2 = rset_c2.trim();
    267:                 rset_c3 = rset.getLong(3);
    268:                 rset_c4 = rset.getLong(4);
    269:                 // 在庫データの設定
    270:                 product[orderCnt]  = rset_c1;
    271:                 prodname[orderCnt] = rset_c2;
    272:                 price[orderCnt]    = new Long(rset_c3);
    273:                 stoks[orderCnt]    = new Long(rset_c4);
    274:                 orderCnt++;
    275:             }
    276: 
    277:             // 表示データの更新
    278:             session.setAttribute( "AttrShowNum", new Integer(orderCnt));
    279:             session.setAttribute( "AttrShowProduct", product );
    280:             session.setAttribute( "AttrShowProdName", prodname );
    281:             session.setAttribute( "AttrShowPrice", price );
    282:             session.setAttribute( "AttrShowStoks", stoks );
    283: 
    284:             // DB Objectクローズ
    285:             if( rset != null ) rset.close();
    286:         } catch (SQLException e) {
    287:             // 現在表示データの復帰
    288:             session.setAttribute( "AttrShowNum",      rbkNum );
    289:             session.setAttribute( "AttrShowProduct",  rbkProduct );
    290:             session.setAttribute( "AttrShowProdName", rbkProdName );
    291:             session.setAttribute( "AttrShowPrice",    rbkPrice );
    292:             session.setAttribute( "AttrShowStoks",    rbkStoks );
    293:             throw new IOException(e.getMessage());
    294:         } finally {
    295:             try {  // DB Objectクローズ
    296:                 stmt.close();
    297:                 conn.close();
    298:             } catch(SQLException se) {  }
    299:         }
    300: 
    301:         return;
    302:     }
    303: }
    <EOF>

    2.5.2. 発注データDB登録処理

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

    発注データDB登録処理(DBOrderData.class)のソースを次に表示します。
    000: 
    001: package jp.co.nec.WebOTX.StrutsSample;
    002: 
    003: import javax.servlet.http.HttpServletRequest;
    004: import javax.servlet.http.HttpSession;
    005: import javax.servlet.http.HttpServletResponse;
    006: import javax.servlet.*;
    007: 
    008: import java.io.*;
    009: import java.util.Hashtable;
    010: import java.util.Enumeration;
    011: import java.util.Arrays;
    012: import java.sql.*;
    013: import java.sql.Date.*;
    014: import java.sql.SQLException;
    015: 
    016: public final class DBOrderData {
    017: 
    018:     // ----------------------------------------------------- Instance Variables
    019:     /**
    020:      * The <code>Log</code> instance for this application.
    021:      */
    022:     String[] dbInfo = null;  // DB接続情報
    023:     String dbDriver = null;  // JDBCドライバ名
    024:     String dbUrl    = null;  // DBへのURL
    025:     String dbUserid = null;  // ユーザ名
    026:     String dbPasswd = null;  // パスワード
    027:     Hashtable errorData = new Hashtable();
    028: 
    029:     public DBOrderData( ServletContext servcon,
    030:                             HttpServletRequest request )
    031:             throws IOException {
    032: 
    033:         initDBInfo( servcon, request );
    034:     }
    035: 
    036:     // --------------------------------------------------------- Public Methods
    037: 
    038:     public void initDBInfo( ServletContext servcon,
    039:                             HttpServletRequest request )
    040:             throws IOException {
    041: 
    042:         Connection conn = null;
    043:         Statement  stmt = null;
    044:         ResultSet  rset = null;
    045: 
    046:         HttpSession session = request.getSession();
    047: 
    048:         // DB情報の取得
    049:         dbInfo = (String[])session.getAttribute( "AttrDBInfo" );
    050:         if( dbInfo == null ) {
    051:             dbInfo = new String[4];
    052: 
    053:             dbInfo[0] = dbDriver = servcon.getInitParameter( "dbDriver" );
    054:             dbInfo[1] = dbUrl    = servcon.getInitParameter( "dbURL" );
    055:             dbInfo[2] = dbUserid = servcon.getInitParameter( "dbUserId" );
    056:             dbInfo[3] = dbPasswd = servcon.getInitParameter( "dbPassword" );
    057:             session.setAttribute( "AttrDBInfo", dbInfo );
    058:         } else {
    059:             dbDriver = dbInfo[0];
    060:             dbUrl    = dbInfo[1];
    061:             dbUserid = dbInfo[2];
    062:             dbPasswd = dbInfo[3];
    063:         }
    064:     }
    065: 
    066:     public void entryData( HttpServletRequest request )
    067:             throws IOException {
    068: 
    069:         Connection conn = null;
    070:         Statement  stmt = null;
    071:         ResultSet  rset = null;
    072:         PreparedStatement  od_stmt = null;
    073:         HttpSession session = request.getSession();
    074: 
    075:         // 在庫テーブルのコネクション生成
    076:         try {
    077:             Class.forName( dbDriver );
    078:             conn = DriverManager.getConnection( dbUrl, dbUserid, dbPasswd );
    079:             stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
    080:         } catch (Exception e) {  //SQLException / ClassNotFound / Exception
    081:             try {
    082:                 // DB Objectクローズ
    083:                 if( stmt != null ) {  stmt.close();  }
    084:                 if( conn != null ) {  conn.close();  }
    085:             } catch(SQLException se) { }
    086:             throw new IOException(e.toString());
    087:         }
    088: 
    089:         Hashtable orderData = (Hashtable)session.getAttribute("AttrOrderData");
    090:         if( orderData == null ) {
    091:             return;
    092:         }
    093: 
    094:         String rset_c1     = null;  // 製品CD
    095:         String rset_c2     = null;  // 製品名
    096:         long   rset_c3     = 0;     // 単価
    097:         long   rset_c4     = 0;     // 在庫数
    098:         long   sub_total   = 0;     // 小計
    099:         Timestamp  nowtim  = null;  // 日時刻
    100:         Integer orderNum   = null;  // 注文数
    101:         String sqlStr      = null;  // 実行SQL文
    102: 
    103:         String[] logonInfo = (String[])session.getAttribute("AttrLogOnInfo");
    104:         if( logonInfo == null ) {
    105:             throw new IOException("not found logon data");
    106:         }
    107: 
    108:         Enumeration enu = orderData.keys();
    109: 
    110:         try {
    111:             for( ; enu.hasMoreElements(); ) {
    112:                 rset_c1 = (String)enu.nextElement();
    113:                 // 在庫データより該当データを抽出
    114:                 sqlStr = "SELECT * FROM WEBCONT_WAREHOUSE WHERE PRODUCT_ID LIKE '" + rset_c1 +"'";
    115: 
    116:                 // 自動コミットを解除
    117:                 conn.setAutoCommit( false );
    118: 
    119:                 // 在庫テーブルの抽出
    120:                 rset = stmt.executeQuery( sqlStr );
    121:                 rset.beforeFirst();
    122: 
    123:                 if( rset.next() != true ) {
    124:                     // 自動コミットを復活
    125:                     conn.setAutoCommit( true );
    126:                     continue;
    127:                 }
    128: 
    129:                 // 発注データ有無チェック
    130:                 if( orderData.get( rset_c1 ) == null ) {
    131:                     // 自動コミットを復活
    132:                     conn.setAutoCommit( true );
    133:                     continue;
    134:                 }
    135: 
    136:                 rset_c2 = rset.getString(2);
    137:                 rset_c2 = rset_c2.trim();
    138:                 rset_c3 = rset.getLong(3);
    139:                 rset_c4 = rset.getLong(4);
    140: 
    141:                 orderNum = (Integer)orderData.get( rset_c1 );
    142:                 rset_c4 = rset_c4 - orderNum.longValue();
    143:                 if( rset_c4 < 0 ) {
    144:                     errorData.put( rset_c1, orderNum );
    145: 
    146:                     // 自動コミットを復活
    147:                     conn.setAutoCommit( true );
    148:                     continue;
    149:                 }
    150: 
    151:                 // 検索結果クローズ
    152:                 rset.close();
    153: 
    154:                 // 在庫テーブルの在庫数更新
    155:                 sqlStr = "UPDATE WEBCONT_WAREHOUSE SET STOCK_NUM='" + 
    156:                           new Long(rset_c4).toString() + 
    157:                          "' WHERE PRODUCT_ID='" + rset_c1 + "'";
    158:                 stmt.executeQuery( sqlStr );
    159: 
    160:                 // 発注済みデータの登録
    161:                 sqlStr = "INSERT INTO WEBCONT_ORDER(ORDER_SHOP," + "ORDER_CLERK," + 
    162:                                                "ORDER_NO," + "ORDER_DATE," + 
    163:                                                "PRODUCT_ID," + "PRODUCT_NAME," + 
    164:                                                "UNIT_PRICE," + "ORDER_NUM,SUB_TOTAL)" + 
    165:                                 " values (?,?,?,?,?,?,?,?,?)";
    166:                 // INSERT (注文店/注文者/注文番号/注文日付/製品CD/製品名/単価/注文数/小計)
    167:                 od_stmt = conn.prepareStatement( sqlStr );
    168: 
    169:                 sub_total    = orderNum.longValue() * rset_c3; // 小計計算
    170:                 nowtim = new Timestamp(System.currentTimeMillis());
    171:                 od_stmt.setString( 1, logonInfo[0] );        // 発注店設定
    172:                 od_stmt.setString( 2, logonInfo[1] );        // 発注者設定
    173:                 od_stmt.setString( 3, logonInfo[2] );        // 発注番号設定
    174:                 od_stmt.setTimestamp( 4, nowtim );           // 注文日設定
    175:                 od_stmt.setString( 5, rset_c1 );             // 製品CD設定
    176:                 od_stmt.setString( 6, rset_c2 );             // 製品名設定
    177:                 od_stmt.setLong( 7, rset_c3 );               // 単価設定
    178:                 od_stmt.setLong( 8, orderNum.longValue() );  // 注文数設定
    179:                 od_stmt.setLong( 9, sub_total );             // 小計設定
    180:                 // 設定実行
    181:                 od_stmt.execute();
    182: 
    183:                 // ステートメントクローズ
    184:                 od_stmt.close();
    185: 
    186:                 // コミットを行う
    187:                 conn.commit();
    188: 
    189:                 // 自動コミットを復活
    190:                 conn.setAutoCommit( true );
    191: 
    192:                 // 発注済みデータを発注データより削除
    193:                 orderData.remove( rset_c1 );
    194:             }
    195: 
    196:         } catch (Exception e) {
    197:             try {
    198:                 conn.rollback();
    199:             } catch(SQLException e2) {
    200:                 throw new IOException("DBOrder rollback NG");
    201:             }
    202:             throw new IOException(e.toString());
    203:         } finally {
    204:             try {
    205:                 // 自動コミットを復活
    206:                 conn.setAutoCommit( true );
    207: 
    208:                 // DB Objectクローズ
    209:                 stmt.close();
    210:                 conn.close();
    211:             } catch(SQLException se) { }
    212:         }
    213: 
    214:         return;
    215:     }
    216: }
    <EOF>

    2.5.2.1. データベースへのアクセス

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

    try {

    } catch (SQLException e) {

    :


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

  • 在庫管理テーブル
    製品ID製品名単価在庫数
    PRODUCT_IDPRODUCT_NAMEUNIT_PRICESTOCK_NUM
    char(32)char(32)numbernumber

  • 発注済データテーブル
    発注店担当者発注番号発注日製品ID製品名単価注文数小計
    ORDER_SHOPORDER_CLERKORDER_NOORDER_DATEPRODUCT_IDPRODUCT_NAMEUNIT_PRICEORDER_NUMSUB_TOTAL
    char(32)char(32)char(64)Datechar(10)char(32)numberNumbernumber

  • ユーザ情報テーブル
    ユーザ名パスワード担当店
    INFO_USERINFO_PASSINFO_SHOP
    char(32)char(32)char(32)

  • 2.6. 定義ファイルの作成

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

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

    例) struts-config.xmlの設定例
    000: <?xml version="1.0" encoding="ISO-8859-1" ?>
    001: 
    002: <!DOCTYPE struts-config PUBLIC
    003:           "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
    004:           "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
    005: 
    006: <struts-config>
    007:   <!-- ========== Form Bean Definitions =================================== -->
    008:   <form-beans>
    009:     <!-- Logon form bean -->
    010:     <form-bean      name="logonForm"
    011:                     type="jp.co.nec.WebOTX.StrutsSample.LogonForm"/>
    012:   </form-beans>
    013: 
    014:   <!-- ========== Global Forward Definitions ============================== -->
    015:   <global-forwards>
    016:         <forward name="success"              path="/order.jsp"/>
    017:         <forward name="end"                  path="/entryEnd.jsp"/>
    018:   </global-forwards>
    019: 
    020:   <!-- ========== Action Mapping Definitions ============================== -->
    021:   <action-mappings>
    022:     <action    path="/logon"
    023:                type="jp.co.nec.WebOTX.StrutsSample.LogonAction"
    024:                name="logonForm"
    025:                scope="request"
    026:                input="/logon.jsp">
    027:       <forward name="success"              path="/order.jsp"/>
    028:     </action>
    029: 
    030:     <action    path="/show"
    031:                type="jp.co.nec.WebOTX.StrutsSample.ShowAction"
    032:                scope="request"
    033:                input="/order.jsp">
    034:       <forward name="success"              path="/order.jsp"/>
    035:       <forward name="orderlist"            path="/orderlist.jsp"/>
    036:     </action>
    037: 
    038:     <action    path="/order"
    039:                type="jp.co.nec.WebOTX.StrutsSample.OrderAction"
    040:                scope="request"
    041:                input="/order.jsp">
    042:       <forward name="success"              path="/order.jsp"/>
    043:       <forward name="result"               path="/entryResult.jsp"/>
    044:     </action>
    045: 
    046:   </action-mappings>
    047: 
    048:     <message-resources parameter="jp.co.nec.WebOTX.StrutsSample.ApplicationResources"/>  
    049: 
    050: </struts-config>
    <EOF>

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

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

    web.xmlの設定
    000: <?xml version="1.0" encoding="ISO-8859-1"?>
    001: 
    002: <!DOCTYPE web-app
    003:     PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    004:     "http://java.sun.com/dtd/web-app_2_3.dtd">
    005: 
    006: <web-app>
    007:     <context-param>
    008:         <param-name>dbURL</param-name>
    009:         <param-value>jdbc:oracle:thin:@servername:1521:orcl</param-value>
    010:     </context-param>
    011:     <context-param>
    012:         <param-name>dbDriver</param-name>
    013:         <param-value>oracle.jdbc.driver.OracleDriver</param-value>
    014:     </context-param>
    015:     <context-param>
    016:         <param-name>dbUserId</param-name>
    017:         <param-value>scott</param-value>
    018:     </context-param>
    019:     <context-param>
    020:         <param-name>dbPassword</param-name>
    021:         <param-value>tiger</param-value>
    022:     </context-param>
    023: 
    024:     <!-- Standard Action Servlet Configuration (with debugging) -->
    025:     <servlet>
    026:       <servlet-name>action</servlet-name>
    027:       <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    028:       <init-param>
    029:         <param-name>config</param-name>
    030:         <param-value>/WEB-INF/struts-config.xml</param-value>
    031:       </init-param>
    032:       <init-param>
    033:         <param-name>debug</param-name>
    034:         <param-value>0</param-value>
    035:       </init-param>
    036:       <init-param>
    037:         <param-name>detail</param-name>
    038:         <param-value>0</param-value>
    039:       </init-param>
    040:       <init-param>
    041:         <param-name>validate</param-name>
    042:         <param-value>true</param-value>
    043:       </init-param>
    044:       <load-on-startup>2</load-on-startup>
    045:     </servlet>
    046: 
    047:     <servlet-mapping>
    048:         <servlet-name>action</servlet-name>
    049:         <url-pattern>*.do</url-pattern>
    050:     </servlet-mapping>
    051: 
    052:     <session-config>
    053:         <session-timeout>30</session-timeout>
    054:     </session-config>
    055: 
    056:     <!-- The Usual Welcome File List -->
    057:     <welcome-file-list>
    058:         <welcome-file>index.jsp</welcome-file>
    059:         <welcome-file>index.html</welcome-file>
    060:         <welcome-file>index.htm</welcome-file>
    061:     </welcome-file-list>
    062: 
    063:     <!-- Struts Tag Library Descriptors -->
    064:     <taglib>
    065:         <taglib-uri>http://struts-bean</taglib-uri>
    066:         <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
    067:     </taglib>
    068:     <taglib>
    069:         <taglib-uri>http://struts-html</taglib-uri>
    070:         <taglib-location>/WEB-INF/struts-html.tld</taglib-location>
    071:     </taglib>
    072:     <taglib>
    073:         <taglib-uri>http://struts-logic</taglib-uri>
    074:         <taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
    075:     </taglib>
    076:     <taglib>
    077:         <taglib-uri>http://struts-template</taglib-uri>
    078:         <taglib-location>/WEB-INF/struts-template.tld</taglib-location>
    079:     </taglib>
    080: 
    081: </web-app>
    <EOF>

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

    2.7. warの配備

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

    と入力してください。

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

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

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

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

  • ログオン画面の表示確認

  • ログオン失敗の確認

  • ログオン成功の確認

  • 発注画面表示の確認

  • 発注商品選択の確認

  • 発注データ一覧画面

  • 発注処理の確認

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

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

  • 2.9. データソースの利用

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


     

    Copyright (C) 1998 - 2008 NEC Corporation.All rights reserved.