ColdFusionをサーバーロジックのコアとした多彩な連携について
1. FlexとColdFusionの連携事例
ColdFusionカフェテリアへお越しのみなさま、はじめまして。構造計画研究所の大塚と申します。
わたしたちは、住宅設備メーカー様向けの商品選定システムや、物流メーカー様向けの在庫最適化システムなどの運用システムの構築を得意としています。ブラウザベースのユーザインタフェースやWebを介した情報のやり取りが必要となる場面で、10年以上ColdFusionを愛用して参りました。
このたび、サムライズさまから、表題のテーマで記事を書くよう仰せつかりました。多くの人の目にふれる文章を書くのは初めてのため、大いに緊張しておりますが、どうぞよろしくお願いします。
2009年ごろから、わたしたちはColdFusionにUIを担当させないシステムデザインを頻繁に採用するようになりました。技術的な問題・業務的な問題を合わせて、大きな理由は3つあったと思っています
cfcメインでサーバ側を構築する場合、純粋なSOAPのほか、JSONやXML文字列、Flexの場合はFlash Remotingの仕組み等を介してクライアントと情報をやりとりさせています。こうしたデザインにすると、ColdFusionは主役というよりはシステム全体の仲介役のような働き方をすることになりますが、jarファイルを別途作って読み込ませる、JNBridgeを使って別マシンに仕事をさせる(Linux→Windows等)、など小回りが利くので、たいへん重宝しています。
そうしたわけで、これから書く一連の記事では、システムの仲介役として働くColdFusionの在り方に着目していきます。というわけで今回は、とあるブラウザベースのプロトタイプシステムをColdFusion9.0.1で構築した事例をご紹介したいと思います。プラットフォームとしては1世代前ですが、ご容赦ください。
時は2010年。要件はこんな感じでした。
要件2がとっても芳ばしいですね!!
いろいろ考えた結果、Flexで開発することになりました。その当時もっともリッチで、要件に合致していると思われたためです。また、ソースがダウンロードできてしまうJavaScriptに比べると、ロジックを読みづらいことも重要な要素でした。
そのとき提案したシステム構成はこんな感じでした。
データの流れは、以下のような感じです。クライアントから、CFを介してDBやほかのマシンとやり取りをします。
Flexが持つBindingの仕組みを使い倒して、データをXMLに持たせれば、オンライン時とオフライン時のプログラムの動きの差異を最小限に抑えることができる、という目論見をもとに構築したものです。ColdFusionの役割は、
の3つでした。
A , C に関しては、APIやパフォーマンスの都合から、Javaでクラスを作り、CreateObjectで呼び出すことになりました。また、B に関しては、計算に時間がかかることからColdFusionのイベントゲートウェイの仕組みを採用し、RDBに持たせた処理フラグが完了状態になるまでポーリングで待つ、という処理にしました。
Javaを使っても、Jarファイル内で異常が起きたら必ず例外をthrowするようにして、<cftry>タグで呼び出し部分を囲んでおけば、異常が起きてもColdFusionでスタックトレースを追うことができるので、デバッグに不満を感じることはありませんでした。
ざっと雰囲気が伝わるように、疑似コードを作りましたので、内容を簡単に紹介します。ソースをダウンロードしてご覧ください。
◆XMLやりとり CF側
XMLを受け取って何かする、シンプルなコードを作ろうということで、
を作りました。(id:otsuka, パスワード:passwdでログインできます)
websystem.cfcというソースが本体で、これに処理ごとに様々なソースをincludeしていく構成です。Flash Remotingは、Object型も送信できるのですが、難しい型を利用すると、クライアントのプラットフォームが変わった時にダメージが大きいと考え、XMLのかたちでやりとりしています。
<!---
* <U> checkUser
* <F> ユーザ情報確認
* <V> name="_userid" type="string" [i]ユーザID
name="_password" type="string" [i]パスワード
--->
<cffunction name="checkUser" access="private" returntype="String" >
<cfargument name="_userid" type="string" required="true">
<cfargument name="_password" type="string" required="true">
<cfset _strRet = "">
<!--- ユーザ情報を構築--->
<cfif _userid EQ "otsuka" AND _password EQ "passwd">
<cfscript>
_strRet = "<UserData><UserId>" & 1 & "</UserId>";
_strRet = _strRet & "<firstName>" & "健太" & "</firstName>";
_strRet = _strRet & "<middleName>" & "" & "</middleName>";
_strRet = _strRet & "<lastName>" & "大塚" & "</lastName>";
_strRet = _strRet & "<Belong>" & "構造計画研究所" & "</Belong>";
_strRet = _strRet & "<Authorize>" & "システム管理者" & "</Authorize>";
_strRet = _strRet & "</UserData>";
</cfscript>
<cfelse>
<!--- ログインに失敗した場合 --->
<cfscript>
_strRet = "";
</cfscript>
</cfif>
<cfreturn _strRet>
</cffunction>
◆XMLやりとり Flex側
お手本通りの構成です。設定は、コンパイラの -servicesオプションで外部ファイル(services-config.xml)を参照させているので、ソースの記述は少ないです。動的に設定を変えることが想定される場合は、直接ソースに設定を記述するほうがよいと思います。
FlexXmlSample.mxmlの上に
があり、遷移していく構成です。
ログイン処理は、Dlg_Login.mxml::btnEnter_clickHandlerに記述されています。
ログインに成功した場合、ユーザデータをXMLからActionscriptのオブジェクトに変換し、そのうえでStateの機能を使って画面を遷移させるようになっています。
こちらは、RemoteObjectの定義です。
sourceとして、CfXmlServer.websystem(コンポーネント名)を指定します。
◆コンパイル時の注意
Flex4.5で作ったプロジェクトなので、お手元のFlexのバージョンによっては、以下のような警告が出る場合がありますが、OKを押下していただいて問題ありません。
◆crossdomain.xmlについて
ColdFusionのルートディレクトリには、crossdomain.xmlというファイルがあります。
これは、Flexが外部のWebサーバのリソースにアクセスする場合の設定が書かれているファイルです。dtdが http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd に公開されています。どんな種類のコンテンツへのアクセスを許すか、どんなドメインのどのポートへのアクセスを許すか、といった設定を書くことができます。
詳細は、
http://help.adobe.com/en_US/Flex/4.0/UsingSDK/WS2db454920e96a9e51e63e3d11c0bf6167e-7fe9.html#WS2db454920e96a9e51e63e3d11c0bf69084-7f2b
などにあります。
ファイル名 | ファイルサイズ | ||
---|---|---|---|
Download | cfbridge1.zip | 2.3Mb | ・CF用 サンプルCFC (CfXmlServerフォルダ内) ・Flash Builder用プロジェクトフォルダ(FlexXmlSample) |
触ったことはないのですが、Flash Remotingを.Net Frameworkから使えるようにしよう、という試みもあるようです。http://code.google.com/p/fluorinefx/ データが圧縮されて普通のSOAPなどよりは速いはずなので、試さなければ、と思いつつ時間だけが過ぎていきます(反省)。
ColdFusion10から、Axis2が実装レベルで使えるようになったので、.Net FrameworkとCFとの連携で困ることはもうあまりないと思うのですが、話題として取りあげました。
今回はこれにておしまいです。次回は、CFAjaxProxyを使った事例についてご紹介したいと思います。