Flash側には、
Flash Remotingコンポーネントをインストールします。
Flash MXをインストールしたディレクトリを$FLASH_HOMEと呼ぶことにすると、
$SEASAR_HOME/actionscriptにあるseasar,examplesディレクトリを
$FLASH_HOME/Configuration/Includeにコピーします。
次に、NazunaAMFをセットアップします。
Seasarを終了させた後、
$SEASAR_HOME/src/org/seasarでant webappexamplesを実行し、
Seasarを起動しなおします。
ブラウザで、http://localhost:8080/seasar/gateway
にアクセスし、AMFGateway is runningと表示されれば、
NazunaAMFのセットアップは完了です。
それでは早速、足し算をするFlowletを作成して、Flashから呼び出してみましょう。
AddFlowlet.xmlを次のように記述し、seasar/WEB-INF/classes/examples/org/seasar/nazunaに置きます。
実際は、セットアップ済なので、この作業は不要です。
この場合のFlowletの名前は、seasar/WEB-INF/classes/以下のディレクトリの区切りを.に変換し、
拡張子の.xmlを除いたexamples.org.seasar.nazuna.AddFlowletになります。
<flowlet>
<input>
<arg name="a" className="java.lang.Integer"/>
<arg name="b" className="java.lang.Integer"/>
</input>
<output className="java.lang.Integer"/>
<return>a + b</return>
</flowlet>
Flash MXを起動します。新しいファイルにAddFlowletClient.flaという名前を付けて保存します。
$SEASAR_HOME/flash/examples/seasar/nazuna/AddFlowletClient.flaに完成したバージョンがあります。
タイムラインパネルのレイヤー1の最初のフレームの上で右クリックして、アクションを選びます。
アクションパネルの右上の矢印のアイコンをクリックして、エキスパートモード、行番号の表示を
選択しておきます。今後、アクションスクリプトはエキスパートモードで記述していきます。
記述するアクションスクリプトは以下のようになります。
#include "NetServices.as"
NetServices.setDefaultGatewayURL("http://localhost:8080/seasar/gateway");
conn = NetServices.createGatewayConnection();
flowlet = conn.getService("examples.org.seasar.nazuna.AddFlowlet", this);
flowlet.execute(1, 2);
function onResult(result) {
trace(result);
}
function onStatus(result) {
trace(result.details);
}
最初に、NetService.asをインクルード(#include)します。これで、Flash Remotingが使えるようになります。
NetDebug.asには、まだ対応していないので、インクルードしないようにしてください。
NetServices.setDefaultGatewayURL()で、NazunaAMFが稼動しているURLを指定します。
localhost:8080の部分は、自分の環境に応じて書き換えます。
NetServices.createGatewayConnection()で、NetConnectionオブジェクトを取得します。
NetConnectionオブジェクトのgetService()を呼び出し、NetServiceProxyオブジェクトを取得します。
最初の引数は、Flowlet名です。2番目の引数は、コールバックファンクションを
定義しているオブジェクトを指定します。この場合は、メインのタイムライン(this)になります。
NetServiceProxyオブジェクトのexecute()を呼び出し、NazunaAMFにリクエストを送ります。
引数は、Flowletのargタグと対応させます。
ActionScriptの数値型は、NazunaAMFによって、argタグのclassName属性で指定したオブジェクトに変換されます。
Flowletを実行した結果は、非同期にコールバックファンクションで取得します。
正常に実行された場合、onResult()の引数で結果を取得します。
今回のケースでは、3がトレースウィンドウに出力されます。
例外が発生した場合、onStatus()の引数で例外を取得します。
例外オブジェクトのdetailsプロパティでJavaの例外のスタックトレースを取得できます。
その他に、typeプロパティで例外クラス名、descriptionプロパティで例外のメッセージが取得できます。
AddFlowletと同様に、足し算をするRuletを作成して、Flashから呼び出してみましょう。
AddRulet.javaを次のように記述し、seasar/WEB-INF/src/examples/org/seasar/nazunaに置きます。
実際は、セットアップ済なので、この作業は不要です。
この場合のRuletの名前は、seasar/WEB-INF/src/以下のディレクトリの区切りを.に変換し、
拡張子の.javaを除いたexamples.org.seasar.nazuna.AddRuletになります。
package examples.org.seasar.nazuna;
import org.seasar.nazuna.Rulet;
public class AddRulet extends Rulet {
public int doExecute(int a, int b) {
return a + b;
}
}
Flash MXを起動します。新しいファイルにAddRuletClient.flaという名前を付けて保存します。
$SEASAR_HOME/flash/examples/seasar/nazuna/AddRuletClient.flaに完成したバージョンがあります。
記述するアクションスクリプトは以下のようになります。
#include "NetServices.as"
ruletCallback = new Object();
ruletCallback.onResult = function(result) {
trace(result);
}
ruletCallback.onStatus = function(result) {
trace(result.details);
}
NetServices.setDefaultGatewayURL("http://localhost:8080/seasar/gateway");
conn = NetServices.createGatewayConnection();
rulet = conn.getService("examples.org.seasar.nazuna.AddRulet", ruletCallback);
rulet.executeRulet(1, 2);
onResult()やonStatus()のコールバックファンクションは、
メインのタイムラインに直接記述するのではなく、Flowlet,Rulet,Sqletごとに
コールバックオブジェクトを作成して、そこに記述したほうが、
コードの見通しが良くなります。
作成したコールバックオブジェクトは、NetConnection.getService()の
2番目の引数に指定します。
Ruletの場合、NetServiceProxyオブジェクトのexecuteRulet()を呼び出し、
NazunaAMFにリクエストを送ります。
引数は、doExecute()の引数に対応させます。
Flashの数値型は、NazunaAMFによって、doExecute()の引数の型に合わせて変換されます。
今度は、SelectSqletを、Flashから呼び出してみましょう。
SelectSqlet.xmlをseasar/WEB-INF/classes/examples/org/seasar/nazunaに置きます。
実際は、セットアップ済なので、この作業は不要です。
この場合のSqletの名前は、seasar/WEB-INF/classes/以下のディレクトリの区切りを.に変換し、
拡張子の.xmlを除いたexamples.org.seasar.nazuna.SelectSqletになります。
SqletのexecuteQuery()を呼び出した結果は、JavaBeansを要素にもつjava.util.ArrayListになります。
java.util.ArrayListは、ActionScriptの配列(Arrayオブジェクト)に変換されます。
JavaBeansは、ActionScriptのクラスのオブジェクトに変換されます。
ActionScriptのクラスの定義は次のようになります。
このファイルは、$FLASH_HOME/Configuration/Include/examples/seasar/nazuna/Employee.asに
保存します。$SEASAR_HOME/actionscript/examplesを$FLASH_HOME/Configuration/Includeに
コピー済ならこの作業は不要です。
if (examples.seasar.nazuna.Employee === undefined) {
#include "seasar/lang/SObject.as"
seasar.lang.SObject.defineClass("examples.seasar.nazuna.Employee", null,
["employeeNo", "employeeName", "job", "manager", "hireDate", "salary", "commission", "departmentNo"]);
Object.registerClass("examples.org.seasar.nazuna.Employee", examples.seasar.nazuna.Employee);
}
クラスが、まだ未定義の場合にだけ、クラスを定義するようにするため
if (examples.seasar.nazuna.Employee === undefined)でチェックします。
例えば、A.asをB.asとC.asで使うためにインクルードするとき、A.asが
if (A === undefined) {
Aの定義
}
のようになっていれば、B.asとC.asは、A.asが他のクラスで使われているかどうか気にせずに
クラスを定義するために、seasar/lang/SObject.asを先ずインクルードします。
これで、seasar.lang.SObjectが使えるようになります。
クラスの定義は、seasar.lang.SObject.defineClass()を呼び出して行います。
最初の引数はクラス名です。$FLASH_HOME/Configuration/Includeからのパスを
/を.に変換し、拡張子を取ったものがクラス名になります。
2番目の引数は、スーバークラスです。何も指定されていない場合、seasar.lang.SObjectを
継承することになります。
3番目の引数は、プロパティ名の配列です。SObjectを継承している場合、
ここで指定されたプロパティ以外を参照すると、トレースウィンドウで定義されていない
プロパティを参照したことを知ることができるので、スペルミスなどの発見が早くなります。
最後に、Object.registerClass()でJavaのクラスとActionScriptのクラスを関連付けます。
最初の引数は、Javaのクラス名です。2番目の引数は、ActionScriptのクラスになります。
Flash MXを起動します。新しいファイルにSelectSqletClient.flaという名前を付けて保存します。
$SEASAR_HOME/flash/examples/seasar/nazuna/SelectSqletClient.flaに完成したバージョンがあります。
記述するアクションスクリプトは以下のようになります。
#include "NetServices.as"
#include "examples/seasar/nazuna/Employee.as"
NetServices.setDefaultGatewayURL("http://localhost:8080/seasar/gateway");
conn = NetServices.createGatewayConnection();
sqlet = conn.getService("examples.org.seasar.nazuna.SelectSqlet", this);
sqlet.executeQuery();
function onResult(result) {
var num = result.length;
for (var i = 0; i < num; ++i) {
trace(result[i]);
}
}
function onStatus(result) {
trace(result.details);
}
先ほど作成したEmployee.asをインクルードします。
Sqletの場合、NetServiceProxyオブジェクトのexecuteQuery()を呼び出し、NazunaAMFにリクエストを送ります。
引数がある場合、Sqletのargタグと対応させます。今回は引数はありません。
executeQuery()を実行した結果は、onResulet()の引数で、配列として取得できます。
配列の個々の要素は、先ほど説明したように、Employeeオブジェクトにマッピングされています。
EmployeeはSObjectを継承しているため、トレースによってプロパティとその値を知ることができます。
実行すると、以下のような内容がトレースウィンドウに表示されます。
departmentNo:20, commission:null, salary:800, hireDate:Wed Dec 17 00:00:00 GMT+0900 1980, job:CLERK, employeeName:SMITH, employeeNo:7369, manager:7902 departmentNo:30, commission:300, salary:1600, hireDate:Fri Feb 20 00:00:00 GMT+0900 1981, job:SALESMAN, employeeName:ALLEN, employeeNo:7499, manager:7698 departmentNo:30, commission:500, salary:1250, hireDate:Sun Feb 22 00:00:00 GMT+0900 1981, job:SALESMAN, employeeName:WARD, employeeNo:7521, manager:7698 departmentNo:20, commission:null, salary:2975, hireDate:Thu Apr 2 00:00:00 GMT+0900 1981, job:MANAGER, employeeName:JONES, employeeNo:7566, manager:7839 departmentNo:30, commission:1400, salary:1250, hireDate:Mon Sep 28 00:00:00 GMT+0900 1981, job:SALESMAN, employeeName:MARTIN, employeeNo:7654, manager:7698 departmentNo:30, commission:null, salary:2850, hireDate:Fri May 1 00:00:00 GMT+0900 1981, job:MANAGER, employeeName:BLAKE, employeeNo:7698, manager:7839 departmentNo:10, commission:null, salary:2450, hireDate:Tue Jun 9 00:00:00 GMT+0900 1981, job:MANAGER, employeeName:CLARK, employeeNo:7782, manager:7839 departmentNo:20, commission:null, salary:3000, hireDate:Thu Dec 9 00:00:00 GMT+0900 1982, job:ANALYST, employeeName:SCOTT, employeeNo:7788, manager:7566 departmentNo:10, commission:null, salary:5000, hireDate:Tue Nov 17 00:00:00 GMT+0900 1981, job:PRESIDENT, employeeName:KING, employeeNo:7839, manager:0 departmentNo:30, commission:0, salary:1500, hireDate:Tue Sep 8 00:00:00 GMT+0900 1981, job:SALESMAN, employeeName:TURNER, employeeNo:7844, manager:7698 departmentNo:20, commission:null, salary:1100, hireDate:Wed Jan 12 00:00:00 GMT+0900 1983, job:CLERK, employeeName:ADAMS, employeeNo:7876, manager:7788 departmentNo:30, commission:null, salary:950, hireDate:Thu Dec 3 00:00:00 GMT+0900 1981, job:CLERK, employeeName:JAMES, employeeNo:7900, manager:7698 departmentNo:20, commission:null, salary:3000, hireDate:Thu Dec 3 00:00:00 GMT+0900 1981, job:ANALYST, employeeName:FORD, employeeNo:7902, manager:7566 departmentNo:10, commission:null, salary:1300, hireDate:Sat Jan 23 00:00:00 GMT+0900 1982, job:CLERK, employeeName:MILLER, employeeNo:7934, manager:7782
Flash Remotingでは、UIコンポーネントと簡単に連動できるRecordSetクラスが
提供されています。
executeQuery()のかわりにexecuteRSQuery()を呼び出すことで、RecordSetを取得することができます。
Flash MXを起動します。新しいファイルにSelectSqletClient2.flaという名前を付けて保存します。
$SEASAR_HOME/flash/examples/seasar/nazuna/SelectSqletClient2.flaに完成したバージョンがあります。
記述するアクションスクリプトは以下のようになります。
#include "NetServices.as"
#include "seasar/nazuna/NzRecordSet.as"
#include "examples/seasar/nazuna/Employee.as"
NetServices.setDefaultGatewayURL("http://localhost:8080/seasar/gateway");
conn = NetServices.createGatewayConnection();
sqlet = conn.getService("examples.org.seasar.nazuna.SelectSqlet", this);
sqlet.executeRSQuery();
function onResult(rs) {
trace(rs.getColumnNames());
var num = rs.getLength();
for (var i = 0; i < num; ++i) {
trace(rs.getItemAt(i));
}
}
function onStatus(result) {
trace(result.details);
}
executeRSQuery()を呼び出すために、seasar/nazuna/NzRecordSet.asをインクルードします。
後は、executeRSQuery()を呼び出すだけで、RecordSetオブジェクトを取得できます。
実行すると、以下のような内容がトレースウィンドウに表示されます。
employeeNo,employeeName,job,manager,hireDate,salary,commission,departmentNo departmentNo:20, commission:null, salary:800, hireDate:Wed Dec 17 00:00:00 GMT+0900 1980, job:CLERK, employeeName:SMITH, employeeNo:7369, manager:7902 departmentNo:30, commission:300, salary:1600, hireDate:Fri Feb 20 00:00:00 GMT+0900 1981, job:SALESMAN, employeeName:ALLEN, employeeNo:7499, manager:7698 departmentNo:30, commission:500, salary:1250, hireDate:Sun Feb 22 00:00:00 GMT+0900 1981, job:SALESMAN, employeeName:WARD, employeeNo:7521, manager:7698 departmentNo:20, commission:null, salary:2975, hireDate:Thu Apr 2 00:00:00 GMT+0900 1981, job:MANAGER, employeeName:JONES, employeeNo:7566, manager:7839 departmentNo:30, commission:1400, salary:1250, hireDate:Mon Sep 28 00:00:00 GMT+0900 1981, job:SALESMAN, employeeName:MARTIN, employeeNo:7654, manager:7698 departmentNo:30, commission:null, salary:2850, hireDate:Fri May 1 00:00:00 GMT+0900 1981, job:MANAGER, employeeName:BLAKE, employeeNo:7698, manager:7839 departmentNo:10, commission:null, salary:2450, hireDate:Tue Jun 9 00:00:00 GMT+0900 1981, job:MANAGER, employeeName:CLARK, employeeNo:7782, manager:7839 departmentNo:20, commission:null, salary:3000, hireDate:Thu Dec 9 00:00:00 GMT+0900 1982, job:ANALYST, employeeName:SCOTT, employeeNo:7788, manager:7566 departmentNo:10, commission:null, salary:5000, hireDate:Tue Nov 17 00:00:00 GMT+0900 1981, job:PRESIDENT, employeeName:KING, employeeNo:7839, manager:0 departmentNo:30, commission:0, salary:1500, hireDate:Tue Sep 8 00:00:00 GMT+0900 1981, job:SALESMAN, employeeName:TURNER, employeeNo:7844, manager:7698 departmentNo:20, commission:null, salary:1100, hireDate:Wed Jan 12 00:00:00 GMT+0900 1983, job:CLERK, employeeName:ADAMS, employeeNo:7876, manager:7788 departmentNo:30, commission:null, salary:950, hireDate:Thu Dec 3 00:00:00 GMT+0900 1981, job:CLERK, employeeName:JAMES, employeeNo:7900, manager:7698 departmentNo:20, commission:null, salary:3000, hireDate:Thu Dec 3 00:00:00 GMT+0900 1981, job:ANALYST, employeeName:FORD, employeeNo:7902, manager:7566 departmentNo:10, commission:null, salary:1300, hireDate:Sat Jan 23 00:00:00 GMT+0900 1982, job:CLERK, employeeName:MILLER, employeeNo:7934, manager:7782
ActionScriptとJavaのデータマッピングは、次のようになります。
| ActionScript | Java |
|---|---|
| null | null |
| undefined | null |
| boolean | boolean |
| Number | int, long, double |
| String | java.math.BigDecimal |
| String | java.lang.String |
| Date | java.util.Date |
| 配列 | java.util.ArrayList |
| Object.registerClass() されているオブジェクト | 対応するJavaのオブジェクト |
| Object.registerClass() されていないオブジェクト | java.util.HashMap |
| RecordSet | × |
| Java | ActionScript |
|---|---|
| null | null |
| boolean | boolean |
| int, long, double | Number |
| java.math.BigDecimal | String |
| java.lang.String | String |
| java.util.Date | Date |
| 配列, java.util.Collection | 配列 |
| Object.registerClass() されているオブジェクト | 対応するActionScript のオブジェクト |
| Object.registerClass() されていないオブジェクト | オブジェクト |
| org.seasar.nazuna.NzRecordSet | seasar.nazuna.NzRecordSet |