2012-02-28 12 views
6

Tôi có một CFC hiện có hoạt động tốt khi truyền các cấu trúc vào phương thức.Làm thế nào để vượt qua STRUCT - HOẶC - JSON để Coldfusion Phương pháp CFC

Vấn đề là, bây giờ chúng ta cũng cần truyền dữ liệu vào cùng một hàm thông qua JSON.

Dưới đây là đoạn mã 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 /> 

Đây là cách chúng ta vượt qua trong các cấu trúc:

<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> 

Bây giờ, chúng ta cũng cần phải vượt qua trong những điều sau đây nhưng rõ ràng gặp lỗi do CFC mong đợi một cấu trúc:

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 
); 

}

Làm cách nào để chuyển thành công đoạn mã getJSON?

Cảm ơn.

Trả lời

3

JSON chỉ là một chuỗi, vì vậy bạn cần phải "xử lý" cuộc gọi phương thức trước khi nó đến lớp dịch vụ thực tế của bạn.

Danimal phù hợp với điều bạn cần làm là tạo trình bao bọc lớp dịch vụ web xung quanh dịch vụ của bạn.

Vì vậy, phương pháp dịch vụ của bạn trông như thế này:

<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 thuê bao của bạn trông như thế này:

<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> 

Vì vậy, bạn đẩy JSON tại đăng ký API, chuyển đổi dữ liệu vào một struct và đảm bảo rằng bạn có sẵn tất cả dữ liệu phù hợp và chuyển cho dịch vụ đăng ký của bạn. Phương thức createSubscription trong dịch vụ thuê bao kiểm tra xem listid tồn tại và kiểm tra xem liệu người đó đã đăng ký chưa. Nếu danh sách là tốt và đăng ký không tồn tại, hãy chèn đăng ký mới vào cơ sở dữ liệu, nếu không trả lại kết quả cho biết điều gì đã xảy ra trong cấu trúc cho lớp API của bạn, chuyển đổi nó thành JSON và trả về nó.

Lợi ích của việc này là bạn có thể sử dụng lại các dịch vụ trong ứng dụng mà không cần phải đi qua lớp API và xử lý lớp api của bạn đẩy yêu cầu đến các phương thức dịch vụ chính xác và đảm bảo có dữ liệu thích hợp chúng.

Đừng bỏ qua phạm vi địa phương xung quanh!Có thể có một tải trọng của các công cụ trong đó bao gồm tất cả các phương pháp khác trong dịch vụ. Chỉ cần trả lại những gì được yêu cầu và không có gì hơn.

Có nhiều cách khác để bạn có thể giải quyết vấn đề này - ví dụ bạn thực sự có thể đặt đối số vào cuộc gọi phương thức phương thức trên CFC từ JSON. Bạn có thể sử dụng cfajaxproxy để tạo lớp giữa dịch vụ và javascript của bạn, cho phép bạn gọi trực tiếp các phương thức cfc của mình dưới dạng hàm javascript. Và tôi chắc chắn có những giải pháp khác trên đầu trang này.

Hãy nhớ .... ColdFusion == Serverside, Javascript == clientside. Tách chúng. Đặt một lớp giữa chúng để xử lý thông tin liên lạc.

Hy vọng điều đó sẽ hữu ích.

+0

Tôi không lưu trữ dịch vụ API. Chỉ thực hiện cuộc gọi đến một API từ xa. –

+0

Nếu tôi sử dụng phương pháp này, tôi thấy bạn đã thay đổi cfargument thành một chuỗi kiểu. Điều này sẽ không phá vỡ cuộc gọi khác của tôi mà đi qua một cấu trúc? –

+0

Có, nhưng sau đó bạn không nên gọi lớp api từ bên trong ứng dụng của bạn. Bạn nên gọi trực tiếp lớp dịch vụ và phương thức createSubscription. Phương thức này cho phép bạn chuyển một cấu trúc như một bộ sưu tập đối số. –

1

Sửa từ giải pháp gốc:

Nó không giống như bạn có thể vượt qua một đối tượng JSON trực tiếp đến Coldfusion và có nó hiểu là một Struct. Những gì bạn có thể làm là để tạo ra một phương pháp bao bọc xung quanh phương pháp hiện tại của bạn chấp nhận một chuỗi JSON, sau đó deserializes nó vào một struct trong Coldfusion để vượt qua trong phương pháp hiện tại của bạn:

<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> 

Và 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

Thật không may, điều này không làm việc. Cảm ơn câu trả lời của bạn mặc dù. –

+0

Xem giải pháp đã chỉnh sửa của tôi. –

+0

Cảm ơn. Tôi sẽ thử cái này –

2

Nếu bạn muốn có một phương pháp để lấy hoặc là một struct hoặc một chuỗi json như một đối số duy nhất, bạn có thể làm một cái gì đó giống như ...

<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>