bil*_*ill 4603 apache-flex coldfusion soap wsdl actionscript
我们有一名姓氏为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>
Run Code Online (Sandbox Code Playgroud)
可爱,对吧?
参数类型是string
.
我在用:
请注意,从ColdFusion页面调用Web服务作为对象时,不会发生错误.
Ben*_*rns 1094
起初我以为这是一个强制性的错误,在那里null
被强迫"null"
并且"null" == null
正在经历的考验.不是.我很亲密,但非常非常错.对于那个很抱歉!
我已经在wonderfl.net上进行了大量的调整,并在代码中进行了跟踪mx.rpc.xml.*
.在XMLEncoder
(在3.5源中)的第1795行setValue
,所有的XMLEncoding归结为
currentChild.appendChild(xmlSpecialCharsFilter(Object(value)));
Run Code Online (Sandbox Code Playgroud)
这基本上与:
currentChild.appendChild("null");
Run Code Online (Sandbox Code Playgroud)
根据我原来的小提琴,这段代码返回一个空的XML元素.但为什么?
根据评论者Justin Mclean关于错误报告FLEX-33664的说法,以下是罪魁祸首(请参阅我的小提琴中的最后两个测试来验证这一点):
var thisIsNotNull:XML = <root>null</root>;
if(thisIsNotNull == null){
// always branches here, as (thisIsNotNull == null) strangely returns true
// despite the fact that thisIsNotNull is a valid instance of type XML
}
Run Code Online (Sandbox Code Playgroud)
当currentChild.appendChild
传递字符串时"null"
,它首先将其转换为带有文本的根XML元素null
,然后针对空文字测试该元素.这是一个弱的相等性测试,因此要么将包含null的XML强制转换为null类型,要么将null类型强制转换为包含字符串"null"的根xml元素,并且测试通过它可能失败的地方.一个修复可能是在检查XML(或任何真正的)"nullness"时始终使用严格的相等性测试.
CDATA值是改变整个文本值的最合适方式,否则会导致编码/解码问题.例如,十六进制编码适用于单个字符.当您转义元素的整个文本时,首选CDATA值.最大的原因是它保持了人类的可读性.
Ale*_*puy 296
在xkcd上,Bobby Tables网站提供了很好的建议,可以避免在各种语言(包括ColdFusion)的SQL查询中不正确地解释用户数据(在本例中为字符串"Null").
从问题中不清楚这是问题的根源,并且考虑到对第一个答案的评论中指出的解决方案(将参数嵌入到结构中),似乎它可能是其他东西.
Jef*_*ser 128
@ doc_180有正确的概念,除了他专注于数字,而原始海报有字符串的问题.
解决方案是更改mx.rpc.xml.XMLEncoder
文件.这是第121行
if (content != null)
result += content;
Run Code Online (Sandbox Code Playgroud)
[我查看了Flex 4.5.1 SDK; 行号可能在其他版本中有所不同]
基本上,验证失败是因为'content为null',因此您的参数不会添加到传出的SOAP数据包中; 从而导致缺少参数错误.
您必须扩展此类以删除验证.然后链上有一个大雪球,修改SOAPEncoder以使用修改后的XMLEncoder,然后修改Operation以使用修改后的SOAPEncoder,然后对WebService进行moidfying以使用备用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>
Run Code Online (Sandbox Code Playgroud)
这是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>
Run Code Online (Sandbox Code Playgroud)
跟踪输出是:
使用!=条件,null string不等于null保留字
使用==条件,null string不等于null保留字
使用===条件,null string不等于null保留字
doo*_*gle 65
将所有字符转换为其十六进制实体等效项.在这种情况下,Null
将被转换为E;KC;C;
And*_*ett 51
null
在ActionScript中对值进行字符串化将为字符串提供字符串"NULL"
.我怀疑是有人决定,因此,一个好主意,将字符串解码"NULL"
为null
,导致你在这里看到的破损-可能是因为他们在传递null
对象和获取字符串在数据库中,当他们不想(所以一定要检查那种bug).
Mar*_*ark 39
作为一个hack,你可以考虑在客户端进行特殊处理,将'Null'字符串转换为永远不会发生的字符串,例如,XXNULLXX并在服务器上转换回来.
它不漂亮,但它可以解决这种边界情况的问题.
Chr*_*utz 31
好吧,我猜Flex的SOAP Encoder实现似乎错误地序列化了空值.将它们序列化为String Null似乎不是一个好的解决方案.正式版本似乎是传递null值为:
<childtag2 xsi:nil="true" />
Run Code Online (Sandbox Code Playgroud)
因此,"Null"的值只不过是一个有效的字符串,这正是您正在寻找的.
我想在Apache Flex中修复这个问题不应该那么难.我建议打开一个Jira问题或联系apache-flex邮件列表的人.然而,这只会修复客户端.我不能说ColdFusion是否能够使用这种方式编码的空值.
另请参阅Radu Cotescu的博客文章如何在soapUI请求中发送空值.
SPi*_*com 22
它是一个kludge,但假设有一个最小长度SEARCHSTRING
,例如2个字符,第二个字符substring
的SEARCHSTRING
参数,并将其作为两个参数传递:SEARCHSTRING1 ("Nu")
并且SEARCHSTRING2 ("ll").
Concatenate
在执行查询到数据库时它们一起返回.