2014-02-24 26 views
3

我有一個CFC(稱爲proxy.cfc),我正在使用它作爲我編寫的一個簡單API的代理。一切都一帆風順,一些合作伙伴開始有效地使用API​​。驗證發佈到CFC的JSON

但是,一個試圖發佈數據的站點沒有發送有效的JSON,我似乎無法理解如何正常處理此錯誤。

被公佈爲URL PARAM可能是這樣一個有效的JSON字符串:

{"apicomponent":"proxyRemoteAdd","apimethod":"add","apiarguments":{"ph_num":1212,"rbpid":999,"ph_exch":555,"state":"HI","address_1":"123 Main Street","address_2":"","rmtid":"PON83","last_name":"Smith","test":1,"zip":999999,"first_name":"Joe","email":"[email protected]","city":"Honolulu","type":"SP","ph_area":995},"apiauthkey":"abc123"} 

這工作得很好。

但是,如果該字符串被截斷以任何理由:

{"apicomponent":"proxyRemoteAdd","apimethod":"add","apiarguments":{"ph_num":1212,"rbpid":999,"ph_exch":555,"state":"HI" 

我捕捉異常如下:異常:JSON解析失敗:JSON字符串結尾

這是從我的onError未來在Application.cfc中。我也添加一些代碼到它,如下所示隔離在的Application.cfc:

<cfif ARGUMENTS.EXCEPTION.MESSAGE IS "JSON parsing failure: Unexpected end of JSON string"> 
<!--- do some stuff here ---> 
</cfif> 

是最好的方式來處理該類型的錯誤?有沒有辦法將它傳遞給proxy.cfc文件,以便我可以將錯誤消息返回給發佈客戶端?現在Application.cfc正在捕獲它,甚至不讓我進入proxy.cfc文件。

更新 - 這是一些特定的代碼示例。這是我怎麼一直在測試,將說明得到的數據發佈方式:

<cfhttp url="https://www.domain.com/api/proxy.cfc" method="post" result="httpResult" charset="UTF-8"> 
    <cfhttpparam type="url" name="method" value="apiauth"/> 
    <cfhttpparam type="url" name="argumentCollection" value="#jsData#"/> 
</cfhttp> 

「apiauth」是在充當授權和代理的CFC的方法。 參數集合是一個JSON字符串,如下所示。它列出了一個組件(一個不同的CFC),該組件中的方法,訪問AP的用戶的authkey,然後是一個名爲apiarguments的JSON字符串,其中包含傳遞給列出的apicomponent的參數和數據。

代理CFC文件看起來是這樣的:

<cffunction name="apiauth" access="remote" returntype="any" output="false" returnFormat="JSON"> 
    <cfargument name="apicomponent" required="yes" type="string"/> 
    <cfargument name="apimethod" required="yes" type="string"/> 
    <cfargument name="apiauthkey" required="yes" type="string"/> 
    <cfargument name="apiarguments" required="yes" type="struct"/> 
    <cfset var LOCAL = {}/> 

    <cfif not isDefined("ARGUMENTS.apiauthkey")> 
     <cfreturn THIS.NewErrorResponse("Error 401 Malformed Request.") /> 
    </cfif> 
    <cfif not isDefined("ARGUMENTS.apicomponent")> 
     <cfreturn THIS.NewErrorResponse("Error 402 Malformed Request.") /> 
    </cfif>  
    <cfif not isDefined("ARGUMENTS.apimethod")> 
     <cfreturn THIS.NewErrorResponse("Error 403 Malformed Request.") /> 
    </cfif> 

     <cfset LOCAL.checkpwResult = FALSE/> 
     <cfset LOCAL.apicomponent = ARGUMENTS.apicomponent /> 
     <cfset LOCAL.apimethod = ARGUMENTS.apimethod /> 

在這一點上一些其他氟氯化碳的訪問檢查API密鑰和用戶ID#以確保它們可以訪問API。如果一切正常那裏得到的數據將傳遞給正確的組件/方法:

<cfinvoke component="#LOCAL.apicomponent#" method="#LOCAL.apimethod#" argumentcollection="#apiarguments#" returnvariable="LOCAL.Response.Data"/> 

然而,JSON異常正在此之前,CFC拋出甚至可以用的Application.cfc文件訪問。如果我在proxy.cfc中放置一個快速的cfmail來轉儲併發送參數,它甚至不會觸及它。

這裏的堆棧跟蹤的大塊:

coldfusion.runtime.JSONUtils $ JSONParseOverflowException:JSON解析失敗:在 coldfusion.runtime.JSONUtils $ ParserState.incrementOffset JSON字符串結尾(JSONUtils.java:1999 )at coldfusion.runtime.JSONUtils $ ParserState.incrementOffset(JSONUtils.java:1980)at coldfusion.runtime.JSONUtils.parseString(JSONUtils.java:1385)at coldfusion.runtime.JSONUtils.parseObject(JSONUtils.java:1074)at coldfusion .runtime.JSONUtils.parseStruct(JSONUtils.java:1178)位於coldfusion.runtime.JSONUtils.parseObject(JSONUtils.java:1059)處,位於coldfusion.runtime的coldfusion.runtime.JSONUtils.parseStruct(JSONUtils.java:1178)。在coldfusion.runtime.JSONUtils.deserializeJSON上的coldfusion.runtime.JSONUtils.deserializeJSON(JSONUtils.java:168)處的coldfusion.runtime.JSONUtils.parseJSON(JSONUtils.java:1028)處的JSONUtils.parseObject(JSONUtils.java:1059)(JSONUtils在Coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:442)處的coldfusion.filter.ComponentFilter.invoke(ComponentFilter.java:193)處的coldfusion.filter.FilterUtils.GetArgumentCollection(FilterUtils.java:50)在coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40) coldfusion.filter.PathFilter.invoke(PathFilter.java:112)at coldfusion.filter。在Coldfusion.filter.NoCacheFilter.invoke處的coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)處的coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)處的ExceptionFilter.invoke(ExceptionFilter.java:94)(NoCacheFilter .java:58)at co lfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)at coldfusion.xml.rpc.CFCServlet.invoke(CFCServlet.java:155)at coldfusion.xml .rpc.CFCServlet.doPost(CFCServlet.java:331)at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)at

+1

proxy.cfc是如何調用?即客戶端是否直接或通過其他方法將URL參數傳遞給它?你能張貼一些代碼來說明事件鏈嗎? – Leigh

+1

你可以使用'isJSON()'來檢查,然後給它們提供錯誤信息嗎? –

+0

我將用一些代碼示例更新主要問題 – Steve

回答

0

如果您的參數始終是JSON字符串,您應該可以將參數類型更改爲字符串,並以此方式傳遞它(它將使其通過Application.cfc),然後在使用isJSON的apiAuth函數中驗證它( ) - 無論如何,您應該驗證它是否針對惡意JSON,因此最初不會檢查isJSON()的代碼。這樣,您的API將提供有意義的反饋,並將所有代碼保留在應該的位置。

但是,如果您有其他用戶將一個實際的結構體傳遞給您的方法,那將無法工作。

你一定會想知道爲什麼JSON字符串被截斷。在猜測我會建議有可能會傳遞一些未轉義的字符,其中是早期截斷字符串...

+0

謝謝Marty。這是另一個用戶傳遞數據的地方 - 我在我的例子中只使用了argumentcollection ='',因爲我已經設置了我的測試。導致錯誤的用戶在他的測試環境中工作良好,然後在他投入生產時打破了,所以在這一點上(看到沒有其他人有問題),我會認爲這是他的最終目標。 – Steve