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

フレームワークは、Webアプリケーションの画面制御や、エラーのハンドリングをしてくれるため、Webアプリケーションの開発工数を削減できます。また、フレームワークに沿って、開発したアプリケーションは再利用性が高まります。
「MVCモデル2」Webアプリケーションのスケルトンです。MVCモデル2とは下記のMVCとモデル2の考え方を組み合わせた物として提案されています。
· JSPのモデル2 : JSPとJava BeansとJava Servletから構成されます。JSPがプレゼンテーションを分担し、Java Beansがアプリケーションロジックとデータの保持を分担、Java Setvletがフロー制御を行います。
· MVC : MVCとは、アプリケーションのロジックとデータを表現するModel、Modelが表現するデータを可視化するView、ユーザの入力に対応してModelを制御するControllerからなります。
MVCモデル2は一般的に次のような構成をとります。

· Java Servletコントローラ : HTTPのリクエストを受けてリクエストの解析とアプリケーションロジックの呼び出し、アプリケーションロジックの結果からJSPの呼び出しを行います。(Controllerに相当、以降ConntolloerServletと表記)
· アプリケーションクラスとJava Beans : ControllerServletからの要求を受けつけるアプリケーションクラスとアプリケーションロジックを実装したJava Beans、データを保持するJava Beans。(Modelに相当、以降アプリケーションクラスと表記)
· JSP : ControllerServletからの指示(forward)を受け付けて、データを保持するアプリケーションクラスからデータを取得し、表示データを生成します。JSPの構造をより簡単にするために、タグライブラリを利用します。(Viewに相当)
Strutsは定義ファイル(struts-config.xml)を設定することで、リクエストによる処理の振り分け、画面
遷移の制御等を行います。
Strutsには以下の主要機能があります。
・コントローラServlet。リクエストをアプリケーション開発者が提供する適切なActionクラスに
割り付けます。
※ Modelに当たる処理はStrutsより制御できるようにStrutsの用意した特定クラスを継承
する必要があります。継承するクラスはアプリケーションクラスを作成するためのAction
Servletクラス、入力データの妥当性をチェックするためのActionFormクラス(Action
Servletクラスが呼ばれる前に呼ばれます)等があります。
・コントローラServletにおけるJSPカスタムタグライブラリ関連のサポート。開発者が対話的な
フォームベースのアプリケーションを作成するのをサポートします。
・ユーティリティクラス。XMLのパース、JavaリフレクションAPIをベースとしたJavaBeanプロ
パティの自動設定、メッセージプロンプトの国際化などをサポートします。
・シナリオ作成 :作成するWebAPの処理概要を作成します。
・MVCに当てはめる :処理概要をMVCモデルに当てはめます。
・処理部品の作成 :MVCモデルに当てはめた各処理を作成します。
・定義ファイル作成 :各処理を制御(リクエスト振り分け、画面遷移等)する定義ファイルを
作成します。
Strutsを使用したサンプルアプリケーション(StrutsSample)の開発手順を記述します。
Strutsを用いたサンプルWebアプリケーションを作成します。
サンプルの処理概要は
・PCサプライ商品を発注するWebアプリケーションとする。
・ログオン処理を行う(ユーザ情報はDBより取得)
・在庫データを表示する(在庫データはDBより取得)
・表示されたデータより商品を選択し、注文数を入力する。
・選択した商品を発注する(発注したデータはDBに登録される)

