注意:アプリケーションの REST 関連コンポーネントを変更したときは、必ずアプリケーションを更新してください。
ColdFusion Splendor では、サイトレベルの REST アプリケーションがサポートされ、プラグ可能なシリアライザーとデシリアライザーを使用できるようになりました。
ColdFusion 10 では、たとえアプリケーションが異なるホストに存在する場合でも、複数のアプリケーションで同じ名前を持つことはできません。ColdFusion Splendor では、REST 機能が強化され、異なるホストの複数のアプリケーションで同じ名前を持つことができます。また、仮想ホストごとにデフォルトのアプリケーション(REST サービスを含む)を 1 つ設定できます。
次のオプションのいずれかを使用して、REST サービスを含むディレクトリを登録できます。
- アプリケーション設定の自動登録
- ColdFusion Administrator コンソール
- ColdFusion Admin API
- restInitApplication メソッド
ColdFusion Splendor では、新しいアプリケーション設定の「自動登録」が導入されました。
- アプリケーションの自動登録を有効にする場合、autoregister を true に設定します。
<cfset this.restsettings.autoregister="true"/>
- servicemapping の指定はオプションです。servicemapping が指定されていない場合、"this.name"/アプリケーション名がデフォルトとして使用されます。
<cfset this.restsettings.servicemapping="testmapping"/>
- usehost または hostname を指定します。usehost 属性を true に設定すると、ホスト名は URL から解析され、使用されます。
<cfset this.restsettings.usehost=true/>
- host に明示的に名前を指定すると、ホスト名が作成されます。host が指定されていない場合は、usehost 名がデフォルトになります。
<cfset this.restsettings.host="www.adobe.com"/>
- isDefault を true に設定すると、そのアプリケーションがデフォルトアプリケーションになります。
<cfset this.restsettings.isDefault=true/>
usehost と host の両方が指定されていない場合、そのアプリケーションはホスト名なしで登録されます。アプリケーションに最初のリクエストが到達し、そのリクエストが REST リクエストでない場合、アプリケーションが開始され、登録されます。
|
最初のリクエスト自体が REST リクエストである場合、アプリケーションは開始されません。 |
- Administrator コンソールを使用して、REST 対応 CF コンポーネントを含むディレクトリを登録します。Adobe ColdFusion Splendor Administrator コンソール/データとサービス/REST サービスを選択します。
- ColdFusion が REST 対応 CF コンポーネントのセットを含むディレクトリを検索する際のルートパス(またはアプリケーションのパス)を参照して選択します。
(オプション)「サービスマッピング」セクションで、アプリケーション名の代わりに仮想マッピングを指定します。フォルダーに Application.cfc ファイルがあり、アプリケーション名が指定されている場合、アプリケーション名を使用してディレクトリ内の REST サービスを特定します。
(オプション)ホスト名を入力します。これにより、選択したアプリケーションをホストとマッピングできます。ホストごとにデフォルトアプリケーションを持つことができ、同じアプリケーション名を持つ複数のアプリケーションが異なるホストにマッピングできます。
- 「デフォルトアプリケーションとして設定する」オプションを設定することで、REST アプリケーションをデフォルトアプリケーションとして設定します。このオプションを選択することで、URI でサービスマッピングやアプリケーション名を指定する必要がなくなります。
- 「サービスを追加」ボタンをクリックして、ディレクトリの登録を完了します。
- 「アクティブな ColdFusion REST サービス」表示テーブルを表示して、アクティブなサービスのマッピングのリストを表示します。将来のサービスマッピングの編集または削除に、同じ表示テーブルを使用できます。
オプション 3:ColdFusion Admin API を使用した REST アプリケーションの登録
CFIDE.adminapi.extensions CFC で定義した関数を使用して、REST アプリケーションを管理できます。その関数を次に示します。
- registerRESTService(path[,serviceMapping[,host[,isdef]]]:この関数は、REST アプリケーションを登録します。ルートパスは、REST 対応 CF コンポーネントを含むディレクトリを指定します。オプションで、REST アプリケーションのサービスマッピング、ホスト名および isdefault を指定できます。
- getRESTServices():この関数は、ColdFusion Administrator で登録した REST サービスの配列を返します。
- deleteRESTService(rootPath):この関数は、ColdFusion Administrator で登録された REST アプリケーションのうち指定されたものを削除します。
- refreshRESTService(rootPath):REST 対応 CF コンポーネントに変更を加えた場合、この関数を呼び出すことで、登録されたアプリケーションを更新できます。
- getDefaultRestService():サーバー全体のデフォルトの REST アプリケーションを返します。
- getAllDefaultRESTServices:すべてのデフォルト REST サービスを返します。値は、パスとホストのペアの配列です。
オプション 4:restInitApplication メソッドを使用した REST アプリケーションの登録
また、メソッド restInitApplication を呼び出すことでも、REST アプリケーションを登録できます。
構文を次に示します:
restInitApplication(rootPath[,serviceMapping[,options]])
options はオプションの引数です。options 構造体で、次を渡すことができます:
host を明示的に指定することで登録する場合:
<cfset str=structNew()>
<cfset str.host = "www.site1.com:82">
<cfset str.isDefault = "true">
<cfscript>
RestInitApplication("C:¥dev¥ColdFusion¥cf_main¥cfusion¥wwwroot¥withhostAndDefault", "withhostAndDefault", str);
</cfscript>
<cfoutput> App registered </cfoutput>
useHost 属性を指定することで登録する場合:ホスト名は、リクエスト URL から抽出され、登録に使用されます。
<cfset str=structNew()>
<cfset str.useHost = "true">
<cfset str.isDefault = "true">
<cfscript>
RestInitApplication("C:¥dev¥ColdFusion¥cf_main¥cfusion¥wwwroot¥withhostAndDefault", "withhostAndDefault", str);
</cfscript>
<cfoutput> App registered </cfoutput>
|
このタスクを実行するのに、管理者権限は必要ありません。構文を次に示します。
restInitApplication(rootPath[,serviceMapping[,options]])
|
- options には、host、useHost、isDefault を指定できます。このオプションの使用方法は、autoRegister 機能と同じです。
- 既に Administrator モジュールを使用してアプリケーションを登録済みの場合、restInitApplication を呼び出してREST サービスを更新します。
- restDeleteApplication 関数を使用して REST サービスを削除します。構文は restDeleteApplication(rootPath) です。
application.cfc で、複合型のシリアライズおよびデシリアライズのための独自のハンドラーを登録できます。シリアライザーが指定されていない場合、ColdFusion は、デフォルトのシリアル化メカニズムを使用します。
例:次のパラメーターでシリアル化する必要のある電話帳がある場合:
- 主要なデータ構造は配列です。
- 配列の各要素は、構造体です。
- 構造体には、2 つの要素が含まれます。
- 1 番目は連絡先の名前で、2 番目はコードおよび電話番号を含む構造体です。
配列
構造体
[
name(String],
phoneNo(Struct)
[
code(String),
no(String)
]
]
構造体
[
name(String],
phoneNo(Struct)
[
code(String),
no(String)
]
]
デフォルトの ColdFusion シリアル化データは次のように表示されます。
<Array size="1"> <Item index="1"> <Struct> <Entry> <Key>Name</Key> <Value>Paul</Value> </Entry> <Entry> <Key>PhoneNo</Key> <Value> <Struct> <Entry> <Key>Code</Key> <Value>080</Value> </Entry> <Entry> <Key>No</Key> <Value>411150326</Value> </Entry> </Struct> </Value> </Entry> </Struct> </Item> </Array>
またこの例では、構造体のみを単純な形式でシリアル化し、次のような結果を得ることを目的とします。
<Array size="1"> <Item index="1"> <root> <Name>Paul</Name> <PhoneNo> <root> <Code>080</Code> <No>411150326</No> </root> </PhoneNo> </root> </Item> </Array>
強化された ColdFusion Splendor REST 機能により、ユーザーは、デフォルトのシリアル化メカニズムを使用する代わりに、プラグインのカスタムシリアライザーを使用できます。カスタムシリアライザーには、次の 4 つの関数があります。
- canSerialize:ブール値を返し、リクエストの「承認タイプ」を引数として取ります。カスタムシリアライザーに、渡された引数タイプにデータをシリアル化させたい場合、true を返すことができます。
- Serialize:主要なシリアル化ロジックは、この関数で実装される必要があります。canSerialize がリクエストに「True」を返す場合、ColdFusion はこの関数を使用してシリアル化します。canSerialize がリクエストに「false」を返す場合、ColdFusion はデフォルトのシリアル化メカニズムを使用してシリアル化します。
- CanDeserialize:ブール値を返し、リクエストの「コンテンツタイプ」を引数として取ります。カスタムシリアライザーにデータを逆シリアル化させたい場合、true を返すことができます。
- DeSerialize:主要な逆シリアル化ロジックは、この関数で実装される必要があります。canDeSerialize がリクエストに「True」を返す場合、ColdFusion はこの関数を使用して逆シリアル化します。canDeSerialize がリクエストに「false」を返す場合、ColdFusion はデフォルトの逆シリアル化関数を使用して逆シリアル化します。
次の CustomSerializer コード例は、上記で説明したシナリオ(電話帳のシリアル化/逆シリアル化のカスタマイズ)で結果を出すのに役立ちます。
<cfcomponent>
<cffunction name="serializeData" access="remote" returntype="String">
<cfargument name="arg" type="any" hint="The object to be serialized"/>
<cfargument name="type" type="string"
hint="The accept header of the request in array format. The order of types in the array is according to the priority of the MIME types in the header."/>
<cfif #type# eq "XML">
<cfif isStruct(#arg#)>
<cfset var result = "<root>">
<cfset var key = "">
<cfloop collection=#arg# item="key">
<cfset var result = result & "<" & #key# & ">">
<cfset var result = result & serializeXML(#arg[key]#, true)>
<cfset var result = result & "</" & #key# & ">">
</cfloop>
<cfset var result = result & "</root>">
<cfreturn result>
<cfelse>
<cfreturn serializeXML(#arg#)>
</cfif>
<cfelseif #type# eq "JSON">
<cfdump var="#arg.getClass().getName()#" output="console">
<cfif arg.getClass().getName() eq "java.lang.String">
<cfreturn "test" & #arg#>
<!---<cfelseif isStruct(#arg#)>
<cfdump var="#arg#" output="console" >
<cfset var kresult = "{">
<cfset var kkey = "">
<cfloop collection=#arg# item="key">
<cfset var kresult = kresult & "__" & #kkey# & "__">
<cfset var kresult = kresult & serializeJSON(#arg[kkey]#)>
<cfset var kresult = kresult & "</" & #kkey# & ">">
</cfloop>
<cfset var kresult = kresult & "}">
<cfreturn kresult>--->
<cfelse>
<cfreturn serializeJSON(#arg#)>
</cfif>
<cfelse>
<cfreturn serialize(#arg#, #type#)>
</cfif>
</cffunction>
<cffunction name="canSerialize" access="remote" returntype="boolean">
<cfargument name="type" type="string"/>
<cfif #type# eq "XML">
<cfreturn true>
<cfelseif #type# eq "JSON">
<cfreturn true>
<cfelse>
<cfreturn false>
</cfif>
</cffunction>
<cffunction name="canDeserialize" access="remote" returntype="boolean">
<cfargument name="type" type="string"/>
<cfif #type# eq "XML">
<cfreturn true>
<cfelseif #type# eq "JSON">
<cfreturn true>
<cfelse>
<cfreturn false>
</cfif>
</cffunction>
<cffunction name="deserializeData" access="remote" returntype="any">
<cfargument name="arg" type="String" hint="The string to be deserialized"/>
<cfargument name="type" type="String" hint="The content-type header of the request."/>
<cfargument name="returntype" type="String" required="false" defaultvalue="any"
hint="The expected type of data. It could be any for the contents of complex types such as Struct, array etc."/>
<cfif #type# equals "XML" and isXml(arg)>
<cfset var xmlDoc = xmlParse(arg)>
<cfif #xmlDoc.XmlRoot.XmlName# equals "root">
<cfset var result = StructNew()>
<cfset var numEntries = ArrayLen(xmlDoc.root.XMLChildren)>
<cfloop index="i" from="1" to=#numEntries#>
<!--- <cfdump var="#xmlDoc.root.XMLChildren[i].XMLChildren#" output="console" > --->
<cfset var key = xmlDoc.root.XMLChildren[i].XmlName>
<cfif "" eq Trim(xmlDoc.root.XMLChildren[i].XMLText)>
<cfset var value = deserializeXML(ToString(xmlDoc.root.XMLChildren[i].XMLChildren[1]), true)>
<cfelse>
<cfset var value = deserializeXML(xmlDoc.root.XMLChildren[i].XMLText, true)>
</cfif>
<cfset result[key] = value>
</cfloop>
<cfreturn result>
<cfelse>
<cfreturn deserializeXML(#arg#, true)>
</cfif>
<cfelse>
<cfreturn deserializeXML(#arg#, true)>
</cfif>
</cffunction>
</cfcomponent>
実装した CustomSerializer は、application.cfc で指定できます。
<cfset this.customSerializer="CustomSerializer">
|
注意:この新しいプラグ可能なシリアライザー/デシリアライザーは、RESTful Web サービスに限定されません。ColdFusion では、このプラグ可能なシリアライザー/デシリアライザーを使用できる新しい API を提供しています。以下のリストを参照してください。
|