以我的理解为OnCFCRequest方法功能的问题

时间:2019-04-11 23:29:13

标签: coldfusion coldfusion-10 lucee

当我将filter参数传递给单独的函数以用于搜索时,此示例无法正常工作

像这样

  

函数Search的无效调用,第4个参数(过滤器)的类型无效,无法转换字符串[{“ groupOp”:“ AND”,“ rules”:[{“ field”:“ errorid”,“ op“:” eq“,” data“:” 1“},{” field“:” line“,” op“:” eq“,” data“:...]类型为[struct] < / p>

我这样称呼它:

#SearchOptions(arguments.filters)#

来自功能

<cfset filters = {"groupOp":"AND","rules":[{"field":"template","op":"eq","data":"a"},{"field":"error_type","op":"eq","data":""}]}>

<cfdump var="#filters#">
<cfoutput>
    <cfloop from="1" to="#arrayLen(filters.rules)#" index="i">
        #i#
        <cfset dataArr = filters.rules[i]>
        <cfloop collection="#dataArr#" item="key">
            #key#   
        </cfloop>
    </cfloop>   
</cfoutput>

我的应用程序中有一个onCFCRequest函数

<cffunction name="onCFCRequest" access="public" returntype="void" output="true" hint="I process the user's CFC request.">
    <cfargument name="component" type="string" required="true" hint="I am the component requested by the user." />
    <cfargument name="methodName" type="string" required="true" hint="I am the method requested by the user." />
    <cfargument name="methodArguments" type="struct" required="true" hint="I am the argument collection sent by the user." />
    <cfif !structKeyExists( application.apiCache, arguments.component )>
        <cfset application.apiCache[ arguments.component ] = createObject( "component", arguments.component ).init() />
    </cfif>
    <cfset local.cfc = application.apiCache[ arguments.component ] />
    <cfinvoke returnvariable="local.result" component="#local.cfc#" method="#arguments.methodName#" argumentcollection="#arguments.methodArguments#" />
    <cfset local.responseData = "" />
    <cfset local.responseMimeType = "text/plain" />
    <cfif structKeyExists( local, "result" )>
        <cfparam name="url.returnFormat" type="string" default="#getMetaData( local.cfc[ arguments.methodName ] ).returnFormat#" />
        <cfif ( (url.returnFormat eq "json") && !structKeyExists( url, "callback" ) )>
            <cfset local.responseData = serializeJSON( local.result ) />
            <cfset local.responseMimeType = "text/x-json" />
        <cfelseif ( (url.returnFormat eq "json") && structKeyExists( url, "callback" ) )>
            <cfset local.responseData = ( "#url.callback#(" & serializeJSON( local.result ) & ");" ) />
            <cfset local.responseMimeType = "text/javascript" />
        <cfelseif (url.returnFormat eq "wddx")>
            <cfwddx action="cfml2wddx" input="#local.result#" output="local.responseData" />
            <cfset local.responseMimeType = "text/xml" />
        <cfelse>
            <cfset local.responseData = local.result />
            <cfset local.responseMimeType = "text/plain" />
        </cfif>
    </cfif>
    <cfset local.binaryResponse = toBinary( toBase64( local.responseData ) ) />
    <cfheader name="content-length" value="#arrayLen( local.binaryResponse )#" />
    <cfcontent type="#local.responseMimeType#" variable="#local.binaryResponse#" />
</cffunction>

1 个答案:

答案 0 :(得分:3)

我从Ben Nadel blog中认识到这种模式。您在问题中发布的代码缺少两个重要部分。首先,cfinvoke从您的application.apiCache对象中调用的方法-对该方法的调用失败,并引发异常。其次是调用此方法的JavaScript代码。

实际上,错误的原因很简单。当您传递JavaScript对象时,您的JavaScript代码可能会将数据作为字符串传递。因为调用了JSON.stringify或因为使用了某种“魔术”库,所以将该对象序列化为字符串。

解决方案是在ColdFusion函数的第四个参数(根据错误消息命名的过滤器)上调用DeserializeJSON。我自己使用如下代码。只有将参数成功转换为结构,bSave才会成为true

当函数中有cfargument个标记时,必须相应地将相关标记的type属性更改为string

<cfset local.struVals = {}>
<cfset local.bSave = false>

<cftry>
  <cfset local.struVals = DeserializeJSON( Arguments.filters )>

  <cfset local.bSave = true>

  <cfcatch></cfcatch>
</cftry>

<cfif local.bSave>

</cfif>