2012-02-28 80 views
6

我有一個現有的CFC在將結構傳遞給方法時工作正常。如何將STRUCT - 或 - JSON傳遞給Coldfusion CFC方法

問題是,我們現在還需要通過JSON將數據傳遞到相同的函數中。

這裏是CFC片段:

<cffunction 
    name="subscribeAPI" 
    access="remote" 
    returntype="struct" 
    returnformat="json" 
    output="false"> 

    <cfargument 
    name="structure" 
    type="struct" 
    required="true" 
    hint="data structure received from call"> 

<cfif StructKeyExists(arguments.structure, "listID") 
    AND len(arguments.structure.listID)> 
... 
</cfif> 

<cfreturn LOCAL /> 

下面是我們如何在結構傳遞:

<cfset preStruct = { 
    apiAction="Create", 
    listID="1463", 
    email="#form.cartEmail#", 
    firstname="#form.first_name#", 
    preCart="#now()#", 
    planDescription="#application.name.site#" 
    } 
/> 

<cfscript>voidReturn = application.goxObj.subscribeAPI(preStruct);</cfscript> 

現在,我們還需要在下面的通過,但顯然由於CFC預期結構而出現錯誤:

function HandleSubscribe(){ 
    $j.getJSON(
    "/com/list.cfc?wsdl", 
    { 
     method : "subscribeAPI", 
     action : "Create", 
     listID : $j("#listID").val(), 
     triggerKey : $j("#triggerKey").val(), 
     email : $j("#emailNL").val(), 
     firstname : $j("#firstnameNL").val() 
    }, 
    handleSubscribeCallback 
); 

}

如何成功傳入getJSON代碼片段?

謝謝。

回答

3

JSON只是一個字符串,因此您需要在方法調用到達實際服務層之前「處理」方法調用。

丹尼爾是正確的,你需要做的是創建一個圍繞你的服務的Web服務層包裝。

所以,你的服務的方法是這樣的:

<cffunction name="CreateSubscription" access="public" returntype="struct" output="false"> 
    <cfargument name="listID" required="true" type="numeric"> 
    <cfargument name="emailaddress" required="true" type="string"> 
    <cfargument name="firstname" required="true" type="string"> 

    <cfset var resultset = {success=false}> 

    <!--- Validate your listid and subscription details ---> 
    <!--- If Valid Then insert subscription ---> 
    <cfset resultset.success = true> 

    <!--- else ---> 
    <cfset resultset.message = 'kerboom!'> 

    <!--- only return what you need as a struct, not the whole local scope! ---> 
    <cfreturn resultset /> 
</cffunction> 

您的訂閱API看起來是這樣的:

<cffunction name="subscribeAPI" access="remote" returntype="struct" returnformat="json" output="false"> 

    <cfargument name="JSONPacket" type="string" required="true" hint="data structure received from call"> 
    <cfset var incomingData = deserializeJSON(arguments.JSONPacket)> 
    <cfset var resultset = {success=false,message='invalid data'}> 

    <cfif StructKeyExists(incomingData, "apiAction")> 
     <cfif incomingData.apiAction EQ "create"> 
      <!--- You should also check you have the required fields for the createSubscription method here too. ---> 
      <cfset resultset = subscriptionService.createSubscription(incomingData)> 
     </cfif> 
    <cfelse> 
     <cfset resultset.message = 'No API Action specified'> 
    </cfif> 

    <cfreturn resultset> 
</cffunction> 

所以你推JSON在訂閱API,將數據轉換成一個struct並確保您擁有所有正確的數據並將其傳遞給您的訂閱服務。訂閱服務中的createSubscription方法檢查是否存在listid並檢查該人是否已訂閱。如果列表正確且訂閱不存在,則將新訂閱插入到數據庫中,否則返回結果,以指示結構中出錯的API層將其轉換爲JSON並將其返回。

這樣做的好處是您可以在應用程序中重新使用服務,而無需通過API層,並且您的API層會將請求推送到正確的服務方法,並確保有適當的數據可用於他們。

不要傳遞本地範圍!在那裏可能會有一些東西流入,包括服務中的所有其他方法。只需要返回所需要的東西,而不是更多。

還有其他一些方法可以解決這個問題 - 例如,您可以將參數實際放入來自JSON的CFC的方法方法調用中。你可以使用cfajaxproxy在你的服務和你的javascript之間創建一個層,使你可以直接調用你的cfc方法作爲javascript函數。我相信在這些之上還有其他解決方案。請記住.... ColdFusion == Serverside,Javascript == clientside。將它們分開。在它們之間放置一層來處理通信。

希望有所幫助。

+0

我沒有託管API服務。只調用遠程API。 – 2012-02-28 23:02:57

+0

如果我使用這種方法,我看到你將cfargument改爲一個字符串類型。這不會打破我在結構中傳遞的另一個呼叫嗎? – 2012-02-28 23:03:46

+0

是的,但你不應該從應用程序內部調用api層。你應該直接調用服務層和createSubscription方法。此方法允許您將結構作爲參數集合傳遞。 – 2012-02-28 23:16:03

1

從原來的解決方案編輯:

它看起來並不像你可以傳遞一個JSON對象直接ColdFusion和有它解釋爲一個結構。你可以做的是建立在你的現有方法的包裝方法,它接受一個JSON字符串,然後將其反序列化到ColdFusion的一個結構中傳遞到您現有的方法:

<script> 
    var data = { dude: "wow"}; 
    $(function() { 
     $('#ajax').click(function() { 
      $.getJSON(
       "test.cfc", 
       { 
        method: "foo", 
        json: JSON.stringify(data) 
       }, 
       function(data) { 
        // so something with result 
       } 
      ); 
     }); 
    }) 
</script> 

而且ColdFusion的:

<cffunction name="foo" access="remote" returntype="Struct" returnformat="JSON"> 
    <cfargument name="json" type="string" /> 

     <cfset myStruct = DeserializeJSON(arguments.json) /> 

     <!--- now call your existing method passing it myStruct ---> 
</cffunction> 
+0

不幸的是,這是行不通的。儘管感謝您的回答。 – 2012-02-28 21:40:54

+0

請參閱我編輯的解決方案。 – 2012-02-28 22:33:49

+0

謝謝。我會試試這個。 – 2012-02-28 23:11:22

2

如果你想利用或是結構或JSON字符串作爲單個參數的方法,你可以這樣做......

<cffunction name="myFunction" access="remote" returntype="Struct" returnformat="JSON"> 
    <cfargument name="data" type="any" required="true"> 

    <cfif isJson(arguments.data)> 
     <cfset arguments.data = deserializeJSON(arguments.data) /> 
    </cfif> 

    <cfif NOT isStruct(arguments.data)> 
     <cfthrow message="argument must be structure or a json string" /> 
    </cfif> 

    ... 

</cffunction>