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



Answers

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

从问题中不清楚这是问题的根源,并且在第一个答案(将参数嵌入到结构中)的评论中给出解决方案中提到的解决方案时,似乎可能是其他问题。

Question

我们有一位姓氏为空的员工。 我们的员工查询应用程序在使用该姓氏作为搜索词时(这种情况现在经常发生)被终止。 收到的错误(谢谢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页面将webservice作为对象调用时,不会发生该错误。




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




@ doc_180有正确的概念,除了他专注于数字,而原始的海报有字符串的问题。

解决方案是更改mx.rpc.xml.XMLEncoder文件。 这是第121行

    if (content != null)
        result += content;

[我看了一下Flex 4.5.1 SDK; 行号可能在其他版本中有所不同]

基本上,验证因'内容为空'而失败,因此您的参数不会添加到传出的SOAP数据包中; 从而导致缺少参数错误。

您必须扩展此类才能删除验证。 然后,链上出现一个大大的雪球,修改SOAPEncoder以使用您的修改的XMLEncoder,然后修改操作以使用您的修改的SOAPEncoder,然后使WebService停止使用您的替代操作类。

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

您可能只需修复XMLEncoder行并修改一些猴子来使用自己的类。

我还会补充一点,如果您切换到使用ColdFusion的RemoteObject / AMF,则null传递没有问题。

11/16/2013更新

我最近还有一个关于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>

跟踪输出是:

空字符串不等于使用!=条件的空保留字

空字符串不等于使用==条件的空保留字

空字符串不等于使用===条件的空保留字




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

<childtag2 xsi:nil="true" />

所以“Null”的值只会是一个有效的字符串,这正是你正在寻找的。

我想在Apache Flex中修复这个问题不应该很难完成。 我会建议打开Jira问题或联系apache-flex邮件列表的人员。 但是,这只能解决客户端问题。 我不能说ColdFusion是否能够以这种方式编码空值。

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






Related