YUI FrameworkにはAMF3を使ったサーバ通信機能が(こっそりと)実装されているので、それを使ってサーバとデータ交換を行ってみます。
サーバ側の仕様を先に決めておきます。
- 言語:Java + Seasar2 + S2Flex2
- ゲートウェイURL:http://127.0.0.1:8080/HelloAmf3World/gateway
- データクラス名:examples.dto.HelloDto
- サービスクラス名:HelloService
- 実行メソッド名:remoteAction
- 引数:HelloDto
- 戻り値:HelloDto
このサーバ情報を元に各クラスを変更していきます。
src/dto/HelloDto.as
package dto { [RemoteClass(alias="examples.dto.HelloDto")] [Bindable] public class HelloDto { public var myName:String = "Hello World!"; public var message:String; } }
[RemotingClass()]のメタデータタグにデータクラス名を指定しています。
また、せっかくなのでmyNameを追加しました。
src/view/HelloView.mxml
<?xml version="1.0" encoding="utf-8"?> <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:yui="http://akabana.seasar.org/yui/mxml" xmlns:logic="logic.*" width="400" height="300"> <yui:RemotingService id="amf" destination="helloService"/> <mx:VBox> <mx:FormItem label="お名前" required="true"> <mx:TextInput id="myName"/> </mx:FormItem> <mx:Button label="click me!" id="clickMe"/> </mx:VBox> <mx:StringValidator id="messageValidator" required="true" source="{myName}" property="text" requiredFieldError="名前を入れてください。"/> </mx:Canvas>
yui:RemotingServiceタグのdestinationにサービスクラス名を指定しています。
src/logic/HelloViewLogic.as
package logic { import dto.*; import flash.events.*; import flash.utils.*; import mx.controls.*; import mx.core.*; import mx.rpc.events.*; import mx.utils.*; import org.seasar.akabana.yui.service.rpc.event.*; import org.seasar.akabana.yui.service.rpc.remoting.*; import view.*; public class HelloViewLogic { [View] public var helloView:HelloView; [Model(bindView="helloView")] public var helloDto:HelloDto; [Service] public var helloService:RemotingService; /** * ボタン押下 */ public function clickMeClickHandler(event:MouseEvent):void { if (helloDto.myName == "") { return; } helloService.remotingAction(helloDto); } /** * 通信成功 */ public function helloServiceRemotingActionResultHandler(event:RpcResultEvent):void { var result:HelloDto = event.result as HelloDto; if (result != null) { helloDto.message = result.message; Alert.show(helloDto.message); } } /** * 通信失敗(RpcFaultEvent) */ public function helloServiceRemotingActionFaultHandler(event:RpcFaultEvent):void { trace(ObjectUtil.toString(event.faultStatus)); } /** * 通信失敗(SecurityErrorEvent) */ public function helloServiceNetStatusEventHandler(event:NetStatusEvent):void { trace(ObjectUtil.toString(event.info)); } /** * 通信失敗(NetStatusEvent) */ public function helloServiceSecurityErrorEventHandler(event:SecurityErrorEvent):void { trace(ObjectUtil.toString(event)); } /** * 通信失敗(IOErrorEvent) */ public function helloServiceioErrorEventHandler(event:SecurityErrorEvent):void { trace(ObjectUtil.toString(event)); } } }
ロジックはいろいろと追記しています。
まずRemotingServiceの定義に[Service]メタデータタグを付けます。
この時、インスタンス名はHelloView.mxmlのdestinationと一致している必要があります。
(つまり、サービスクラス名 == インスタンス名 == destination名、になります)
次に、通信はclickMeボタン押下時に行っています。
ここではサーバ側メソッド名のremotingActionと、引数のHelloDtoを合わせています。
最後に、ボタンハンドラ以降のメソッド名が長ったらしいですが、YUIの命名規則に従っているためこれが仕様です。呼ばれるメソッド名は、サーバとの通信が行われた場合、サービスインスタンス名 + 実行メソッド名 + 結果イベント名 + Handlerとなります。
- 成功時のメソッド名:"helloService" + "RemotingAction" + "Result" + "Handler"
- 失敗時のメソッド名:"helloService" + "RemotingAction" + "Fault" + "Handler"
また、通信エラーなどでサーバとのやりとり自体が正しく行えなかった場合は、別のイベントが発生します。このメソッド名も長いですが、サービスインスタンス名 + エラーイベント名 + "Handler"となります。
- NetStatusEventのメソッド名:"helloService" + "netStatusEvent" + "Handler"
- SecurityErrorEventのメソッド名:"helloService" + "securityErrorEvent" + "Handler"
- IOErrorEventのメソッド名:"helloService" + "ioErrorEvent" + "Handler"
YUI Frameworkの内部でdispatchEvent()しているのはこの3つなので、ハンドラははこの3つでOKだと思います。
今回は、この他にFlashプレイヤーの呼び出しHTMLにも追記します。
bin-debug/HelloYuiWorld.html
AC_FL_RunContent( "src", "HelloYuiWorld", "width", "100%", "height", "100%", "align", "middle", "id", "HelloYuiWorld", "quality", "high", "bgcolor", "#869ca7", "name", "HelloYuiWorld", "flashvars",'remoting.defaultGateway=http://127.0.0.1:8080/HelloAmf3World/gateway', "allowScriptAccess","sameDomain", "type", "application/x-shockwave-flash", "pluginspage", "http://www.adobe.com/go/getflashplayer" );
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="HelloYuiWorld" width="100%" height="100%" codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab"> <param name="movie" value="HelloYuiWorld.swf" /> <param name="quality" value="high" /> <param name="bgcolor" value="#869ca7" /> <param name="allowScriptAccess" value="sameDomain" /> <param name="FlashVars" value="remoting.defaultGateway=http://127.0.0.1:8080/HelloAmf3World/gateway" /> <embed src="HelloYuiWorld.swf" quality="high" bgcolor="#869ca7" width="100%" height="100%" name="HelloYuiWorld" align="middle" play="true" loop="false" quality="high" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer"> </embed> </object>
長いので、必要な箇所だけにしていますが、
「"remoting.defaultGateway=http://127.0.0.1:8080/HelloAmf3World/gateway"」
が含まれる行をそれぞれ追記するだけです。
これでFlex側は完了です。
それにしてもYUI Frameworkはドキュメントが少なく、ほとんどがソースを追っかけていって調べています。
あまり使っている人がいないのだろうか。