首页 文章

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

提问于
浏览
4515

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

9 回答

  • 1066

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

    <childtag2 xsi:nil="true" />
    

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

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

    另见Radu Cotescu的博客文章How to send null values in soapUI requests .

  • 237

    @ 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进行moidfying以使用备用Operation类 .

    我花了几个小时,但需要继续前进 . 这可能需要一两天时间 .

    您可以只修复XMLEncoder行并进行一些猴子修补以使用您自己的类 .

    我还要补充一点,如果你切换到使用带有ColdFusion的RemoteObject / AMF,则传递null并没有问题 .


    11/16/2013 update

    我最后一篇关于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保留字使用!= condition null字符串不等于null保留字使用== condition null字符串不等于null保留字使用===条件

  • 63

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

  • 126

    问题可能在于作为NaN(非数字)传递的Flex 's SOAP encoder. Try extending the SOAP encoder in your Flex application and debug the program to see how the null value is handled. My guess is, it' . 这有时会弄乱SOAP消息解组过程(最明显的是JBoss 5服务器......) . 我记得扩展了SOAP编码器并对NaN的处理方式进行了明确的检查 .

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

  • 21

    xkcd note上,Bobby Tables website对于避免在各种语言的SQL查询中对用户数据(在本例中为字符串"Null")的不正确解释提供了很好的建议,包括ColdFusion .

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

  • 293

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

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

  • 49

    's a kludge, but assuming there'是 SEARCHSTRING 的最小长度,例如2个字符, substring 是第二个字符的 SEARCHSTRING 参数,并将其作为两个参数传递: SEARCHSTRING1 ("Nu")SEARCHSTRING2 ("ll"). Concatenate 它们在执行查询到数据库时一起返回 .

  • 37

    追踪它

    起初我认为这是一个强制性的错误, null 被强迫 "null" 并且 "null" == null 的测试正在通过 . 不是 . I was close, but so very, very wrong. Sorry about that!

    我已经做了很多fiddling on wonderfl.net和跟踪 mx.rpc.xml.* 中的代码 . 在 XMLEncoder 的第1795行(在3.5源文件中),在 setValue 中,所有的XMLEncoding归结为

    currentChild.appendChild(xmlSpecialCharsFilter(Object(value)));
    

    这基本上与:

    currentChild.appendChild("null");
    

    根据我原来的小提琴,这段代码返回一个空的XML元素 . 但为什么?

    原因

    根据评论者贾斯汀·麦克莱恩的错误报告FLEX-33664,以下是罪魁祸首(请参阅我的fiddle中的最后两个测试来验证这一点):

    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的XML强制转换为null类型,要么将null类型强制转换为包含字符串"null"的根xml元素,并且测试通过它可能失败的地方 . 一个修复可能是在为"nullness."检查XML(或其他任何内容)时始终使用strict equality测试

    解决方案

    我能想到的唯一合理的解决方法,就是在每个该死的ActionScript版本中修复这个bug,就是测试"null"和 escape them as CDATA values. 的字段

    CDATA values are the most appropriate way to mutate an entire text value that would otherwise cause encoding/decoding problems. 例如,十六进制编码适用于单个字符 . 当您转义元素的整个文本时,首选CDATA值 . 最大的原因是它保持了人类的可读性 .

  • 30

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

相关问题