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





coldfusion wsdl (9)


它是一个kludge,但假设SEARCHSTRING有一个最小长度,例如2个字符,则在第二个字符处对SEARCHSTRING参数进行substring ,并将其作为两个参数传递: SEARCHSTRING1 ("Nu")SEARCHSTRING2 ("ll"). 在对数据库执行查询时将它们Concatenate在一起。

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




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

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




好吧,我猜Flex的SOAP Encoder实现似乎错误地序列化了空值。 将它们序列化为String Null似乎不是一个好的解决方案。 正式版本似乎是传递空值为:

<childtag2 xsi:nil="true" />

所以“Null”的值只不过是一个有效的字符串,这正是你要找的。

我想在Apache Flex中修复这个问题不应该那么难。 我建议打开一个Jira问题或联系apache-flex邮件列表的人。 然而,这只会修复客户端。 我不能说ColdFusion是否能够使用这种方式编码的空值。

另请参阅Radu Cotescu的博客文章如何在soapUI请求中发送空值




ActionScriptnull值进行字符串化将使字符串"NULL" 。 我怀疑有人已经决定将字符串"NULL"解码为null是一个好主意,导致你在这里看到的破坏 - 可能是因为他们传入null对象并在数据库中获取字符串,他们不想那样(所以一定要检查那种bug)。




作为一个黑客,您可以考虑在客户端进行特殊处理,将“Null”字符串转换为永远不会发生的字符串,例如XXNULLXX并在服务器上转换回来。

它并不漂亮,但它可以解决这种边界情况的问题。




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

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




追踪它

起初我认为这是一个强制错误,其中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值。 最大的原因是它保持了人类的可读性。




将所有字符转换为其十六进制实体等效项。 在这种情况下, Null将被转换为&#4E;&#75;&#6C;&#6C;




REST几乎总是会更快。 SOAP的主要优点是它提供了一种服务机制来向客户描述自己,并宣传他们的存在。

REST更轻巧,可以使用几乎所有工具实现,从而带来更低的带宽和更短的学习曲线。 但是,客户必须知道要发送什么以及期望什么。

一般而言,当您向外部世界发布复杂或可能发生变化的API时,SOAP将更加有用。 除此之外,REST通常是更好的选择。





flex actionscript soap coldfusion wsdl