アプリケーションの概要
2項の加減算を行う簡単なアプリケーションです。


制御ページ
main.jsp
<HTML> <HEAD> <TITLE>sample</TITLE> <%@ page contentType= "text/html; charset=shift_jis" %> <%@ taglib uri="uji-taglib" prefix="uji" %> </HEAD> <BODY> <uji:dispatch /> <uji:include pane="head" /> <uji:include pane="body" /> </BODY> </HTML>
アプリケーションはmain.jspを指定して実行を開始します。制御ページはHTTPリクエストを受け取り、Apcoordinatorを起動します。 taglibディレクティブは、ApcoordinatorのUJIタグを使用可能にする宣言です。 uji:dispatchタグは、HTTPリクエストを解析して、対応するビジネスクラスを呼び出します。 uji:includeタグは画面の各領域にJSPを取り込む指示です。ここではheadとbodyの2つの領域を指定しています。
データBean
HeadBean.java
package sample;
import com.fujitsu.uji.DataBean;
public class HeadBean extends DataBean
{
protected int count;
protected java.util.Date loginTime;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public java.util.Date getLoginTime() {
return loginTime;
}
public void setLoginTime(java.util.Date loginTime) {
this.loginTime = loginTime;
}
}BodyBean.java
package sample;
import com.fujitsu.uji.DataBean;
public class BodyBean extends DataBean
{
protected String message;
protected double val1;
protected double val2;
protected double result;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public double getVal1() {
return val1;
}
public void setVal1(double val1) {
this.val1 = val1;
}
public double getVal2() {
return val2;
}
public void setVal2(double val2) {
this.val2 = val2;
}
public double getResult() {
return result;
}
public void setResult(double result) {
this.result = result;
}
}データBeanは、画面とロジックの間で転送するデータを持つクラスです。データの項目は、JavaBeanのプロパティの形式でset・getメソッドを作成します。例のHeadBeanではcountとloginTime、BodyBeanではmessage、val1、val2、resultの各項目を作成しています。
入出力ページ
header.jsp
<%@ page contentType="text/html; charset=shift_jis" %> <%@ taglib uri="uji-taglib" prefix="uji" %> <uji:useBean id="head" cls="sample.HeadBean" request="true" /> 実行回数は <uji:getProperty bean="head" property="count" /> 回です。 <BR> セションを開始した時間は <uji:getProperty bean="head" property="loginTime" /> です。 <BR> <HR><BR>
request.jsp
<%@ page contentType="text/html; charset=shift_jis" %>
<%@ taglib uri="uji-taglib" prefix="uji" %>
<uji:useBean id="body" cls="sample.BodyBean" request="true" />
サンプルプログラムでは、2項の加減算を実行します。
<FORM method="post">
<INPUT name="uji.verbs" type="hidden" value="add,sub">
<INPUT name="uji.id" type="hidden" value="body">
値1の入力: <INPUT name="val1"> <BR>
値2の入力: <INPUT name="val2"> <BR>
<INPUT name="add" type="submit" value="加算">
<INPUT name="sub" type="submit" value="減算">
</FORM>response.jsp
<%@ page contentType="text/html; charset=shift_jis" %>
<%@ taglib uri="uji-taglib" prefix="uji" %>
<uji:useBean id="body" cls="sample.BodyBean" request="true" />
<uji:getProperty bean="body" property="message" /><BR>
<uji:getProperty bean="body" property="val1" />と
<uji:getProperty bean="body" property="val2" />の計算結果は<BR>
<uji:getProperty bean="body" property="result" />です。<BR>
<FORM method="post">
<INPUT name="uji.verbs" type="hidden" value="next">
<INPUT name="uji.id" type="hidden" value="body">
<INPUT name="next" type="submit" value="入力に戻る">
</FORM>画面の本体です。例のheader.jspはヘッダ部に表示するための画面、request.jspとresponse.jspはボディ部に表示するための画面です。 taglibディレクティブは、ApcoordinatorのUJIタグを使用可能にする宣言です。 uji:useBeanタグは、データBeanの変数名を宣言しています。簡単のために、表示領域名と名前を合わせています。データBeanの変数の内容を参照するためには、uji:getPropertyタグを使用します。
request.jspでは、FORMタグ中のINPUTタグで2つの隠し項目uji.verbsとuji.id、2つの入力項目val1とval2、2つの送信ボタンaddとsubを宣言しています。 uji.verbsはこのフォームで送信されるコマンド(ボタン名)の一覧をApcoordinatorに通知します。 uji.idはこのフォームの入力を受け取るデータBeanの変数名をApcoordinatorに通知します。
response.jspには、フォームの入力項目なしで隠し項目と送信ボタンだけ定義してあります。
フォームのあて先(action)は省略してあります。この場合、HTTPリクエストは同じ制御ページmain.jspに送られます。また、データ量が増えても送信可能にするため、method="post"を指定します。
request.jspとresponse.jspはどちらもBodyBeanに対応する画面で、区別のために画面の表示モードが必要です。あとで出てきますが、これをreqmodeとresmodeとしておきます。 header.jspはHeadBeanに対応する唯一の画面のため、画面モードは不要です。
ビジネスクラス
SampleHandler.java
package sample;
import com.fujitsu.uji.DispatchContext;
import com.fujitsu.uji.GenericHandler;
public class SampleHandler extends GenericHandler
{
public SampleHandler() {
}
public boolean init() {
return true;
}
public void add(DispatchContext context, BodyBean dataBean) {
double result = dataBean.getVal1() + dataBean.getVal2();
dataBean.setMessage("加算を実行しました。");
dataBean.setResult(result);
dataBean.setVerb("resmode");
context.setResponseBean("body", dataBean);
setHead(context);
}
public void sub(DispatchContext context, BodyBean dataBean) {
double result = dataBean.getVal1() - dataBean.getVal2();
dataBean.setMessage("減算を実行しました。");
dataBean.setResult(result);
dataBean.setVerb("resmode");
context.setResponseBean("body", dataBean);
setHead(context);
}
public void next(DispatchContext context, BodyBean dataBean) {
dataBean.setVerb("reqmode");
context.setResponseBean("body", dataBean);
setHead(context);
}
public void startup(DispatchContext context) {
BodyBean dataBean = new BodyBean();
dataBean.setVerb("reqmode");
context.setResponseBean("body", dataBean);
setHead(context);
}
private HeadBean headBean;
private void setHead(DispatchContext context) {
if(headBean == null) {
headBean = new HeadBean();
headBean.setLoginTime(new java.util.Date());
}
headBean.setCount(headBean.getCount() + 1);
context.setResponseBean("head", headBean);
}
}ビジネスクラスでは処理ロジックを記述します。例では送信ボタンに対応したメソッドadd、sub、nextと、初回起動のためのメソッドstartupを持っています。 addメソッドでは、まず、ビジネスロジックとして加算を実行しています。次に結果をデータBeanに設定しています。結果の画面に対応したデータBeanを使用しますが、この例ではデータBeanは共通なのでパラメタとして受け取ったBodyBeanをそのまま利用しています。 setVerbメソッドは、画面の表示モードを指定しています。setResponseBeanで、画面領域とデータBeanを対応付けてApcoordinatorに設定します。 head領域の部分は共通のため、setHeadメソッドでサブルーチン化しています。setHeadの中ではheadBeanに値を設定し、head領域に対応付けています。 initメソッドがtrueを返していますが、これはこのビジネスクラスをセションスコープにする指定です。このクラスの中にはheadBeanという変数があります。セションスコープにすることにより、同じセションでは同じインスタンスを使うことが保証され、headBeanの値が保持されます。
関係定義ファイル
commands.map
# commands.map sample.BodyBean;add=sample.SampleHandler.add sample.BodyBean;sub=sample.SampleHandler.sub sample.BodyBean;next=sample.SampleHandler.next ;=sample.SampleHandler.startup
pages.map
# pages.map sample.HeadBean;=header.jsp sample.BodyBean;reqmode=request.jsp sample.BodyBean;resmode=response.jsp
コマンドマップファイルcommands.mapでは、画面の入力結果のデータBeanとコマンド(送信ボタンの名前)に対応して呼び出すビジネスクラスとメソッドを指定しています。
ページマップファイルpages.mapでは、処理結果のデータBeanと表示モード(setVerbで指定)によって表示する入出力画面の名前を指定しています。