« ManyToMany | メイン | Transfer のドキュメント生成ツール »

ColdSpring の Remote Facades

ColdSpring のドキュメントに Remote Facades という項目がある。
これも確か、デザインパターンで見たような気がする。
便利なサイトがあったので、参考にさせてもらった。ありがたい。
なるほどなるほど。
実際の実装にはここを参考にさせてもらった。

で、とりあえず、http://localhost/shopping/model/ItemArrayBean.cfc?method=getItemArray にアクセス。

コンポーネント [[リポジトリ]]\shopping\www\model\ItemArrayBean.cfc のメソッド 'getItemArray' はリモートでアクセスできません。

cffunction の access 属性が public なのだから当然。


次に、単純に、access 属性を remote にしただけの場合。

要素 TRANSFER は、 として参照されているタイプ class [Ljava.lang.String; の Java オブジェクト内で未定義です

よく見る ColdFusion のエラー。Model-Glue が Transfer を利用できるようにしてくれているわけだから、Model-Glue を経由しない、
コンポーネントへの直接リモートアクセスでは、だめなわけか。
それにしても、この単純和訳は、なんとかならんものだろうか。

shopping.model.ItemArrayBean.cfc の getItemArray 関数をリモートから利用できるようにしてみる。

まず、リモートへの Facade(と言っていいのかな?)となる shopping.model.ItemService.cfc を作成する。

 <cfcomponent displayname="ItemService" output="false">
 <cfprocessingdirective pageencoding="UTF-8" />

  <cffunction name="init" access="public">
   <cfargument name="itemArrayBean" type="any" required="true" />
   <cfset variables.itemArrayBean = arguments.itemArrayBean />
  </cffunction>
  
  <cffunction name="getItemList" access="remote">
   <cfreturn variables.itemArrayBean.getItemArray() />
  </cffunction>

 </cfcomponent>

次に ColdSpring.xml に、以下のように追加。

 <bean id="itemService" class="&topOfPackage;.model.ItemService">
  <constructor-arg name="itemArrayBean"><ref bean="itemArrayBean" /></constructor-arg>
 </bean>
 
 <bean id="itemService_remote" class="coldspring.aop.framework.RemoteFactoryBean">
  <property name="target">
   <ref bean="itemService" />
  </property>
  <property name="beanFactoryScope">
   <value>application</value>
  </property>
  <property name="beanFactoryName">
   <value>beanFactory</value>
  </property>
  <property name="serviceName">
   <value>rItemService</value>
  </property>
  <property name="relativePath">
   <value>/&topOfPackage;/model/remote</value>
  </property>
  <property name="remoteMethodNames">
   <value>*</value>
  </property>
 </bean>

bean id="itemService" はいいと思うけど、ここで肝心なのが、bean id="itemService_remote"。
Remote Facades の対象とする Bean を target で指定。
BeanFactory がどこのスコープに入っているかを beanFactoryScope で指定。
BeanFactory の名前をどのように命名しているかを beanFactoryName で指定。
serviceName は、この名前のコンポーネントが、relativePath に生成される。実際にリモートで利用するためには、この生成されたコンポーネントを指定する。
remoteMethodNames は、利用できる関数を制限、指定できる。

さて、Model-Glue 経由じゃないと、いろいろと不都合があるので、BeanFactory を取得するタイミングが問題である。
Controller の一番最初に駆動される関数 getItemList に、以下のコードを追加してみた。
ColdSpring の BeanFactory が どこかのスコープに入ってないと行けないらしい。Andy Jarrett 氏は、Application にしている。
それが一番妥当で簡単だろう。

 <cfscript>
  if (NOT IsDefined("application.beanFactory")) {
   application.beanFactory = getModelGlue().getBeanFactory();
   application.beanFactory.getBean('itemService_remote');
  }
 </cfscript>

ただ、元々、BeanFactory は、Model-Glue が管理しているので、これを Application スコープに入れてしまうのっていいのだろうか。
何かうまい方法あるのかなぁ。

こうして、http://localhost/shopping/model/remote/rItemService.cfc?method=getItemArray で、リモート利用できる。
http://localhost/shopping/model/remote/rItemService.cfc?wsdl で、Web サービスも可能ということか。

トラックバック

このエントリーのトラックバックURL:
http://www.schwarzmond.info/mt/mt-tb.cgi/81

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

About

2008年06月06日 09:33に投稿されたエントリーのページです。

ひとつ前の投稿は「ManyToMany」です。

次の投稿は「Transfer のドキュメント生成ツール」です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。