我们有一位姓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)柔性3.5动作脚本3冷聚变8
请注意,当从ColdFusion页面作为对象调用Web服务时,不会发生错误。
追踪它
起初,我认为这是一个强制错误,其中null被强制为“null”,并且通过了“null”==null的测试。事实并非如此。我很接近,但非常非常错误。抱歉!
此后,我在wonderfl.net上做了很多手脚,并在mx.rpc.xml.*中跟踪代码。在XMLEncoder(在3.5源代码中)的1795行,在setValue中,所有XMLEncoding归结为
currentChild.appendChild(xmlSpecialCharsFilter(Object(value)));
其基本上与:
currentChild.appendChild("null");
根据我最初的想法,这段代码返回一个空的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
}
当currentChild.appendChild传递字符串“null”时,它首先将其转换为文本为null的根XML元素,然后根据null文本测试该元素。这是一个弱相等测试,因此,要么将包含null的XML强制为null类型,要么将null类型强制为包含字符串“null”的根XML元素,然后测试在可能失败的地方通过。一个解决办法可能是在检查XML(或任何东西)是否为“空”时始终使用严格的相等测试
解决方案除了在每个该死的ActionScript版本中修复这个bug之外,我能想到的唯一合理的解决方法是测试字段是否为“null”,并将其转义为CDATA值。
CDATA值是变异整个文本值的最合适方法,否则会导致编码/解码问题。例如,十六进制编码用于单个字符。当您转义元素的整个文本时,首选CDATA值。最大的原因是它保持了人类的可读性。
嗯,我猜SOAP编码器的Flex实现似乎错误地序列化了空值。将它们序列化为字符串Null似乎不是一个好的解决方案。正式正确的版本似乎是传递一个空值:
<childtag2 xsi:nil="true" />
因此,“Null”的值只不过是一个有效字符串,这正是您要查找的。
我想在ApacheFlex中修复这个问题应该不难。我建议打开Jira问题或联系apacheflex邮件列表中的人。然而,这只会修复客户端。我不能说ColdFusion是否能够处理这样编码的空值。
另请参阅Radu Cotescu的博客文章“如何在soapUI请求中发送空值”。