[Seasar-user:14705] Re: [S2BlazeDS]Array 型からjava.util.List型への変換

山田 祐己 [E-MAIL ADDRESS DELETED]
2008年 6月 16日 (月) 09:48:42 JST


くろの@FxUGさん

お世話になります。山田です。
返信が遅くなり、大変恐縮です。

> S2Flex2でもS2BlazeDSでもArrayCollectionとArrayList<型指定>間での
> マッピングは自動でやってくれます。完全自動ではありません。

くろのさんの案内をみて、再度、記述の簡素化に挑戦した結果、
以下の記述での動作を確認しました。

ここから
------------------------------------------------------------------------
○flex側ソース
<?xml version="1.0" encoding="UTF-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundColor="#FFFFFF">
<mx:Script>
<![CDATA[
import flex.samples.entity.Product;
]]>
</mx:Script>
<mx:RemoteObject id="srv" destination="productService"/>
<mx:DataGrid id="dg" dataProvider="{srv.getProducts.lastResult}"
width="100%" height="100%" editable="true" />
<mx:HBox>
<mx:Button label="Get Data" click="srv.getProducts() as Product"/>
<mx:Button label="Save Data" click="srv.setProducts(dg.dataProvider)"/>
</mx:HBox>
</mx:Application>

○java側ソース(methodのみ)
public void setProducts(List<Product> products) {
log.debug("setProducts in");
for(Product product:products) {
log.debug("product.name:" + product.name);
}

}

------------------------------------------------------------------------
ここまで

上記の記述の場合、java側に「setProducts」メソッドで
for文前のlog行でブレークポイントを張って、デバッグで内容を見た限り、
引数には、「ArrayCollection(Product)型」で渡っていました。
以降のforループも問題なく動きましたので上手く、
ArrayCollection→List<型指定>が出来ていると感じました。

それと、「flex-config.xml」の方法は、試しましたが上手くいきませんでした。
ただ、以降は、FXUG側に移しての質問が適当だと思いますので、
ここでは割愛します。
(くろのさんの記事を拝見して、それで上手く行かない時は、質問予定です)

どうもありがとうございます。
以上

山田 祐己(Yuki Yamada)
E-Mail [E-MAIL ADDRESS DELETED]


