Flash側には、
Flash Remotingコンポーネントをインストールします。
Flash MXをインストールしたディレクトリを$FLASH_HOMEと呼ぶことにすると、
$SEASAR_HOME/actionscriptにあるseasarディレクトリを
$FLASH_HOME/Configuration/Includeにコピーします。
EclipseからFlashを立ち上げることができるように設定します。
メニューのウィンドウ->設定->ワークベンチのツリーを展開し、
ファイルの関連付けを選びます。
ファイルタイプの追加をクリックし、*.flaと入力します。
関連付けられたエディターを追加し、外部プログラムから、Flash Docを選びます。
これで、パッケージエクスポローらーから、*.flaをダブルクリックするとFlashが立ち上がります。
それでは早速、足し算をするFlowletを作成して、Flashから呼び出してみましょう。
AddFlowlet.xmlを次のように記述し、WEB-INF/classes/examples/org/seasar/nazunaに置きます。
実際は、セットアップ済なので、この作業は不要です。
この場合のFlowletの名前は、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という名前を付けて保存します。
実際は、examplesプロジェクト/flash/AddFlowletClient.flaに完成したバージョンがあります。
タイムラインパネルのレイヤー1の最初のフレームの上で右クリックして、アクションを選びます。
アクションパネルの右上の矢印のアイコンをクリックして、エキスパートモード、行番号の表示を
選択しておきます。今後、アクションスクリプトはエキスパートモードで記述していきます。
記述するアクションスクリプトは以下のようになります。
#include "NetServices.as" NetServices.setDefaultGatewayURL("http://localhost:8080/examples/gateway"); conn = NetServices.createGatewayConnection(); flowlet = conn.getService("examples.org.seasar.nazuna.AddFlowlet", this); function onResult(result) { c_txt.text = result; } function onStatus(result) { error_mb._x = (Stage.width - error_mb.width) / 2; error_mb._y = (Stage.height - error_mb.height) / 2; error_mb.setMessage(result.type + "\n" + result.description); trace(result.details); } function calculate() { flowlet.execute(Number(a_txt.text), Number(b_txt.text)); }
最初に、NetService.asをインクルード(#include)します。これで、Flash Remotingが使えるようになります。
NetDebug.asには、まだ対応していないので、インクルードしないようにしてください。
NetServices.setDefaultGatewayURL()で、NazunaAMFが稼動しているURLを指定します。
localhost:8080の部分は、自分の環境に応じて書き換えます。
NetServices.createGatewayConnection()で、NetConnectionオブジェクトを取得します。
NetConnectionオブジェクトのgetService()を呼び出し、NetServiceProxyオブジェクトを取得します。
最初の引数は、Flowlet名です。2番目の引数は、コールバックファンクションを
定義しているオブジェクトを指定します。この場合は、メインのタイムライン(this)になります。
Flowletを実行した結果は、非同期にコールバックファンクションで取得します。
正常に実行された場合、onResult()の引数で結果を取得します。
今回のケースでは、c_txt.textに結果を代入します。
例外が発生した場合、onStatus()の引数で例外を取得します。
例外オブジェクトのdetailsプロパティでJavaの例外のスタックトレースを取得できます。
その他に、typeプロパティで例外クラス名、descriptionプロパティで例外のメッセージが取得できます。
calculateファンクションでNetServiceProxyオブジェクトのexecute()を呼び出し、
NazunaAMFにリクエストを送ります。引数は、Flowletのargタグと対応させます。
計算ボタンをクリックするとcalculateファンクションが呼び出されます。
実行するには、 http://localhost:8080/examples/flash/AddFlowletClient.htmlをクリックします。
AddFlowletと同様に、足し算をするRuletを作成して、Flashから呼び出してみましょう。
AddRulet.javaを次のように記述し、WEB-INF/src/examples/org/seasar/nazunaに置きます。
実際は、セットアップ済なので、この作業は不要です。
この場合のRuletの名前は、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という名前を付けて保存します。
実際は、examplesプロジェクト/flash/AddRuletClient.flaに完成したバージョンがあります。
記述するアクションスクリプトは以下のようになります。
#include "NetServices.as" ruletCallback = new Object(); ruletCallback.onResult = function(result) { _root.c_txt.text = result; } ruletCallback.onStatus = function(result) { error_mb._x = (Stage.width - error_mb.width) / 2; error_mb._y = (Stage.height - error_mb.height) / 2; error_mb.setMessage(result.type + "\n" + result.description); trace(result.details); } NetServices.setDefaultGatewayURL("http://localhost:8080/examples/gateway"); conn = NetServices.createGatewayConnection(); rulet = conn.getService("examples.org.seasar.nazuna.AddRulet", ruletCallback); function calculate() { rulet.executeRulet(Number(a_txt.text), Number(b_txt.text)); }
onResult()やonStatus()のコールバックファンクションは、
メインのタイムラインに直接記述するのではなく、Flowlet,Rulet,Sqletごとに
コールバックオブジェクトを作成して、そこに記述したほうが、
コードの見通しが良くなります。
作成したコールバックオブジェクトは、NetConnection.getService()の
2番目の引数に指定します。
Ruletの場合、NetServiceProxyオブジェクトのexecuteRulet()を呼び出し、
NazunaAMFにリクエストを送ります。
引数は、doExecute()の引数に対応させます。
実行するには、 http://localhost:8080/examples/flash/AddRuletClient.htmlをクリックします。
今度は、SelectSqletを、Flashから呼び出してみましょう。
SelectSqlet.xmlをWEB-INF/classes/examples/org/seasar/nazunaに置きます。
実際は、セットアップ済なので、この作業は不要です。
この場合のSqletの名前は、WEB-INF/classes/以下のディレクトリの区切りを.に変換し、
拡張子の.xmlを除いたexamples.org.seasar.nazuna.SelectSqletになります。
SqletのexecuteQuery()を呼び出した結果は、JavaBeansを要素にもつjava.util.ArrayListになります。
java.util.ArrayListは、ActionScriptの配列(Arrayオブジェクト)に変換されます。
JavaBeansは、ActionScriptのクラスのオブジェクトに変換されます。
ActionScriptのクラスの定義は次のようになります。
このファイルは、examplesプロジェクト/falsh/examples/seasar/nazuna/Employee.asに
保存します。実際は、セットアップ済なので、この作業は不要です。
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という名前を付けて保存します。
実際は、examplesプロジェクト/flash/SelectSqletClient.flaに完成したバージョンがあります。
記述するアクションスクリプトは以下のようになります。
#include "NetServices.as" #include "examples/seasar/nazuna/Employee.as" NetServices.setDefaultGatewayURL("http://localhost:8080/examples/gateway"); conn = NetServices.createGatewayConnection(); sqlet = conn.getService("examples.org.seasar.nazuna.SelectSqlet", this); function onResult(result) { result_lb.removeAll(); var num = result.length; for (var i = 0; i < num; ++i) { result_lb.addItem(result[i].employeeName, result[i]); trace(result[i]); } } function onStatus(result) { error_mb._x = (Stage.width - error_mb.width) / 2; error_mb._y = (Stage.height - error_mb.height) / 2; error_mb.setMessage(result.type + "\n" + result.description); trace(result.details); } function search() { sqlet.executeQuery(); } function clear() { result_lb.removeAll(); }
先ほど作成したEmployee.asをインクルードします。
Sqletの場合、NetServiceProxyオブジェクトのexecuteQuery()を呼び出し、NazunaAMFにリクエストを送ります。
引数がある場合、Sqletのargタグと対応させます。今回は引数はありません。
executeQuery()を実行した結果は、onResulet()の引数で、配列として取得できます。
配列の個々の要素は、先ほど説明したように、Employeeオブジェクトにマッピングされています。
EmployeeはSObjectを継承しているため、トレースによってプロパティとその値を知ることができます。
実行するには、 http://localhost:8080/examples/flash/SelectSqletClient.htmlをクリックします。
Flash Remotingでは、UIコンポーネントと簡単に連動できるRecordSetクラスが
提供されています。
executeQuery()のかわりにexecuteRSQuery()を呼び出すことで、RecordSetを取得することができます。
Flash MXを起動します。新しいファイルにSelectSqletClient2.flaという名前を付けて保存します。
実際は、examplesプロジェクト/flash/SelectSqletClient2.flaに完成したバージョンがあります。
記述するアクションスクリプトは以下のようになります。
#include "NetServices.as" #include "seasar/nazuna/NzRecordSet.as" #include "examples/seasar/nazuna/Employee.as" NetServices.setDefaultGatewayURL("http://localhost:8080/examples/gateway"); conn = NetServices.createGatewayConnection(); sqlet = conn.getService("examples.org.seasar.nazuna.SelectSqlet", this); function onResult(result) { result_lb.removeAll(); var num = result.getLength(); var emp = null; for (var i = 0; i < num; ++i) { emp = result.getItemAt(i); result_lb.addItem(emp.employeeName, emp); trace(emp); } } function onStatus(result) { error_mb._x = (Stage.width - error_mb.width) / 2; error_mb._y = (Stage.height - error_mb.height) / 2; error_mb.setMessage(result.type + "\n" + result.description); trace(result.details); } function search() { sqlet.executeRSQuery(); } function clear() { result_lb.removeAll(); }
executeRSQuery()を呼び出すために、seasar/nazuna/NzRecordSet.asをインクルードします。
後は、executeRSQuery()を呼び出すだけで、RecordSetオブジェクトを取得できます。
実行するには、 http://localhost:8080/examples/flash/SelectSqletClient2.htmlをクリックします。
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() されていないオブジェクト | org.seasar.util.Struct |
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 |