DTOの中身を見て、オブジェクトそのままの受け渡せる理由を知る
次に、QuizResponseDtoを見てみます。
[Bindable] [RemoteClass(alias="jp.co.atmarkit.quiz.dto.QuizResponseDto")] /** * Quizサービス用のResponseDTOクラスです。 */ public class QuizResponseDto { /** 設問のリスト */ public var quizList:ArrayCollection; /** コメントのリスト */ public var commentList:ArrayCollection; }
ここでのポイントはArrayCollection型の変数です。QuizResponseDtoのJava版のソースを見てみます。
/** * Quizサービス用のResponseDTOクラス */ public class QuizResponseDto { /** 設問のリスト */ public List<Quiz> quizList; /** コメントのリスト */ public List<Comment> commentList;
Java側のレスポンスDTOでは、quizListにはQuizオブジェクトが、commentListにはCommentオブジェクトが複数格納されています。それら変数の中身の変換も自動的に行ってくれます。すなわち、Flex側のquizList、commentListにはそれぞれJava側同様に型の付いたオブジェクトが格納されています。
実際にonGetQuizListS2BlazeDS_resultメソッド内でソースの左の方をクリックしてブレークポイントを設定しデバッグを行うと、以下のように戻り値の変数の中身が実際に期待したものになっていることを確認できます。
配列系の中身の自動変換処理が行われない場合
この相互変換処理ですが、以下の場合、「配列系の中身の自動変換処理」が行われません。
- エンティティにBindableとRemoteClassメタデータタグが指定されていない
- 要素のクラスがFlex側で利用されていない
特に、後者のケースがくせものです。このケースはクラスは定義されているが、そのクラスがほかのMXMLやActionScriptの「ソース上」に表れない場合に起こります。これは、今回のような「DTOに配列系のデータが入ってくる場合」によく起こります。
「クラス読み込みクラス」とは?
この問題を回避するには、クラスをクラスパスに無理やり登録するクラス(クラス読み込みクラス)を用意します。以下は、Flex SDKでのクラス読み込みクラスの例です(C:\Program Files\Adobe\Flex Builder 3\sdks\3.0.0\frameworks\projects\framework\srcにあるFrameworkClasses.asです)。
package{ internal class FrameworkClasses{ import mx.binding.ArrayElementWatcher; ArrayElementWatcher; import mx.binding.BindabilityInfo; BindabilityInfo; } }
「クラス読み込みクラス」の作り方
「クラス読み込みクラス」の作り方は以下になります。
- プロジェクトのルートパッケージ直下に○○Classesという名前のクラスを作成(今回のサンプルアプリケーションだとjp.co.atmarkit.quiz直下にQuizClassesという名前のクラスを作成している)
- クラスの可視性はpublic
- クラス内にクラスパスに追加したいクラスを記述。[Ctrl]+[Space]キーで保管すると、import文が作成される
- 作成されたimport文を追加したクラスの前に持ってくる
この手順では分かりにくいので、実際にQuizクラスを「クラス読み込みクラス」に登録した例を見てください。
Quizクラスを追加すると、import文ができる
package jp.co.atmarkit.quiz { import jp.co.atmarkit.quiz.entity.Quiz; public class QuizClasses { Quiz } }
import文を移動する
package jp.co.atmarkit.quiz { public class QuizClasses { import jp.co.atmarkit.quiz.entity.Quiz; Quiz } }
今回のサンプルアプリケーションの作りでは、Quizクラスを「クラス読み込みクラス」に登録する必要はありませんが、例として追加しています。
「クラス読み込みクラス」を読み込む
後は、この「クラス読み込みクラス」をflex-config.xmlのincludesタグで読み込みます。
<?xml version="1.0"?> <flex-config> <includes> <symbol>jp.co.atmarkit.quiz.QuizClasses</symbol> </includes> </flex-config>
このflex-config.xmlはプロジェクトのプロパティのFlexコンパイラの設定で読み込まれています。その結果、QuzClassesに登録されているクラスすべてがクラスパスに追加されるようになります(flex-config.xmlにクラスを1個1個登録してもいいのですが、補間などが行えないのと、クラス名を変更したりした場合にflex-config.xml上の設定を書き直し忘れることが多いので、お勧めしません)。
コードは完ぺきなのにどうもうまく動作しない場合に
作ったFlexアプリケーションのコードは完ぺきなのにどうもうまく動作しないといった場合には、この「クラス読み込みクラス」へのクラスの追加を試してみてください(※クラス読み込みクラス内のimport文がとても変な場所にありますが、気にしないようにしましょう! このクラスだけの特別なコーディング規約です)。
以上でQuizLogicの解説は終わりです。
Seasarアプリケーションの設定ファイル「dicon」
次に、Java側のアプリケーションを見ていきます。Java側のアプリケーションはシンプルにサービスコンポーネントが用意されているだけです。そのサービスコンポーネントがS2BlazeDSを通してFlexから呼び出されます。
「dicon(だいこん)」とは?
クラスの詳細を見る前に、設定ファイル(dicon(だいこん)ファイル)をチェックします。
Seasarでは、特定のパッケージに特定の命名規則でクラスを作成するとそれがコンポーネントとして自動登録されます。開発者はdiconファイルでその命名規則などをカスタマイズします。横断的な処理を追加したり、トランザクションを制御したりといったこともdiconファイルを通して設定します。
クイズアプリケーションでカスタマイズしているdiconファイルは以下のファイルです(diconファイルはsrc/main/resourcesにあります)。
「convention.dicon」
コンポーネントに登録したいパッケージを登録します。Conventionはパッケージの「命名規則」を表します。HelloS2BlazeDSのときのflex.samplesパッケージに加えて、jp.co.atmarkit.quizパッケージを今回登録してあります。
このパッケージ下のserviceパッケージまで登録する必要はありません。serviceやdtoなどの決まった名前のパッケージが含まれるパッケージを指定します(serviceやdtoなどのパッケージ名はSeasarで決められています)。
<component class="org.seasar.framework.convention.impl.NamingConventionImpl"> <initMethod name="addRootPackageName"> <arg>"flex.samples"</arg> </initMethod> <initMethod name="addRootPackageName"> <arg>"jp.co.atmarkit.quiz"</arg> </initMethod> </component>
「creator.dicon」
S2JDBCでDBアクセスするコンポーネントを自動登録するための「命名規則」を追加しています。Creatorはコンポーネントを生成するルールです。
<!-- カスタム設定 --> <!-- S2JDBCコンポーネントの登録 --> <component class="flex.samples.creator.JdbcCreator" > <initMethod name="setInstanceDef"> @org.seasar.framework.container.InstanceDef@SINGLETON_NAME </initMethod> </component>
このファイルのほかの部分を読むと、SeasarではAction、Service、Logic、Dto、Interceptorに関するCreatorが登録されていることを確認できます。
次ページでは、いよいよS2JDBCによるDBアクセス処理について解説を行います。
Copyright © ITmedia, Inc. All Rights Reserved.