S2Flex2の導入,その1
S2Flex2 - AMF3Gateway with DI Container -をStuvieに導入した時のメモ.
因みにFlexBuilder2で,JavaのプロジェクトはTeedaを使っています.
まず,pom.xmlに
<dependency> <groupId>org.seasar.flex2</groupId> <artifactId>s2-flex2</artifactId> <version>1.1.0</version> </dependency> <dependency> <groupId>org.seasar.flex2</groupId> <artifactId>s2-flex2-tiger</artifactId> <version>1.0.0</version> </dependency>
を追加.
次に,app.diconに
<include path="remoting_amf3.dicon"/>
を追加.diconは1.1からjarに同梱されているので,app.diconに書くだけでいい.
続いて,web,xmlに
<servlet> <servlet-name>gateway</servlet-name> <servlet-class>org.seasar.flex2.rpc.remoting.RemotingGateway</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>showGetResponse</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>useSession</param-name> <param-value>true</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>gateway</servlet-name> <url-pattern>/gateway</url-pattern> </servlet-mapping>
を追加して,gatewayサーブレットを登録する.これがS2Flex2側のS2Flex2Serviceコンポーネントに指定するgatewayUrlになる.
これで,プロジェクトの設定はおしまい.
というか,ほんっとにSeasarプロジェクトはドキュメントが適当で困る.便利なもの作ってるんだから後はドキュメントさえしっかりしていれば言うことないのに.
で,Flex側の設定は,公式からS2Flex2 componentsの最新を落としてきて,
s2flex2-components\src\actionscript\org
を,Flexプロジェクトのメインソースディレクトリに置く.
そして,
<s2:S2Flex2Service id="amf" destination="lectures_lectureService" showBusyCursor="true" gatewayUrl="http://localhost:8080/stuvie/gateway" result="this.application.onGetLectureResult(event)" fault="this.application.onGetLectureFault(event)"/>
の様にすれば
<mx:Button click="amf.getLectures(1)"/>
というように使える.s2接頭辞は
xmlns:s2="org.seasar.flex2.rpc.remoting.*"
と指定すればいい.onFault,onResultの実装は,
public function onGetLectureResult(event:ResultEvent):void{ trace(event); } public function onGetLectureFault(event:FaultEvent):void{ trace(event); }
って感じ.
ここまでできたら,サービスの実装になる.
ここでまずconvention.diconを確認する.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN" "http://www.seasar.org/dtd/components21.dtd"> <components> <component class="org.seasar.framework.convention.impl.NamingConventionImpl"> <initMethod name="addRootPackageName"> <arg>"com.semcode.stuvie"</arg> </initMethod> <property name="viewRootPath">"/"</property> </component> </components>
となっているのなら,サービスの定義は,
com.semcode.stuvie.service
パッケージに,サービスの実装は
com.semcode.stuvie.service.impl
にそれぞれ置く.でないと,
DEBUG 2008-02-19 01:32:06,828 [http-8080-1] サービス(lectures_lectureService)のメソッド(getLectures)を呼び出します。 DEBUG 2008-02-19 01:32:06,859 [http-8080-1] クラス(com.semcode.stuvie.service.lectures.LectureService[lectures_lectureService])のコンポーネント定義を登録します ERROR 2008-02-19 01:32:07,156 [http-8080-1] サービス(lectures_lectureService)のメソッド(getLectures)の実行中に例外が発生しました。 org.seasar.flex2.rpc.remoting.service.exception.InvokerNotFoundRuntimeException: [EFLX0001]適用可能なサービスメソッド実行クラス(lectures_lectureService)が、見つかりません。.
とかいって怒られる.また,サービス名がLectureServiceなら,実装クラスはLectureServiceImplでなくてはならない.FQDNで書くなら
com.semcode.stuvie.service.lectures.LectureService com.semcode.stuvie.service.impl.lectures.LectureServiceImpl
となる.serviceパッケージ以下のサブパッケージをFlexのdestinationに書くときは,
lectures_LectureService
の様にする.
実装のサンプルもついでに載せておくと
LectureService.java
package com.semcode.stuvie.service.lectures; import com.semcode.stuvie.dto.Lectures; public interface LectureService { public Lectures getLectures(Integer contentId); }
の様に,サービス定義をインターフェースで書いて,その実装クラスを
LectureServiceImpl.java
package com.semcode.stuvie.service.lectures.impl; import org.seasar.flex2.rpc.remoting.service.annotation.RemotingService; import com.semcode.stuvie.dto.Lectures; import com.semcode.stuvie.service.lectures.LectureService; @RemotingService public class LectureServiceImpl implements LectureService { public Lectures getLectures(Integer contentId) { return new Lectures(); } }
の様に定義する.
これで,Flex側から
ams.getLectures(1);
の様にして呼び出せるようになる.
んーとっても楽で便利なのに,導入障壁が高すぎるッ.パッケージのネーミング規則ぐらいはドキュメントに書いておいて欲しい.ホントに.
・・・あんまり人のことを言うと罰が当たりそうですが.