kagamihogeの日記

kagamihogeの日記です。

Eclipse3.3 + Flex Builder 3 + S2BlazeDS さわってみた

S2BlazeDS

S2BlazeDS のサンプルを動かすのは S2BlazeDS - Setup に沿ってやれば楽に出来る。

このエントリは「S2BlazeDSサーバ雛形」使ってお約束の足し算サンプル作るとこまでが目標。ただ、「S2BlazeDSサーバサンプル」と「S2BlazeDSクライアントサンプル(FlexBuilder3用)」を基に作ってく方がもう少し楽だったかも、と今思ってる。

手順としてはこんな感じ。

  • サーバ側の Java プロジェクト作る。
  • クライアント側の Flex プロジェクトを作る。
  • サーバ側に足し算のロジックを実装する。
  • クライアント側に RemoteObject 使用してサーバと通信する部分のコード書く。

S2BlazeDS のチュートリアル見てるとサーバとの通信方法は 4 つあるらしい。HTTPService, WebService, RemoteObject, データプッシュ。今回は RemoteObject だけ扱う。オマケ的に HTTPService の手抜きサンプルも作ってみた。

S2BlazeDS サーバ側プロジェクトの作成

まず「S2BlazeDSサーバ雛形」をインポートしてサーバ側の Java プロジェクトを作る。

ファイル -> インポート -> 既存プロジェクトをワークスペースへ -> s2blazeds-server-blank を選択してインポート。プロジェクト名は、変えなくてもいいけど、F2 押して変更。ここでは s2blazeds-server-testhoge にしとく。GUI だとどっからかえるんだろ?

プロジェクト名変えた場合は、プロジェクト右クリック -> プロパティ -> Tomcat -> 全般 -> コンテキスト名も s2blazeds-server-testhoge に変えておいたがほうが良い。

プロジェクト右クリック -> プロパティ -> Tomcat プロジェクト -> コンテキスト定義を更新

ビルドして Tomcat 起動。Seasar2 関連のログがだだだーって出て http://localhost:8080/s2blazeds-server-testhoge/ で HelloWorld が表示されればおk。

S2BlazeDS クライアント側プロジェクトの作成

次に mxml や ActionScript を置くクライアント側の Flex プロジェクトを作る。

ファイル -> 新規 -> Flex プロジェクト -> プロジェクト名は s2blazeds-client-testhoge とする。「サーバーテクノロジ」の「アプリケーションサーバーの種類」は J2EE を選ぶ。んで次へ。

J2EE サーバーを設定の画面。「サーバーの場所」の「ローカルの LifeCycle データサービスサーバーにデフォルトの場所を使用」のチェックを外す。下記の内容を入力する。

「ルートフォルダ」に ${DOCUMENTS}\s2blazeds-server-testhoge\webapp
「ルート URL」に http://localhost:8080/s2blazeds-server-testhoge
「コンテキストルート」に /s2blazeds-server-testhoge

入力したら「設定の検証」を押す。Web ルートフォルダとルート URL は有効です。と表示されればおk。フォルダが無いとかコンテキストルートが無効だとか怒られる場合はどっかの設定と食い違っている。うっかりサーバ側のTomcat プロジェクト の コンテキスト定義を更新してなかった、とか。あとは、当たり前っちゃ当たり前だけどルート URL は Tomcat 起動してないと見に行けないんで Tomcat 起動してませんでした、とか。

main.mxml で Alt+Shift+D,F でデバッグ起動して、ブラウザが立ち上がればおk。

これで S2BlazeDS で開発する準備は完了。

サーバ側に足し算のロジックを実装

再び s2blazeds-server-testhoge を開いてパースペクティブを Java に切り替える。

src/main/java ソースディレクトリに flex.add.service, flex.add.dto を作る。次に src/main/resources/convention.dicon の該当部分を↓みたいに書き換える。



"flex.add"

パッケージ名とか diocn の中とかの命名規則は Seasar2 のドキュメント見て下さい。俺もまだあんまり詳しくないw

flex.add.dto.AddDto クラスを作る。


package flex.add.dto;

import java.io.Serializable;

public class AddDto implements Serializable {
private static final long serialVersionUID = 1L;

public int arg1;
public int arg2;
public int sum;
}

flex.add.service.AddService クラスを作る。


package flex.add.service;

import flex.add.dto.AddDto;

public class AddService {
public AddDto calculate(AddDto addDto) {
addDto.sum = addDto.arg1 + addDto.arg2;
return addDto;
}
}

この辺は……どうみても S2Flex2 のサンプル丸コピです。本当にありがとうございました。ぱくりですいません。

ビルドしてサーバ側の作業はおわり。

クライアント側に RemoteObject 使用してサーバと通信する部分のコード