fukuda.tomonari さんは書きました:
> くろの@FxUG(福田@くらめそ)です。
>
> S2Flex2でもS2BlazeDSでもArrayCollectionとArrayList<型指定>間での
> マッピングは自動でやってくれます。完全自動ではありません。
>
> ・Flex側のエンティティ(ArrayCollectionに詰めるもの)におまじないをする
> 例:
> [Bindable]
> [RemoteClass(alias="flex.samples.entity.Test")]
> public class Test {
> (ここはS2BlazeDSサンプルのProductエンティティでも指定されていました)
>
> ・Java側はArrayListに型指定をしておく
> (ここも指定されているでしょう(未確認))
>
> ・重要:Flex側でそのエンティティがソース内に一度も出ないような場合、
> (例:サーバーから受け取ってそのままDataGridに表示)
> エンティティがクラスパス内に入っておらず認識されないため、
> 自動型変換をやってくれません。Objectで送られたり、返ってきます。
> その場合flex-config,xmlにFlex側のエンティティを
> <includes>タグの<symbol>タグに追加しておく必要があります。
> 例:
> <includes>
> <symbol>flex.samples.entity.Test</symbol>
> </includes>
> (Flexコンパイラで読み込まれているか要チェック)
>
> 山田さんの「以下の様に修正したら上手くいきました。」
> のソースでProductがremoteobjectmain.mxmlで初登場しました。
> 無駄にスクリプトのどこかでvar product:Product = new Product();product
=null;
> とやるだけでも自動型変換やってくれるようになりますが、
> Flex-configに記述するのが良いでしょう。
>
> こんな感じでDataGridの値を丸ごと送ったり、
> Select * した処理結果を丸ごと受け取ったり、
> 楽チンに出来るかと思います。
>
> (今執筆中の記事のサンプルを少し改造して配列の授受をテストしてみました
> がうまく行きました。ここらは8月位の記事で書く予定でしたが、今月末位に
> 出る記事にここの動きをこっそり混ぜておくことにしました)
>
>
>> -----Original Message-----
>> From: [E-MAIL ADDRESS DELETED]
>> [mailto:[E-MAIL ADDRESS DELETED]] On Behalf Of 山田 祐己
>> Sent: Friday, June 13, 2008 8:10 AM
>> To: [E-MAIL ADDRESS DELETED]
>> Subject: [Seasar-user:14680] Re: [S2BlazeDS]Array 型からjava.util.List
>> 型への変換
>>
>> 近藤(nobu)さん
>>
>> お世話になります。山田です。
>> 返信、ありがとうございます。
>>
>>> この部分ですかね?
>>>
>>>> var product:Product = list.getItemAt(i) as Product;
>>> 私はS2Flex2を使用していますが、S2Flex2だと上記の部分は必要ですね。
>>> というのも、Array、ArrayCollectionの要素1つ1つはObjectクラスなの
>>> で、ObjectクラスのままJava側に転送しようとすると、Flexから送信され
>>> てきたObjectクラスをJava側のEntityにマッピングできなくなってエラー
>>> が発生します。BlazeDSはどうなんでしょうね?
>> はい。そこなのですが、BlazeDSでもEntityにマッピングは自動ではして
>> 貰えない様です。
>>
>>> srv.setProducts(dg.dataProvider.source);
>>>
>>> としてみてください。dg.dataProviderがArrayCollectionであるなら、
>>> ArrayCollection.sourceはArrayCollection内のデータソース(Array)
>>> を指します。
>> 近藤さんの、ご提案戴きました「dg.dataProvider.source」と云う記述自体が、
>> 上手く認識せずに例外が発生しました。
>> ただ、自動でentityまでマッピングと云うのは、私の過度の期待でしたので、
>> ループでCastしてからメソッドを呼ぶように致します。
>>
>> どうもありがとうございます。
>>
>> 以上
>>
>> 山田 祐己(Yuki Yamada)
>> E-Mail [E-MAIL ADDRESS DELETED]
>>
>> --nobu<[E-MAIL ADDRESS DELETED]> wrote:
>>> 近藤(nobu)です。
>>>
>>>> 上記例ではscriptを使用して、dataProviderをcastし直していますが、
>>> この部分ですかね?
>>>
>>>> var product:Product = list.getItemAt(i) as Product;
>>> 私はS2Flex2を使用していますが、S2Flex2だと上記の部分は必要ですね。
>>> というのも、Array、ArrayCollectionの要素1つ1つはObjectクラスなの
>>> で、ObjectクラスのままJava側に転送しようとすると、Flexから送信され
>>> てきたObjectクラスをJava側のEntityにマッピングできなくなってエラー
>>> が発生します。BlazeDSはどうなんでしょうね?
>>>
>>> BlazeDSがマッピングを賢くしてくれるのであれば、
>>>
>>>> for (var i:int = 0; i < list.length; i++) {
>>>> var product:Product = list.getItemAt(i) as Product;
>>>> condition.push(product);
>>>> // はじめは、ここで1entity毎に実行していた。
>>>> // srv.update(product);
>>>> }
>>>> srv.setProducts(condition);
>>> この部分を、
>>>
>>> srv.setProducts(dg.dataProvider.source);
>>>
>>> としてみてください。dg.dataProviderがArrayCollectionであるなら、
>>> ArrayCollection.sourceはArrayCollection内のデータソース(Array)
>>> を指します。
>>> これでうまくいかなかった場合は、やはり要素1つ1つをキャストして
>>> 配列に詰め直す必要がありそうです。
>>>
>>> いかがでしょうか?
>>>
>>>
>>> 山田 祐己 さんは書きました:
>>>> 近藤(nobu)さん
>>>>
>>>> お世話になります。
>>>> 山田です。
>>>>
>>>> S2BlazeDSのサンプル「remoteobjectmain.mxml」を以下の様に修正したら
>>>> 上手くいきました。
>>>>
>>>> ------------------------------------------------
>>>> ○Flex側ソース
>>>> <?xml version="1.0" encoding="UTF-8"?>
>>>> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
>>>> backgroundColor="#FFFFFF">
>>>>
>>>> <mx:RemoteObject id="srv" destination="productService"/>
>>>>
>>>> <mx:DataGrid id="dg" dataProvider="{srv.getProducts.lastResult}"
>>>> width="100%" height="100%" editable="true" />
>>>>
>>>> <mx:HBox>
>>>> <mx:Button label="Get Data" click="srv.getProducts()"/>
>>>> <!--
>>>> この記述では、java側にArrayCollection(Object)で渡ってしまう。
>>>> <mx:Button label="Save Data"
>> click="srv.setProducts(dg.dataProvider)"/>
>>>> -->
>>>> <mx:Button label="Save Data" click="setProducts()"/>
>>>> </mx:HBox>
>>>>
>>>> <mx:Script>
>>>> <![CDATA[
>>>> import flex.samples.entity.Product;
>>>> import mx.collections.IList;
>>>> import mx.controls.Alert;
>>>> private function setProducts():void {
>>>> var list:IList = IList(dg.dataProvider);
>>>> var condition:Array = new Array();
>>>>
>>>> for (var i:int = 0; i < list.length; i++) {
>>>> var product:Product = list.getItemAt(i) as Product;
>>>> condition.push(product);
>>>> // はじめは、ここで1entity毎に実行していた。
>>>> // srv.update(product);
>>>> }
>>>> srv.setProducts(condition);
>>>> Alert.show('更新を完了しました', '完了');
>>>> }
>>>> ]]>
>>>> </mx:Script>
>>>> </mx:Application>
>>>>
>>>> ○java側ソース
>>>> /**
>>>> * プロダクトのリストを登録(予定)
>>>> *
>>>> */
>>>> public void setProducts(List<Product> products) {
>>>> for(Product product:products) {
>>>> log.debug("product.name:" + product.name);
>>>> }
>>>>
>>>> }
>>>> ------------------------------------------------
>>>> ここまで
>>>>
>>>>
>>>> ついでの質問で恐縮ですが、上記例ではscriptを使用して、
>>>> dataProviderをcastし直していますが、
>>>> ActionScript(MXML)の記述を正しく(?)記載すれば、
>>>> こんな、手間な記述は不要でしょうか?
>>>> Flexの質問ですみませんが、ご存知であればご指導を戴けますと幸いです。
>>>> 宜しくお願いします。
>>>>
>>>> 以上
>>>>
>>>> 山田 祐己(Yuki Yamada)
>>>> E-Mail [E-MAIL ADDRESS DELETED]
>>>>
>>>> --nobu<[E-MAIL ADDRESS DELETED]> wrote:
>>>>> 近藤(nobu)です。
>>>>>
>>>>> 試してみました。勝手に変換してくれました。
>>>>> 以下のような感じです。HelpKeywordというのは、<Bean>に当たる自作
>>>>> クラス(Entity)です。
>>>>>
>>>>> ■Flex側
>>>>> private function buttonOnClickHandler(event:MouseEvent):void
>>>>> {
>>>>> var condition:Array = new Array();
>>>>> var item1:HelpKeyword = new HelpKeyword();
>>>>> item1.helpKeywordId = 1;
>>>>> item1.name = "hoge1";
>>>>> condition.push(item1);
>>>>>
>>>>> var item2:HelpKeyword = new HelpKeyword();
>>>>> item2.helpKeywordId = 2;
>>>>> item2.name = "hoge2";
>>>>> condition.push(item2);
>>>>>
>>>>> var item3:HelpKeyword = new HelpKeyword();
>>>>> item3.helpKeywordId = 3;
>>>>> item3.name = "hoge3";
>>>>> condition.push(item3);
>>>>>
>>>>> svr.echo(condition);
>>>>> }
>>>>>
>>>>> ■Java側
>>>>> public void echo(List<HelpKeyword> message) throws Exception
>>>>> {
>>>>>>>>>>>>>>>>>>>> }
>>>>>
>>>>> やってみるもんです。
>>>>> AMF3通信で、Collectionの受け渡しは鬼門だと思っていたので、ずっと
>>>>> 配列しか使っていませんでしたので、勉強になりました。






Seasar-user メーリングリストの案内