※ MVCのC(Controller)に当たる処理は定義ファイルをを元にStrutsが行います。
※1 表示データ編集処理は同一のものです。
サンプルの処理概要を3つの処理(A,B,C)に分けてMVCモデルに当てはめていきます。
ログオン処理(A)
・ログオン画面よりユーザ名、パスワードを設定したリクエスト(@)はStrutsにより、ログオン
Form処理へ遷移()します。
・ログオンForm処理でユーザ名、パスワードをチェックし入力されていない(null)場合はエラー
メッセージを生成しログオン画面に遷移します。ログオン画面はエラーメッセージを表示し、再
度入力を要求します。入力が確認できた場合、ログオンActionに遷移(A)します。
・ログオンActionにてDBより取得したユーザ情報を用いて認証処理を行います。認証に失敗した
場合エラーメッセージを生成しログオン画面に遷移(C)します。ログオン画面はエラーメッセー
ジを表示し、再度入力を要求します。認証に成功した場合、発注画面の表示用データを作成(B)
した後、発注画面に遷移(D)します。
注文データ入力処理(B)
・発注画面はログオンActionが作成した表示データを元に画面を表示します。発注画面より商品
注文数が入力(@)された場合データ表示Actionは小計を計算、セション情報として保存しま
す。発注画面より発注一覧画面表示が入力(@)された場合データ表示Actionは一覧画面が表示
するデータを編集(A)し、発注一覧表示画面に遷移(B)します。
・発注一覧表示画面はデータ表示Actionが作成した表示データを元に発注をかけようとしている
注文データを一覧表示します。発注一覧表示画面より「戻る」が入力(B)された場合、データ表
示Actionは発注画面の表示用データを作成(A)した後、発注画面に遷移(@)します。
・注文データ入力が完了し、発注画面より「発注を行います」が入力された場合、発注Actionに
リクエストを発信します。
注文データDB登録処理(C)
・発注Actionは先の注文データ入力処理でセション情報に設定された注文データを元に発注済デ
ータをDBに登録(@)して在庫データも更新します。発注をかけた商品の在庫がすでに足りなか
った場合、発注に失敗した商品の一覧を編集し、発注結果表示画面に遷移(A)します。発注結果
表示画面は発注に失敗した商品情報の一覧を表示し、発注を続ける(C)か、処理を終了する(D)
か、を選択します。
・発注が成功した場合、発注完了画面に遷移(B)します。また在庫データ登録時、DBへのアクセ
スエラー等、深刻なエラーが発生した場合、エラーメッセージを編集し発注完了画面に遷移(B)
します。この場合発注完了画面はエラーメッセージを画面に表示します。
MVCに当てはめた各部品を作成していきます。
・logon.jsp :ログオン画面(View)
・LogonForm.class :ログオンForm(Action)
・LogonAction.class :ログオンAction(Action)
・EditShowData.class :表示データ編集処理(Model)
・order.jsp :発注画面(View)
・orderlist.jsp :発注一覧表示画面(View)
・ShowAction.class :データ表示Ation(Action)
・entryResult.jsp :発注結果表示画面(View)
・entryEnd.jsp :発注完了画面(View)
・OrderAction.class :発注Action(Action)
・DBOrderData.class :発注データDB登録処理(Model)
サンプル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アプリケーションの処理概要図は以下の通りです。


1) StrutsSampleの初期表示画面です。
2) 「ログオン画面へ」を選択するとログオン画面に遷移します。

1) サンプル実行時に起動される画面で、ユーザ名、パスワードを入力します。
ユーザ名 パスワード
User_1 Pass_1 User_2 Pass_2
2) 「発注開始」ボタンをクリックすると、ログオンAction(LogonAction.class)にリクエストを送信
します。
3) 「発注中止」ボタンをクリックすると、発注処理終了画面(entryEnd.jsp)に遷移し発注処理を中断
します。
4) 使用しているStrutsの機能
・beanのmessageタグを使用し、画面に表示する文言をpropertiesファイルより取得し表示
(本サンプルではApplicationResources.properties、ApplicationResources_ja.propertiesを
用意し、後者のファイルを参照)
・htmlのerrorタグを使用し、ログオン処理(LogOnAction/LogonForm.class)内で発生したエ
ラーを画面に表示
errorタグを使用しエラーメッセージを表示した場合の画面を次に示します。

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

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

