flex 如何在ActionScript 3中將“Null”(一個真正的姓氏!)傳遞給SOAP Web服務?
在xkcd註釋中 , Bobby Tables網站提供了很好的建議,可以避免在各種語言(包括ColdFusion )的SQL查詢中對用戶數據(在本例中為字符串“Null”)的不正確解釋。
從問題中不清楚這是問題的根源,並且考慮到對第一個答案的評論中指出的解決方案(將參數嵌入到結構中),似乎它可能是其他東西。
我們有一名姓氏為Null的員工。 當該姓氏用作搜索詞時(現在經常發生),我們的員工查找應用程序將被終止。 收到的錯誤(感謝Fiddler!)是:
<soapenv:Fault>
<faultcode>soapenv:Server.userException</faultcode>
<faultstring>coldfusion.xml.rpc.CFCInvocationException: [coldfusion.runtime.MissingArgumentException : The SEARCHSTRING parameter to the getFacultyNames function is required but was not passed in.]</faultstring>
可愛,對吧?
參數類型是string
。
我在用:
- WSDL(SOAP)
- Flex 3.5
- ActionScript 3
- ColdFusion 8
請注意,從ColdFusion頁面調用Web服務作為對象時,不會發生錯誤。
@ doc_180有正確的概念,除了他專注於數字,而原始海報有字符串的問題。
解決方案是更改mx.rpc.xml.XMLEncoder
文件。 這是第121行
if (content != null)
result += content;
[我查看了Flex 4.5.1 SDK; 行號可能在其他版本中有所不同]
基本上,驗證失敗是因為'content為null',因此您的參數不會添加到傳出的SOAP數據包中; 從而導致缺少參數錯誤。
您必須擴展此類以刪除驗證。 然後鏈上有一個大雪球,修改SOAPEncoder以使用修改後的XMLEncoder,然後修改Operation以使用修改後的SOAPEncoder,然後模擬WebService以使用備用Operation類。
我花了幾個小時,但需要繼續前進。 這可能需要一兩天時間。
您可以只修復XMLEncoder行並進行一些猴子修補以使用您自己的類。
我還要補充一點,如果你切換到使用帶有ColdFusion的RemoteObject / AMF,則傳遞null並沒有問題。
11/16/2013更新 :
我最後一篇關於RemoteObject / AMF的評論還有一個新增內容。 如果您使用的是CF10; 然後從服務器端對像中刪除對像上具有空值的屬性。 因此,您必須在訪問之前檢查屬性是否存在,否則您將收到運行時錯誤。 像這樣檢查:
<cfif (structKeyExists(arguments.myObject,'propertyName')>
<!--- no property code --->
<cfelse>
<!--- handle property normally --->
</cfif>
這是CF9的行為變化; 其中null屬性將變為空字符串。
編輯12/6/2013
由於存在關於如何處理空值的問題,因此這是一個快速示例應用程序,用於演示字符串“null”如何與保留字null相關聯。
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" initialize="application1_initializeHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected function application1_initializeHandler(event:FlexEvent):void
{
var s :String = "null";
if(s != null){
trace('null string is not equal to null reserved word using the != condition');
} else {
trace('null string is equal to null reserved word using the != condition');
}
if(s == null){
trace('null string is equal to null reserved word using the == condition');
} else {
trace('null string is not equal to null reserved word using the == condition');
}
if(s === null){
trace('null string is equal to null reserved word using the === condition');
} else {
trace('null string is not equal to null reserved word using the === condition');
}
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</s:Application>
跟踪輸出是:
使用!=條件,null string不等於null保留字
使用==條件,null string不等於null保留字
使用===條件,null string不等於null保留字
在ActionScript對null
值進行字符串化將使字符串"NULL"
。 我懷疑有人已經決定將字符串"NULL"
解碼為null
是一個好主意,導致你在這裡看到的破壞 - 可能是因為他們傳入null
對象並在數據庫中獲取字符串,他們不想那樣(所以一定要檢查那種bug)。
好吧,我猜Flex的SOAP Encoder實現似乎錯誤地序列化了空值。 將它們序列化為String Null似乎不是一個好的解決方案。 正式版本似乎是傳遞空值為:
<childtag2 xsi:nil="true" />
所以“Null”的值只不過是一個有效的字符串,這正是你要找的。
我想在Apache Flex中修復這個問題不應該那麼難。 我建議打開一個Jira問題或聯繫apache-flex郵件列表的人。 然而,這只會修復客戶端。 我不能說ColdFusion是否能夠使用這種方式編碼的空值。
另請參閱Radu Cotescu的博客文章如何在soapUI請求中發送空值 。