2 サーバとの連携と BlazeDS Flex アプリケーションではクライアント ( ブラウザ ) で処理できる機能が多いですが データベースへのアクセスや クライアントでは負担が大きい処理などはサーバ側で行います また パソコンのローカルディスクへのアクセスのように セキュリティの都合でクライアントで直接処理できない場合は一旦サーバにアップロードするなどして処理します 2-1 ファイルアップロードファイルをアップロードする場合は FileReference クラスを使います アップロードするファイルの選択するには browse 関数でファイル選択ウィンドウを表示します ファイルが選択されたら SELECT イベントが発生しますので addeventlistener でイベントハンドラを登録しておきます ファイルが選択されたら 送信先の URL を URLRequest クラスで設定して FileReference クラスの upload 関数で送信します Flex では Web システムのセキュリティの問題があるので ファイルアップロード処理はプログラムからは自動で行えず ファイル選択等をユーザに明示する形で行います サンプル ) ファイルアップロードの例 --- クライアント ( ブラウザ ) 側処理 ActionScript private var fr:filereference; // 初期化処理 private function init():void fr = new FileReference(); // ファイルが選択された時に発生するイベント fr.addeventlistener(event.select, selecthandler); // アップロードするファイルを選択する処理 private function startupload():void // ファイル選択ウィンドウの ファイルの種類 を設定 var flt:array = [ new FileFilter("Text file (*.txt)", "*.txt"), new FileFilter("All (*.*)", "*.*") ]; // ファイル選択ウィンドウ fr.browse(flt); // ファイル選択終了 アップロード private function selecthandler(event:event) :void var request:urlrequest = new URLRequest(); request.url = "/phserver/fileupload"; // URLを設定 request.method = URLRequestMethod.POST; // POSTで送信 // アップロード fr.upload(request); Page 5
--- サーバ側処理 Java servlet の例 // 通常の Java servlet での POST で受信と同じ protected void dopost(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException int max = 10240; // バッファの最大 byte[] buf = new byte[max]; // 読み込みバッファ String start = ""; // ヘッダ部開始 Boundaryを格納 int eof = 0; // 結果返信用のオブジェクト PrintWriter out = response.getwriter(); // 受信したデータ ServletInputStream in = request.getinputstream(); // 受信したデータからヘッダ部を読み込む if(eof == -1) out.print("error"); return; // 異常終了 start = new String(buf, 0, eof -2); // 開始 Boundary // ファイル名を含むヘッダを検索 while(true) if(eof == -1) out.print("error"); return; // 異常終了 String header = new String(buf, 0, eof -2); int filen1 = header.indexof("filename="); if(filen1!= -1) ( 必要に応じたファイル名の処理を行う ) // 残りのヘッダを読み飛ばす break; // context // line // ファイルの内容を読み取り必要な処理を行う while(true) // 受信したバッファから読み込む if(eof == -1) break; // 受信ファイル終了 String s = new String(buf, 0, eof); if(s.indexof(start)!= -1) break; // 最初と同じBoundaryでファイル終了 ( 以降 受信したファイル内容を処理 ) Page 6
ファイルアップロード処理に失敗した場合は IOErrorEvent.IO_ERROR イベントが発生します ファイルアップロード送信終了後 サーバからの返信結果を処理する場合は DataEvent.UPLOAD_COMPLETE_DATA イベントを使います サンプル ) ファイルアップロードの終了イベント処理の例 --- クライアント ( ブラウザ ) 側処理 ActionScript private var fr:filereference; // 初期化処理 private function init():void fr = new FileReference(); // ファイルが選択された時に発生するイベント fr.addeventlistener(event.select, selecthandler); // ファイルアップロード終了後に発生するイベント fr.addeventlistener(dataevent.upload_complete_data,completehandler); // ファイルアップロード異常で発生イベント fr.addeventlistener(ioerrorevent.io_error, faultreadhandler); // アップロード終了 private function completehandler(event:dataevent):void var result:string = event.data; if(result!= ERROR ) Alert.show(" ファイルを送信しました "); else Alert.show(" サーバが異常を返しました "); // アップロード異常 private function faultreadhandler(event:event):void Alert.show(" ファイル送信に失敗しました "); 2-2 ファイルダウンロードサーバ側にあるファイルをダウンロードする場合も FileReference クラスを使います ダウンロードファイルの URL を URLRequest クラスで設定して FileReference クラスの download 関数でダウンロードします ダウンロードが完了すると Event.COMPLETE イベントが発生します 処理に失敗した場合は IOErrorEvent.IO_ERROR イベントが発生します ファイルアップロードと同様にセキュリティの問題があるので クライアント ( ブラウザ ) 側のディスクに書き込むファイルダウンロード処理はプログラムからは自動で行えず ユーザがボタンクリックなどのアクションを行ったときのイベントハンドラ内で download 関数を呼び出し download 関数内の処理でファイル保存先をユーザに明示する形で行われます Page 7
サンプル ) ファイルダウンロードの処理の例 --- クライアント ( ブラウザ ) 側 MXML ダウンロード用のボタン <mx:button id="btndownload" label=" ファイルダウンロード " click="startdownload()" x="305" y="175" width="120"/> --- クライアント ( ブラウザ ) 側 ActionScript private var fr:filereference = null; // 初期化処理 private function init():void fr = new FileReference(); // 終了のイベント設定 fr.addeventlistener(event.complete, completehandler); // エラーイベント設定 fr.addeventlistener(ioerrorevent.io_error, ioerrorhandler); // ダウンロードの開始 private function startdownload():void var request:urlrequest = new URLRequest(); request.url = "/phserver/downloaddir/filename"; fr.download(request); // ダウンロード終了 private function completehandler(event:event):void Alert.show(" ダウンロードを終了しました "); // エラーイベント private function ioerrorhandler(event:ioerrorevent):void Alert.show(" エラーが発生しました "); IOErrorEvent.IO_ERROR イベントは パソコン側のファイルを上書きする場合に他のアプリケーションが使用中などで書き込み不可の場合にも発生します 2-3 ファイルアップロード / ダウンロードのプログレスファイルアップロード / ダウンロード中はプログレスイベント ProgressEvent.PROGRESS が定期的に発生します プログレスイベントのプロパティ BytesLoaded, bytestotal を利用してプログレス表示ができます サンプル ) ファイルアップロードのプログレス表示の例 --- クライアント ( ブラウザ ) 側 MXML <mx:progressbar id="prgbar" label="" mode="manual" height="11" width="266"/> Page 8
--- クライアント ( ブラウザ ) 側 ActionScript // 初期化処理 private var fr:filereference; private var pb:progressbar; private function init():void fr = new FileReference(); fr.addeventlistener(progressevent.progress, progresshandler); pb = prgbar; // プログレス表示 private function progresshandler(event:progressevent):void pb.setprogress(event.bytesloaded, event.bytestotal); 2-4 BlazeDS とリモーティング機能 BlazeDS は Adobe 社が提供している Flex とサーバ側の Tomcat, Java との連携を簡単 高速に行えるオープンソースフレームワークです BlazeDS は Adobe 社の LiveCycle Data Services ES 技術の一部をオープンソースにしたものです 下記のサイトから無償でダウンロードできます BlazeDS ダウンロードサイト http://opensource.adobe.com/wiki/display/blazeds/blazeds BlazeDS binary distribution パッケージは BlazeDS 単体 BlazeDS turnkey パッケージには Tomcat とサンプルプログラムが入っています BlazeDS の特徴は リモーティング機能 AMF 通信 メッセージング機能などがありますが ここでは最も使われるリモーティング機能について解説します リモーティング機能は サーバ側の Java クラスのメソッドを Flex から呼び出す機能で Flex 側では MXML の RomoteObject タグで定義できます サーバ側の BlazeDS 設定ファイルは /webapps/web-inf/flex/ にあります リモーティングに必要なファイルは remoting-config.xml で Flex からの受信を受けるクラスなどを定義します サンプル ) リモーティング設定例 --- サーバ側 WEB-INF/flex/remoting-config.xml (Java クラス remoting.moduleconnection を moduleconnectiondist として定義 ) <destination id="moduleconnectiondist" channels="my-amf"> <properties> <source>remoting.moduleconnection</source> </properties> </destination> Page 9
--- クライアント ( ブラウザ ) 側 MXML <mx:remoteobject id="moduleconnection" destination="moduleconnectiondist" result="moduleconresulthandler(event)" fault="moduleconfaulthandler(event)" /> Flex の MXML では RemoteObject タグの destination プロパティで サーバ側 remotingconfig.xml で定義した id を指定します ActionScript では RemoteObject タグで定義した id で Java のメソッドを参照します RemoteObject タグの result プロパティは 処理終了時に呼び出される関数 fault プロパティは 異常発生時に呼び出される関数です サンプル ) リモーティングコーディング例 --- クライアント ( ブラウザ ) 側 MXML <mx:remoteobject id="moduleconnection" destination="moduleconnectiondist" result="moduleconresulthandler(event)" fault="moduleconfaulthandler(event)" /> --- クライアント ( ブラウザ ) 側 ActionScript // サーバの Java プログラムのメソッド getsessiondata を呼び出す moduleconnection.getsessiondata("dummyname"); // 処理結果 private function moduleconresulthandler(event:resultevent):void // 処理結果が Sting の場合 var resultstr:string = event.result as String; ( 結果を処理する ) // 異常終了 private function moduleconfaulthandler(event:event):void Alert.show(" 異常が発生しました "); 尚 Flex builder で Build する場合の設定は [ プロジェクト ][ プロパティ ] で BlazeDS の設定ファイル servicesconfig.xml へのパスが -services コンパイラ引数に設定されている必要があります Page 10
サーバ側の Java メソッドと ActionScript のパラメータの対応について 代表的な型を以下の表に挙げておきます ( 表は一部を抜粋したものです 詳しくは Adobe 社の BlazeDS のドキュメント等をご覧ください ) Array (dense) ActionScript java.util.list Java Array (sparse) Boolean または 文字列の "true" or "false" flash.utils.bytearray byte [] int/uint java.util.map java.lang.boolean java.lang.integer null String null java.lang.string BlazeDS の詳細 ( 英文 ) は以下の Web サイトにあります http://livedocs.adobe.com/blazeds/1/blazeds_devguide/ 2-5 セッション Flex では セッションは殆ど使う必要はありませんが 他の Web ページとの連携などで必要になる場合があります BlazeDS のリモーティングで呼び出される Java メソッドでのセッション処理は FlexContext の gethttprequest メソッドを使います サンプル ) Flex と BlazeDS リモーティングでセッションを扱う例 --- クライアント ( ブラウザ ) 側 MXML <mx:remoteobject id="moduleconnection" destination="moduleconnectiondist" result="moduleconresulthandler(event)" fault="moduleconfaulthandler(event)" /> --- クライアント ( ブラウザ ) 側 ActionScript // リモーティングで設定 moduleconnection.setsessiondata("dummyname", "dataxxxx"); --- サーバ側 Java クラスのメソッド import flex.messaging.flexcontext; import javax.servlet.http.httpsession; Page 11
// セッション属性の設定 public String setsessiondata(string name, String data) String retstr = OK ; try // セッションの獲得 HttpSession session = FlexContext.getHttpRequest().getSession(); // セッション属性の設定 session.setattribute(name, data); catch (Exception e) retstr = ERROR ; return retstr; Page 12