1) データ表示Action(ShowAction.class)で生成された一覧データを元に画面を表示します。
2) 「戻る」ボタンクリックでデータ表示Action(ShowAction.class)に発注画面表示をリクエストしま
す。
3) 使用しているStruts機能
・beanのmessageタグを使用し、画面に表示する文言をpropertiesファイルより取得し表示
(本サンプルではApplicationResources.properties、ApplicationResources_ja.propertiesを
用意し、後者のファイルを参照)
・htmlのerrorタグを使用し、表示データ編集処理(ShowAction.class)内で発生したエラーを
画面に表示
発注一覧表示画面(orderlist.jsp)のシースを次に表示します。
001:<%@ page
import="java.util.Hashtable"
contentType="text/html;charset=UTF-8"%> 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="order.wtitle"/></title> 008: <SCRIPT
LANGUAGE="JavaScript"> 009: function fncchange(f){ 010:
f.submit(); 011: } 012: </SCRIPT> 013: <html:base/> 014:</head> 015:<body
bgcolor="#B0FFB0"> 016: 017:<html:errors/><br><br> 018: 019:<CENTER><DIV
style="background-color:#363562; width:90%; border-style
:outset" align=center> 020: <font size=42
color=white face="arial"><bean:message key="system.title"/></font> 021:</DIV></CENTER> 022:<br> 023: 024:<% 025: boolean errChk = false; 026: String _shop = null; 027: String _clerk = null; 028: String _orderno = null; 029: int _ordernum = 0; 030: int _shownum =
0; 031: 032: String[] logonInfo = (String[])pageContext.getAttribute(
"AttrLogOnInfo", pageContext.SESSION_SCOPE
); 033: if( logonInfo
== null ) { 034:
errChk = true; 035: } else { 036:
_shop = logonInfo[0]; 037:
_clerk
= logonInfo[1]; 038:
_orderno = logonInfo[2]; 039: } 040: 041: Integer _objInteger = (Integer)pageContext.getAttribute( "AttrShowNum",
pageContext.SESSION_SCOPE ); 042: String[] _showproduct
= (String[])pageContext.getAttribute(
"AttrShowProduct", pageContext.SESSION_SCOPE
); 043: String[] _showprodname = (String[])pageContext.getAttribute(
"AttrShowProdName", pageContext.SESSION_SCOPE ); 044: Long[] _showprice = (Long[])pageContext.getAttribute( "AttrShowPrice",
pageContext.SESSION_SCOPE ); 045: Long[] _showstoks
= (Long[])pageContext.getAttribute( "AttrShowStoks",
pageContext.SESSION_SCOPE ); 046: Hashtable
_orderdata = (Hashtable)pageContext.getAttribute("AttrOrderData",
pageContext.SESSION_SCOPE ); 047: if( _objInteger == null || _showproduct
== null || _showprodname == null || 048:
_showprice == null || _showstoks
== null || _orderdata == null ) { 049:
errChk = true; 050: } else { 051:
_shownum = _objInteger.intValue(); 052: } 053:%> 054:
055:
<% 056:if( errChk ) {
%> 057: <center><bean:message key="error.system.paramerr"/></center> 058: <form
name="form2" METHOD="POST" ACTION="entryEnd.jsp"> 059:
<div align="right"> 060:
<input type="submit" value="<bean:message
key="logon.button2"/>"/> 061:
</div> 062: </form> 063:
<% 064:} else {
%> 065: <center><div
align="center"> 066: <table
border="0" width="678"> 067:
<tr> 068:
<td width="10%" nowrap><small><strong><bean:message key="word.orderno"/></strong></small></td> 069:
<td
width="90%"><small><strong>:</strong><%=_orderno%></small></td> 070:
</tr> 071:
<tr> 072:
<td width="10%" nowrap><small><strong><bean:message key="word.branch"/></strong></small></td> 073:
<td width="90%"><small><strong>:</strong><%=_shop%></small></td> 074:
</tr> 075:
<tr> 076:
<td width="10%" nowrap><small><strong><bean:message key="word.charge"/></strong></small></td> 077:
<td
width="90%"><small><strong>:</strong><%=_clerk%></small></td> 078:
</tr> 079:
</table><br> 080: <table
border="0" width="678"> 081:
<tr> 082:
<td COLSPAN="2" width="670" > 083:
<table border="0" width="100%"> 084:
<tr> 085:
<th nowrap
width="20%" bgcolor="#FF8F20"><bean:message key="word.product"/></th> 086:
<th nowrap
width="20%" bgcolor="#FF8F20"><bean:message key="word.prdname"/></th> 087:
<th nowrap
width="15%" bgcolor="#FF8F20"><bean:message key="word.price"/></th> 088:
<th nowrap
width="10%" bgcolor="#FF8F20"><bean:message key="word.stoks"/></th> 089:
<th nowrap
width="10%" bgcolor="#FF8F20"><bean:message key="word.ordernum"/></th> 090:
<th nowrap
width="15%" bgcolor="#FF8F20"><bean:message key="word.subtotal"/></th> 091:
</tr> 092:
<% 093:
for(int cnt=0; cnt
< _shownum; cnt++)
{ 094:
_objInteger = (Integer)_orderdata.get(_showproduct[cnt]); 095:
if( _objInteger != null ) { 096:
_ordernum = _objInteger.intValue(); 097:
} else { 098:
_ordernum = 0; 099:
}
%> 100:
<tr> 101:
<td nowrap width="20%"
bgcolor="#FFE9D2" align="center"><%=_showproduct[cnt]%></td> 102: <td
nowrap width="20%"
bgcolor="#FFE9D2"><%=_showprodname[cnt]%></td> 103:
<td nowrap width="15%"
bgcolor="#FFE9D2" align="right"><%=_showprice[cnt]%></td> 104:
<td nowrap width="10%"
bgcolor="#FFE9D2" align="right"><%=_showstoks[cnt]%></td> 105:
<td nowrap width="10%"
bgcolor="#FFE9D2" align="right"><%=_ordernum%></td> 106:
<td nowrap width="15%"
bgcolor="#FFE9D2" align="right"><%=new Long(_ordernum*_showprice[cnt].longValue())%></td> 107:
</tr>
<% 108:
}
%> 109:
</table> 110:
</td> 111:
</tr>
112:
<tr
height="16"><td></td></tr> 113:
<tr> 114:
<td COLSPAN="2" > 115:
<table border="0" width="100%"
height="16"> 116:
<td nowrap width="75%"
height="16" align="center"> 117:
<form name="form13" method="POST"
action="show.do"> 118:
<input type="submit" size="150"
value="<bean:message
key="orderlist.button1"/>"/> 119:
<input type="hidden" name="REQ_KIND"
value="RESHOW"> 120:
</form> 121:
</td> 122:
</table> 123:
</td> 124:
</tr> 125: </table> 126:
</div></center>
<% 127:}
%> 128: 129:<br> 130:<hr
align="center"> 131:</body> 132:</html:html> [EOF]

