flex - كيفية تمرير "Null"(لقب حقيقي!) إلى خدمة SOAP على الويب في ActionScript 3؟




coldfusion wsdl (6)

لدينا موظف اسمه هو 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)
  • فليكس 3.5
  • ActionScript 3
  • ColdFusion 8

لاحظ أن الخطأ لا يحدث عند استدعاء webservice ككائن من صفحة ColdFusion.


تتبعها

في البداية اعتقدت أن هذا كان علة الإكراه حيث كان يتم الحصول على "null" بالإكراه إلى "null" وكان اختبار "null" == null يمر. ليست كذلك. كنت قريبة ، لكنني مخطئ للغاية. اسف بشأن ذلك!

لقد فعلت ذلك منذ الكثير من تافه على wonderfl.net وتتبع من خلال التعليمات البرمجية في mx.rpc.xml.* . في السطر 1795 من XMLEncoder (في المصدر 3.5) ، في setValue ، setValue كل XMLEncoding إلى

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

وهو في الأساس نفس الشيء:

currentChild.appendChild("null");

هذا الرمز ، وفقا لخاصية الكمان الأصلي ، يقوم بإرجاع عنصر XML فارغ. لكن لماذا؟

سبب

وفقا FLEX-33664 جوستين ماكلين على تقرير الخطأ 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" ، فإنه أولاً تحويله إلى عنصر XML الجذر بنص null ثم ثم يختبر هذا العنصر مقابل حرفية خالية. هذا اختبار ضعيف للمساواة ، لذا إما أن XML المحتوي على null يتم فرضه على النوع الفارغ ، أو يتم فرض نوع null على عنصر xml root يحتوي على السلسلة "null" ، ويمر الاختبار حيث يجب أن تفشل. قد يكون أحد الإصلاحات هو استخدام اختبارات المساواة الصارمة دائمًا عند التحقق من XML (أو أي شيء ، فعلاً) لـ "nullness".

حل

الحل المعقول الوحيد الذي يمكنني التفكير فيه ، وهو اختصار لإصلاح هذا الخطأ في كل إصدار من Actionn ، هو اختبار الحقول لـ "null" والخروج منها كقيم CDATA .

تعتبر قيم CDATA هي الطريقة الأكثر ملائمة لتحوير قيمة النص بالكامل والتي قد تتسبب في مشاكل التشفير / فك التشفير. ترميز Hex ، على سبيل المثال ، مخصص للأحرف الفردية. تُفضل قيم CDATA عندما تفلت من النص الكامل للعنصر. السبب الأكبر لهذا هو أنه يحافظ على قابلية القراءة البشرية.


@ doc_180 كان المفهوم الصحيح ، إلا أنه يركز على الأرقام ، في حين أن الملصق الأصلي لديه مشاكل مع السلاسل.

الحل هو تغيير ملف mx.rpc.xml.XMLEncoder . هذا هو الخط 121

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

[نظرت في فليكس 4.5.1 SDK. قد تختلف أرقام الأسطر في إصدارات أخرى]

بشكل عام ، فشل التحقق من الصحة لأن "المحتوى فارغ" وبالتالي لا يتم إضافة الوسيطة الخاصة بك إلى حزمة SOAP الصادرة ؛ مما تسبب في خطأ المعلمة المفقودة.

يجب عليك توسيع هذا الفصل لإزالة التحقق من الصحة. ثم هناك كرة الثلج كبيرة أعلى السلسلة وتعديل SOAPEncoder لاستخدام XMLEncoder الخاص بك المعدلة ، ثم تعديل عملية لاستخدام SOAPEncoder الخاص بك المعدلة ، ومن ثم الخادمة WebService لاستخدام فئة العملية البديلة الخاصة بك.

قضيت بضع ساعات في ذلك ، ولكنني بحاجة للمضي قدمًا. ربما يستغرق الأمر يومًا أو يومين.

قد تتمكن فقط من إصلاح سطر XMLEncoder والقيام ببعض عمليات تصحيح القرد لاستخدام صفك الخاص.

سأضيف أيضًا أنه إذا قمت بالتبديل إلى استخدام RemoteObject / AMF مع ColdFusion ، يتم تمرير 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

منذ كان هناك سؤال حول كيفية التعامل مع قيمة فارغة هنا هو تطبيق عينة سريعة لشرح كيفية ارتباط سلسلة "خالية" بالكلمة المحجوزة فارغة.

<?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 إلى &#4E;&#75;&#6C;&#6C;


حسنًا ، أعتقد أن تطبيق Flex الخاص بـ SOAP Encoder يبدو وكأنه إجراء تسلسل قيم فارغة بشكل غير صحيح. لا يبدو أن تسلسلها كسلسلة فارغة حل جيد. يبدو أن الإصدار الصحيح رسميًا هو تمرير قيمة فارغة كالتالي:

<childtag2 xsi:nil="true" />

لذا فإن قيمة "Null" لن تكون سوى سلسلة صالحة ، وهذا هو بالضبط ما تبحث عنه.

أعتقد أن الحصول على هذا الثابت في Apache Flex لا ينبغي أن يكون من الصعب القيام به. أود أن أوصي بفتح قضية جيرا أو الاتصال بالشباب من القائمة البريدية أباتشي فليكس. ومع ذلك فإن هذا من شأنه فقط إصلاح جانب العميل. لا أستطيع أن أقول إن كان ColdFusion سيكون قادراً على العمل مع قيم فارغة مشفرة بهذه الطريقة.

راجع أيضًا مشاركة مدونة Radu Cotescu كيفية إرسال قيم فارغة في طلبات soapUI .


على ملاحظة xkcd ، يحتوي موقع Bobby Tables على نصيحة جيدة لتجنب التفسير غير الصحيح لبيانات المستخدم (في هذه الحالة ، السلسلة "Null") في استعلامات SQL بلغات مختلفة ، بما في ذلك ColdFusion .

ليس من الواضح من السؤال أن هذا هو مصدر المشكلة ، وبالنظر إلى الحل الذي لوحظ في تعليق على الإجابة الأولى (تضمين المعلمات في بنية) ، يبدو من المحتمل أنه شيء آخر.


قد تكون المشكلة في برنامج ترميز SOAP الخاص بـ Flex. حاول توسيع برنامج التشفير SOAP في تطبيق Flex الخاص بك وتصحيح البرنامج لمعرفة كيفية معالجة قيمة فارغة. تخميني هو أنه يتم تمريره كـ NaN (ليس رقم). هذا سوف تفشل رسالة SOAP unmarshalling عملية في وقت ما (على الأخص في خادم JBoss 5 ...). أتذكر تمديد برنامج التشفير SOAP وإجراء فحص صريح على كيفية التعامل مع NaN.

(في ملاحظة جانبية ، هل من المتوقع أن تفعل شيئًا مفيدًا إذا كان معرف الموظف هو Null ، فهل هذه ليست مشكلة متعلقة بالتحقق من الصحة؟ قد أكون مخطئًا ، بما أنني لا أعرف المتطلبات ...)