flex - ActionScript 3如何传递正确的"Null"字符串( 雇员合适的姓氏) 给SOAP web服务?

  显示原文与译文双语对照的内容

我们有一个姓为空的雇员。 当他的姓氏被用作搜索项( 现在经常是这样) 时,他杀死了我们的雇员查找应用程序。 收到的错误( 感谢 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>

,哈哈?

参数的类型是字符串。

我用的是:

  • ( 肥皂) 。
  • Flex 3.5
  • ActionScript 3
  • ColdFusion 8

注意,当从ColdFusion页面调用 web service作为对象时,错误不会发生。

时间:

跟踪它

起初我认为这是一个强制 Bug,其中 null 被强制到 "null",而 "null" == null的测试正在通过。 不是的,我已经了,但非常严重。 抱歉 !

我已经做了很多摆弄 wonderfl.net,并通过 mx.rpc.xml.* 代码跟踪。 线 1795 XMLEncoder ( 在 3.5源中) setValue, 所有的XMLEncoding归结为


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

这与下面的基本相同:


currentChild.appendChild("null");

根据我原来的fiddle,这个代码返回一个空的XML元素。 但是为什么?

原因

根据 Justin Mclean在 Bug 报告 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的XML被强制为空类型,或者将空类型强制为包含字符串"空"的根XML元素,并且测试传递的结果应该失败。 一种修复可能是总是使用严格平等当检查xml( 或者什么,真的)" nullness测试。"

解决方案

我能想到的唯一合理的解决方案,缺乏解决这个 Bug actionscript的在每一个该死的版本,是测试领域"空"和逃脱 cdata值。

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

问题可能在flex编码器的SOAP中。 尝试在你的Flex应用程序中扩展SOAP编码器并调试程序以查看如何处理空值。 我的猜测是,它作为 NaN ( 不是数字) 传递。 这将在一段时间内搞乱SOAP消息编解码过程。 我记得扩展了SOAP编码器并对如何处理NaN进行了显式检查。

( 顺便说一句,如果员工标识是空的,你期望做一些有用的事情,这不是一个验证问题? 我可能是错误的,因为我不知道需求。。

xkcd注意, 鲍比表网站好的建议避免不当的解释用户数据( 在本例中,字符串"零") 在各种语言的sql查询,包括 ColdFusion

目前尚不清楚的问题,这是问题的根源,并给予解决方案在评论指出第一个答案( 在结构中嵌入参数) 似乎是别的东西。

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

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


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

[I looked at Flex yf_num_ea2c4njoge888888_yf_num SDK; line numbers may differ in other versions ]

基本上,验证失败,因为'内容为空'和你的参数没有被添加到传出的SOAP数据包;因此导致丢失的参数错误。

你必须扩展该类以删除验证。 然后在链上有一个大的雪球,修改SOAPEncoder来使用你修改的XMLEncoder,然后修改操作以使用你修改的SOAPEncoder,然后 moidfying web service使用你的替代操作类。

我花了几个小时的时间,但是需要继续。 这可能需要一天或者两天。

你可以修复XMLEncoder行并做一些小改动来使用你自己的类。

我也将增加,如果你使用 remoteobject switch/amfcoldfusion,零是通过没有问题。


11/16/2013 更新:

最近我在关于 remoteobject/amf的评论中还添加了一个新的评论。 如果使用的是 CF10 ;则从服务器端对象删除具有空值的属性。 因此,在访问属性之前,你必须检查属性是否存在,否则会得到一个运行时错误。 检查如下:


<cfif (structKeyExists(arguments.myObject,'propertyName')>
 <!--- no property code --->
<cfelse>
 <!--- handle property normally --->
</cfif>

这是来自CF9的行为更改;空属性将变成空字符串。


编辑 12/6/2013

由于这里有一个关于空值的问题,这里是一个快速示例应用程序,用来演示字符串"空"如何与保留字相关。


<?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>

跟踪输出为:

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

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

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

将所有字符转换为它们的hex-entity等价。 在这种情况下,Null 将被转换为 &#4E;&#75;&#6C;&#6C;

Stringifying null 值在 ActionScript"NULL" 将字符串。 我怀疑有人决定,因此,一个好主意解码字符串 "NULL"null, 导致破损你看到--可能是因为他们通过 null 对象和数据库中获取字符串,当他们不希望( 所以,一定要检查那种 Bug ) 。

作为一个 hack,你可以考虑在客户端进行特殊处理,将'空'字符串转换为永远不会发生的事情,例如XXNULLXX和在服务器上转换。

它并不漂亮,但它可以解决这样一个边界案例的问题。

好吧,我猜,flex的soap编码的实现似乎序列化null值不正确。 将它们序列化为字符串空似乎并不是一个好的解决方案。 正式正确的版本似乎是传递空值为:


<childtag2 xsi:nil="true"/>

So value of"空"whenever nothing else than a valid string, which is exactly what you are & for.

我想在 Apache Flex中解决这个问题不应该那么难完成。 我建议打开一个Jira问题或者与apache-flex邮件服务器的人联系。 但是这将只修复客户端。 我不能说如果coldfusion将能够使用null值编码。

参见 Radu cotescu博客帖子 如何发送null值在soapui请求

组装机,但如果有一个最小长度searchstring,例如 2字符,字符串searchstring参数在第二个字符并传递两个参数: SEARCHSTRING1 ("nu") 和 SEARCHSTRING2 ("将") 。 在执行查询到数据库时将它们连接起来。

...