1) 発注に失敗したデータの一覧を表示します。
2) 「Order Page」ボタンをクリックするとデータ表示Action(ShowDataAction.class)に発注画面表示
をリクエストし、処理を継続します。
3) 「EntryEnd Page」ボタンをクリックすると発注完了画面(entryEnd.jsp)に遷移します。
4) 使用しているStrutsの機能
・beanのmessageタグを使用し、画面に表示する文字をpropertiesファイルより取得し表示
(本サンプルではApplicationResources.properties、ApplicationResources_ja.propertiesを
用意し、後者のファイルを参照)
・htmlのerrorタグを使用し、表示データ編集処理(ShowAction.class)内で発生したエラーを
画面に表示
発注結果表示画面(entryResult.jsp)のソースを次に表示します。
001:<%@ page
language="java" contentType="text/html;charset=UTF-8"%> 002:<%@ page
import="java.util.*" %> 003:<%@ taglib
uri="WEB-INF/struts-bean.tld" prefix="bean" %> 004:<%@ taglib
uri="WEB-INF/struts-html.tld" prefix="html" %> 005: 006:<html:html locale="true"> 007:<head> 008:<title><bean:message key="end.wtitle"/></title> 009:<html:base/> 010:</head> 011:<body
bgcolor="#B0FFB0"> 012: 013:<CENTER><DIV
style="background-color:#363562; width:90%; border-style
:outset" align=center> 014: <FONT size=42
color=white face="arial"><bean:message key="system.title"/></FONT> 015:</DIV></CENTER><br> 016:<center> 017:<html:errors/> 018:</center> 019: 020:<center> 021: <table border="0"
width="678" > 022: <tr> 023: <td
width="25%" height="18"></td> 024: <td
width="75%" height="18" align="right"></td> 025: </tr> 026: 027: <tr> 028: <td
width="20%" ></td> 029: <td valign="top" width="80%" nowrap > 030:
<table border="0"
width="100%" height="16"> 031:
<td nowrap width="35%"
height="16"> 032:
<form name="form1" action="order.jsp"> 033:
<input type="submit" border="0"
width="125" value="Order Page"/> 034:
</form> 035:
</td> 036:
<td nowrap width="65%"
height="16"> 037:
<form name="form2" action="entryEnd.jsp"> 038:
<input type="submit" border="0"
width="125" value="Entry End Page"/> 039:
</form> 040:
</td> 041:
</table> 042: </td> 043: </tr> 044: </table> 045:</center> 046: 047:<hr> 048:</body> 049:</html:html>