再び s2blazeds-server-testhoge を開いてパースペクティブを Flex 開発に切り替える。

ソースパスの src に src/flex/add/dto ディレクトリを作る。そのディレクトリに AddDto.as を作成。このクラスがサーバ側の flex.add.dto.AddDto クラスと対応して透過的に扱われることになります。

src/flex/add/dto/AddDto.as の中身はこんな感じ。


package flex.add.dto
{
[RemoteClass(alias="flex.add.dto.AddDto")]
public class AddDto
{
public var arg1:int;
public var arg2:int;
public var sum:int;
public function AddDto(){
}
}
}

main.mxml に足し算用のコンポーネントとサーバ通信のロジックを書く。こんな感じ。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:Script>
    <![CDATA[
        import flex.add.dto.AddDto;
        import mx.rpc.events.ResultEvent;
        private function r(event:ResultEvent):void {
            var addDto:AddDto = addSrv.calculate.lastResult;
            ans_text.text = addDto.sum.toString();
        }
        
        private function clickAdd(event:MouseEvent):void {
            var addDto:AddDto = new AddDto();
            addDto.arg1 = int(arg1_txt.text);
            addDto.arg2 = int(arg2_txt.text);
            addSrv.calculate(addDto);            
        }
    ]]>
</mx:Script>

    <mx:RemoteObject id="addSrv" destination="addService" result="r(event)"/>
    <mx:HBox>
        <mx:TextInput id="arg1_txt"/>
        <mx:TextInput id="arg2_txt"/>
        <mx:Text id="ans_text" text="hoge"/>
        <mx:Button label="add" click="clickAdd(event)"/>
    </mx:HBox>
</mx:Application>

S2BlazeDS のサンプルと違って、データバインディング使ってないからコードが冗長だけど……

これでサーバと通信する足し算が動くはず。

サービスを増やす

たとえば、flex.add.service.AddService に↓のようなリモート呼び出しを追加したとする。


public AddDto multiply(AddDto addDto) {
addDto.sum = addDto.arg1 * addDto.arg2;
return addDto;
}

AddService のクセに multiply とかないわー、ってのはスルーするとして…… main.mxml の RemoteObject の result イベントハンドラがすでに calclulate で使われてるのでどうしたもんか? って話になる。

その辺変えたソースはこんな感じ。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:Script>
    <![CDATA[
        import flex.add.dto.AddDto;
        
        private function showCalculate():void {
            var add:AddDto = addSrv.calculate.lastResult;
            ans_text.text = add.sum.toString();
        }

        private function showMultiply():void {
            var multiply:AddDto = addSrv.multiply.lastResult;
            ans_text.text = multiply.sum.toString();
        }
        
        private function clickAdd(event:MouseEvent):void {
            var addDto:AddDto = new AddDto();
            addDto.arg1 = int(arg1_txt.text);
            addDto.arg2 = int(arg2_txt.text);
            addSrv.calculate(addDto);
        }
        
        private function clickMultiply(event:MouseEvent):void {
            var addDto:AddDto = new AddDto();
            addDto.arg1 = int(arg1_txt.text);
            addDto.arg2 = int(arg2_txt.text);
            addSrv.multiply(addDto);
        }
    ]]>
</mx:Script>

    <mx:RemoteObject id="addSrv" destination="addService" >
        <mx:method name="calculate" result="showCalculate()"/>
        <mx:method name="multiply" result="showMultiply()"/>    
    </mx:RemoteObject>
    
    <mx:HBox>
        <mx:TextInput id="arg1_txt"/>
        <mx:TextInput id="arg2_txt"/>
        <mx:Text id="ans_text" text="hoge"/>
        <mx:Button label="add" click="clickAdd(event)"/>
        <mx:Button label="multiply" click="clickMultiply(event)"/>
    </mx:HBox>
</mx:Application>

サーバーとの通信 第5回 RemoteObject を利用する(2) - 型変換と結果ハンドラー が参考になります。要は RemoteObject の子どもに method をぶら下げれば各リモートメソッドごとにイベントハンドラを書けるようになる。

HTTPService のテキトーなサンプル

サーバ側プロジェクトに webapp/httptest/hoge.html ファイルを作成する。中身はテキトーにこんな感じ。




hoge
hogehoge
ほげ

クライアント側プロジェクトに httptest.mxml を作成する。中身はテキトーにこんな感じ。







まぁ……見たまんまといいますか。実行すると body の中身が表示されます。詳しいことは サーバーとの通信 第3回 HTTPService を利用する(2) を参照。



サーバ連携がめがっさ楽にできますなぁ…… HTTPService とか RemoteObject まわりの仕様を知る必要があるのがちとメンドウといえばメンドウなんだけど。ま、そのくらいは別にね。