Apcoordinator ユーザーズガイド
目次 前ページ次ページ

付録A サンプルアプリケーション

A.1 簡単なサンプル

■アプリケーションの概要

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;

public class HeadBean extends com.fujitsu.uji.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;

public class BodyBean extends com.fujitsu.uji.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;

public class SampleHandler extends com.fujitsu.uji.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で指定)によって表示する入出力画面の名前を指定しています。
目次 前ページ次ページ

All Rights Reserved, Copyright © 富士通株式会社 2000-2005