1) 発注処理に使用した一時データ(ログオン情報、注文データ等)を削除します。
2) 「LogOn Page」ボタンをクリックするとログオン画面(logon.jsp)に遷移します
3) 「Index Page」ボタンをクリックすると初期表示画面(index.html)に遷移します
4) 使用しているStrutsの機能
・beanのmessageタグを使用し、画面に表示する文字をpropertiesファイルより取得し表示
(本サンプルではApplicationResources.properties、ApplicationResources_ja.propertiesを
用意し、後者のファイルを参照)
・htmlのerrorタグを使用し、表示データ編集処理(ShowAction.class)内で発生したエラーを
画面に表示
発注完了画面(entryEnd.jsp)のソースを次に表示します。
001:<%@ page
language="java" contentType="text/html;charset=UTF-8"%> 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:<html:errors/><br><br> 013: 014:<% 015: // Attribute Info clear 016: pageContext.removeAttribute(
"AttrLogOnInfo", pageContext.SESSION_SCOPE
); 017: pageContext.removeAttribute(
"AttrShowNum", pageContext.SESSION_SCOPE ); 018: pageContext.removeAttribute(
"AttrShowProduct", pageContext.SESSION_SCOPE
); 019: pageContext.removeAttribute(
"AttrShowProdName", pageContext.SESSION_SCOPE ); 020: pageContext.removeAttribute(
"AttrShowPrice", pageContext.SESSION_SCOPE
); 021: pageContext.removeAttribute(
"AttrShowStoks", pageContext.SESSION_SCOPE
); 022: pageContext.removeAttribute(
"AttrOrderData", pageContext.SESSION_SCOPE
); 023: pageContext.removeAttribute(
"AttrTotalRec", pageContext.SESSION_SCOPE ); 024: pageContext.removeAttribute(
"AttrNowPage", pageContext.SESSION_SCOPE ); 025:%> 026: 027:<CENTER><DIV
style="background-color:#363562; width:90%; border-style
:outset" align=center> 028: <FONT size=42
color=white face="arial"><bean:message key="system.title"/></FONT> 029:</DIV></CENTER><br> 030: 031:<center> 032: <table border="0"
width="678" height="184"> 033: <tr> 034: <td
width="20%" height="18"></td> 035: <td
width="80%" height="18"
align="right"></td> 036: </tr> 037: 038: <tr><td></td><td><bean:message
key="end.message1"/></td></tr> 039: 040: <tr> 041: <td
width="20%" ></td> 042: <td valign="top" width="80%" nowrap > 043:
<table border="0"
width="100%" height="16"> 044:
<td nowrap width="35%"
height="16"> 045:
<form name="form1" action="logon.jsp"> 046:
<input type="submit" border="0"
width="125" value="LogOn
Page"/> 047:
</form> 048:
</td> 049:
<td nowrap width="65%"
height="16"> 050:
<form name="form2" action="index.html"> 051:
<input type="submit" border="0"
width="125" value="Index Page"/> 052: </form> 053:
</td> 054:
</table> 055: </td> 056: </tr> 057: </table> 058:</center> 059: 060:<hr> 061:</body> 062:</html:html> [EOF]
StrutsのActionServletで受信したリクエストの振り分け先としてActionクラスを継承したアプ
リケーションクラスを作成します。またFormクラスを継承したクラスはアプリケーションクラスが
呼び出される前に入力をチェックするために呼び出されます。
1) ログオン画面でユーザ名、パスワードが入力されている(nullでない)かチェックします。
2) 入力の確認ができたらログオンAction(LogonAction.class)に遷移します。
3) 使用しているStrutsの機能
・処理中にエラーが発生した場合ActionErrorsオブジェクトを生成/保存し、呼び出し元画面
(logon.jsp)に表示
ログオンForm(LogonForm.class)のソースを次に表示します。
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 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]
1) ログオン画面で指定されたログオン情報を元に発注番号を生成、保存します。
2) 表示データ編集処理(EditShowData.class)にて発注画面(order.jsp)で表示するデータを生成します
3) 使用しているStrutsの機能
・処理中にエラーが発生した場合ActionErrorsオブジェクトを生成/保存し、呼び出し元画面
(logon.jsp)に表示
ログオンAction(LogonAction.class)のソースを次に表示します。
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:/** 028: * Implementation of
<strong>Action</strong> that validates a user logon. 029: * 030: * @author Craig R.
McClanahan 031: * @version
$Revision: 1.10 $ $Date: 2002/07/05 032: */ 033:public final class LogonAction extends Action { 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: 076:
String user = request.getParameter("username"); 077:
String pass = request.getParameter("password"); 078: 079:
String[] dbInfo = null; // DB接続情報 080:
String dbDriver = null; // JDBCドライバ名 081:
String dbUrl = null; // DBへのURL 082:
String dbUserid = null; // ユーザ名 083:
String dbPasswd = null; // パスワード 084: 085:
dbInfo = (String[])session.getAttribute(
"AttrDBInfo" ); 086:
if( dbInfo == null ) { 087:
dbInfo = new String[4]; 088: 089:
dbInfo[0] = dbDriver
= servcon.getInitParameter( "dbDriver" ); 090:
dbInfo[1] = dbUrl = servcon.getInitParameter(
"dbURL" ); 091:
dbInfo[2] = dbUserid
= servcon.getInitParameter( "dbUserId" ); 092:
dbInfo[3] = dbPasswd
= servcon.getInitParameter( "dbPassword" ); 093: 094:
session.setAttribute( "AttrDBInfo", dbInfo ); 095:
} else { 096:
dbDriver = dbInfo[0]; 097:
dbUrl = dbInfo[1]; 098:
dbUserid = dbInfo[2]; 099:
dbPasswd = dbInfo[3]; 100:
} 101: 102:
Connection conn = null; 103:
Statement stmt = null; 104:
ResultSet rset =
null; 105: 106:
// 在庫テーブルのコネクション生成 107:
try { 108:
Class.forName( dbDriver ); 109:
conn = DriverManager.getConnection(
dbUrl, dbUserid, dbPasswd );
110:
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); 111:
} catch (Exception e) {
//SQLException / ClassNotFoundException /
Exception 112:
try { // DB Objectクローズ 113:
if( stmt != null ) { stmt.close();
} 114:
if( conn != null ) { conn.close(); } 115:
} catch(SQLException se) { } 116:
throw new ServletException(e.toString()); 117:
} 118: 119:
Vector UserInfo = new Vector(); 120:
try { 121:
String sqlStr = "SELECT * FROM
WEBCONT_USERINFO"; 122:
rset = stmt.executeQuery(
sqlStr ); 123:
for( ; rset.next()==true; ) { 124:
String userinfo[] = new String[3]; 125:
userinfo[0] = rset.getString(
1 ).trim(); 126:
userinfo[1] = rset.getString(
2 ).trim(); 127:
userinfo[2] = rset.getString(
3 ).trim(); 128:
UserInfo.add( userinfo
); 129:
} 130:
rset.close(); 131:
} catch (Exception e) {
//SQLException 132:
throw new ServletException(e.toString()); 133:
} 134: 135:
boolean boo = false; 136:
String logoninfo[] = new String[3]; 137:
for( int cnt = 0; cnt
< UserInfo.size(); cnt++
) { 138:
String userinfo[] = (String[])UserInfo.get( cnt ); 139:
if( userinfo[0].equals(user) && userinfo[1].equals(pass) ) { 140:
logoninfo[0] = userinfo[2]; 141:
logoninfo[1] = userinfo[0]; 142:
Timestamp times = new Timestamp(System.currentTimeMillis()); 143:
DateFormat fmt
= new SimpleDateFormat("yyyyMMddHHmmss"); 144:
logoninfo[2] = userinfo[2]
+ "-" + userinfo[0] + "-" + fmt.format(times); 145:
boo = true; 146:
session.setAttribute( "AttrLogOnInfo", logoninfo
); 147:
} 148:
} 149: 150:
if( !boo ) { 151:
errors.add(ActionErrors.GLOBAL_ERROR, 152:
new ActionError("error.logon.err",
"logon error(user or pass)" )); 153: saveErrors(request, errors); 154:
return (new ActionForward(mapping.getInput())); 155:
} 156: 157:
session.setAttribute( "AttrOrderData", new Hashtable()
); 158: 159:
try { 160:
EditShowData edShowData
= new EditShowData( servcon,
request ); 161:
session.setAttribute( "AttrNowPage", new Integer(1)); 162:
edShowData.getShowData( request ); 163:
} catch (IOException ie)
{ 164:
errors.add(ActionErrors.GLOBAL_ERROR, 165: new
ActionError("error.logon.dberr",
ie.toString() )); 166:
saveErrors(request, errors); 167:
return (new ActionForward(mapping.getInput())); 168:
} 169: 170:
// Forward control to the specified success URI 171:
return mapping.findForward(
"success" ); 172: } 173:} [EOF]
1) 発注画面表示が要求された場合、表示ページ数を元に表示データ編集処理(EditShowData.class)に
て表示データを生成します
2) 次/前ページの表示を要求された場合、表示ページ数を更新して表示データ編集処理(EditShowData
.class)にて発注画面(order.jsp)表示データを生成します
3) 注文数が入力された場合、注文数を製品コードをキーに注文データとして保存します。また注文数
に0が設定された場合、該当するデータを削除します
4) 注文状況一覧が入力された場合、表示データ編集処理(EditShowData.class)にて注文データを元に
表示する一覧データを生成します
5) 使用しているStrutsの機能
・処理中にエラーが発生した場合ActionErrorsオブジェクトを生成/保存し、呼び出し元画面
(order.jsp/orderlist.jsp)に表示
データ表示Action(ShowDataAction.class)のソースを次に表示します。
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 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]
1) 注文データを発注データDB登録処理(DBOrderData.class)にてデータベースに登録します。
2) 発注処理が正常に終了した場合表示する画面を発注終了画面(entryEnd.jsp)に遷移します。正常
に終了しないデータがあった場合ActionErrorsオブジェクトにエラーになった商品データ一覧を
作成し、発注結果表示画面(entryResult.jsp)に遷移します。
3) 使用しているStrutsの機能
・処理中にエラーが発生した場合ActionErrorsオブジェクトを生成/保存し、呼び出し元画面
(order.jsp)に表示
発注処理Action(OrderAction.class)のソースを次に表示します。
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 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 enum = dbOrder.errorData.keys(); 083:
for( ; enum.hasMoreElements() ; ) { 084:
String keyname =
(String)enum.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]
1) 呼び出し元で指定されたページ数を元に発注画面(order.jsp)に表示するデータを生成、保存します
2) 注文データを元に注文状況一覧画面(orderlist.jsp)に表示するデータ一覧を生成、保存します。
表示データ編集処理(EditShowData.class)のソースを次に表示します。
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 enum = 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)enum.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]
1) 注文データを元に発注済データの登録と在庫管理テーブルの更新を行います
在庫データ − 注文データ ⇒更新⇒ 在庫データ
注文データ ⇒追加⇒ 発注済データ
発注データDB登録処理(DBOrderData.class)のソースを次に表示します。
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 enum = orderData.keys(); 109: 110:
try { 111:
for( ; enum.hasMoreElements(); ) { 112:
rset_c1 = (String)enum.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();
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]
ユーザ情報、発注データを保存するためにデータベースを使用します。今回はOracleとその
JDBCドライバを使用しデータの読み書きを行います。
JDBCドライバのファイル(今回はclasses12.zip)をテスト用サーバのクラスパスに登録しておく
必要があります。
try {
@Class.forName( "DBのドライバ名" );
AConnection conn = DriverManager.getConnection( "DBのURL",
"DBのユーザ名", "DBのパスワード" );
BStatement stmt = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
} catch (SQLException e) {
:
@でJDBCドライバを読み込みます
Aでコネクションを生成します。
Bでステートメントを作成し、以後ステートメントに対してSQLを発行します。
サンプルで使用するOracleDBのテーブル情報は以下の通り。
・在庫管理テーブル
|
製品ID |
製品名 |
単価 |
在庫数 |
|
PRODUCT_ID |
PRODUCT_NAME |
UNIT_PRICE |
STOCK_NUM |
|
char(32) |
char(32) |
number |
number |
・発注済データテーブル
|
発注店 |
担当者 |
発注番号 |
発注日 |
製品ID |
|
ORDER_SHOP |
ORDER_CLERK |
ORDER_NO |
ORDER_DATE |
PRODUCT_ID |
|
char(32) |
char(32) |
char(64) |
Date |
char(10) |
|
製品名 |
単価 |
注文数 |
小計 |
|
PRODUCT_NAME |
UNIT_PRICE |
ORDER_NUM |
SUB_TOTAL |
|
char(32) |
number |
Number |
number |
・ユーザ情報テーブル
|
ユーザ名 |
パスワード |
担当店 |
|
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.0//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_0.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> </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の設定
: <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>application</param-name>
<param-value>ApplicationResources</param-value>
</init-param>
<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> : :
<servlet-mapping>の設定によりURLの最後が.doでリクエストされた場合、全てStrutsの
ActionServletクラスが受信することになります。ActionServletクラスは.doの前の部分とStruts
定義ファイル(struts-config.xml)を使用し、振り分け先のアプリケーションクラスを決定します。
Webブラウザより運用管理コンソールを呼び出します。
http://localhost:4848/manager/
と入力してください。
ユーザ名、パスワードを要求された場合、admin/adminadmin を入力してください。
運用管理コンソールが表示されたら、画面左のメニューより「WebApplicationの管理」を選択します。
配備中のWebアプリケーションの一覧が表示されます。WARファイルの配備アップロードの「アップロ
ードするWARファイルの選択」にstruts-sample.warを指定して、「Application Name」に「struts」
を指定して、「Context Root」に「/struts」を指定して配備を実行してください。
以上でWebアプリケーション「struts-example」が配備されます。
ブラウザより
http://localhost/struts/
にアクセスします。
・ログオン画面の表示確認
ログオン画面が表示されることを確認します。
・ログオン失敗の確認
ログオンに失敗した場合の処理を確認します。
何も入力せずに発注開始を選択した場合
→ ログオン画面に戻り、エラーメッセージが画面上部に表示されていること
StrutsのTagを使用したエラーの表示
誤ったユーザ名/パスワードを入力した場合
→ ログオン画面に戻り、エラーメッセージが画面上部に表示されていること
StrutsのTagを使用したエラーの表示
・ログオン成功の確認
ユーザ名(User_1)、パスワード(Pass_1)を入力し発注開始を選択
発注画面が表示されることを確認します。
・発注画面表示の確認
発注画面が表示されることを確認します。
・発注商品選択の確認
商品を選択し、注文数を入力します。小計が計算され表示されることを確認します。
・発注データ一覧画面
発注データ一覧画面を表示し、注文した商品の一覧が表示されることを確認します。
・発注処理の確認
発注処理を実行し、発注完了画面が表示されることを確認します。
DBに発注データが登録され、在庫データが更新されていることを確認します。
(dbtblview.jspを使用)
・発注処理で在庫データ不足により発注に失敗した商品があった場合、発注結果表示画面がが表示さ
れることを確認します。発注を継続する場合、発注画面が表示されることを確認します。発注を中
止した場合、発注完了画面が表示されることを確認します。
・発注完了画面が表示されることを確認します。発注完了画面は発注処理が正常に終了した場合、
発注処理を途中で中断した場合に表示されます。
DBへのコネクション生成は時間のかかる処理です。このコネクションをあらかじめ生成
して、データソースとしてJNDIに登録しておき、使用時に呼び出すことで、生成にかかる
時間を短縮することができます。プログラム中でコネクションを使用するときは、JNDIから
コネクション(データソース)を取得(lookup)することで、コネクションを取得します。