协慌网

登录 贡献 社区

如何在 ActionScript 3 中将 “Null”(一个真正的姓氏!)传递给 SOAP Web 服务?

我们有一名姓氏为 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 服务作为对象时,不会发生错误。

答案

追踪它

起初我认为这是一个强制错误,其中null被强制为"null"并且测试"null" == null正在传递。不是。 我很亲密,但非常非常错。对于那个很抱歉!

我已经在 wonderfl.net 上进行了大量的调整,并在mx.rpc.xml.*代码mx.rpc.xml.* 。在XMLEncoder第 1795 XMLEncoder (在 3.5 源代码中),在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(或任何真正的)“nullness” 时始终使用严格的相等性测试。

我能想到的唯一合理的解决方法,就是在每个该死的 ActionScript 版本中修复这个 bug,就是测试 “null” 字段并将它们作为CDATA 值转义。

CDATA 值是改变整个文本值的最合适方式,否则会导致编码 / 解码问题。例如,十六进制编码用于单个字符。当您转义元素的整个文本时,首选 CDATA 值。最大的原因是它保持了人类的可读性。

xkcd 注释中Bobby Tables 网站提供了很好的建议,可以避免在各种语言(包括ColdFusion )的 SQL 查询中对用户数据(在本例中为字符串 “Null”)的不正确解释。

从问题中不清楚这是问题的根源,并且考虑到对第一个答案的评论中指出的解决方案(将参数嵌入到结构中),似乎它可能是其他东西。

问题可能出在 Flex 的 SOAP 编码器中。尝试在 Flex 应用程序中扩展 SOAP 编码器并调试程序以查看如何处理 null 值。我的猜测是,它以NaN (非数字)传递。这有时会弄乱 SOAP 消息解组过程(最值得注意的是在JBoss 5 服务器......)。我记得扩展了 SOAP 编码器并对 NaN 的处理方式进行了明确的检查。

(另一方面,如果员工 ID 为 Null,您是否希望做一些有用的事情,这不是验证问题吗?我可能错了,因为我几乎不知道要求......)