Питання Як пройти "Нуль" (справжнє прізвище!) До веб-служби SOAP в ActionScript 3?


У нас є працівник, прізвище якого називається 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.


4475
2017-12-16 00:42


походження


Це може не допомогти вам у вирішенні конкретної проблеми, але SOAP 1.2 дозволяє отримати нульові значення, див w3.org/TR/2001/WD-soap12-20010709/#_Toc478383513 - JensG
Я відчуваю, що це пов'язано з Дейвом Нуллом. - George Gibson
Принаймні, це не стосується Чака Норріса. Ось чому, щоб уникнути його в коді: codesqueeze.com/... - SDsolar
Чи вважає працівник зміною свого імені? - Tatranskymedved
Посилаючись на BBC: bbc.com/future/story/... - biziclop


Відповіді:


 Відстеження його вниз

Спочатку я подумав, що це дефект примусу null був примушений "null" і тест на "null" == null проходив Це не. Я був близьким, але дуже, дуже неправильно. Вибач за те!

З тих пір я багато зробив скрипка на wonderfl.net і простежити через код в mx.rpc.xml.*. У рядку 1795 року XMLEncoder (у джерелі 3,5), в setValue, всі XMLEncoding зводиться до

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

який по суті такий самий, як:

currentChild.appendChild("null");

Цей код, згідно з моєю оригінальною скрипкою, повертає порожній елемент XML. Але чому?

 Причина

За словами коментатора Джастіна Мкляна про звіт про помилку 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, що містить нуль, примушений до нульового типу, або нульовий тип примушений до кореневого елементу xml, що містить рядок "null", а тест проходить там, де воно, мабуть, може вийти з ладу. Один виправлення може бути завжди використовувати сувора рівність тести при перевірці XML (або що-небудь насправді) на "нульовість".

Рішення

Єдиний розумний шлях, яким я можу придумати, не виправляючи цю помилку в кожній проклятій версії ActionScript, полягає в тестуванні полів для "null" і уникнути їх як Значення CDATA. 

Значення CDATA - це найбільш підходящий спосіб змінити ціле текстове значення, яке в іншому випадку спричинить проблеми кодування / декодування. Наприклад, шестнадцатеричне кодування призначено для окремих символів. Значення CDATA є кращими, якщо ви викриваєте весь текст елемента. Найбільша причина цього полягає в тому, що вона підтримує читаність людей.


1049
2017-08-01 17:31





На примітка xkcd, the Веб-сайт Таблиці Боббі має хороший порад, щоб уникнути неналежної інтерпретації користувацьких даних (у цьому випадку рядок "Null") у запитах SQL на різних мовах, включаючи ColdFusion.

З питання про те, що це джерело проблеми, незрозуміло, і з урахуванням рішення, зазначеного в коментаря до першої відповіді (вбудовування параметрів у структуру), ймовірно, що це було щось інше.


286
2018-04-27 20:00





Проблема може бути в коді SOAP Flex. Спробуйте розширити SOAP-кодер у додатку Flex і налагодити програму, щоб побачити, як обробляється нульове значення. Я думаю, це пройшло як NaN (Не число). Це призведе до зриву SOAP-повідомлення немаршагування процесу коли-небудь (найбільш помітно в JBoss 5 сервер ...). Я пам'ятаю розширення SOAP-кодувача та проведення явної перевірки того, як обробляється NaN.

(На бічній ноті ви очікуєте зробити щось корисне, якщо ідентифікатор працівника - Null, чи це не питання перевірки? Я міг би помилятися, оскільки я навряд чи знаю вимогу ...)


235
2018-01-16 08:13



name = "Null", звичайно, корисний, і я не бачу, як він повинен бути пов'язаний з NaN. - eckes


@ doc_180 мав правильну концепцію, крім того, що він орієнтований на цифри, тоді як оригінальний плакат мав проблеми зі струнами.

Рішення - змінити mx.rpc.xml.XMLEncoder файл Це рядок 121

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

[Я подивився на Flex 4.5.1 SDK; номери рядків можуть відрізнятися в інших версіях]

В принципі, перевірка не виконується, оскільки "вміст null", і тому ваш аргумент не доданий до вихідного пакету SOAP; що спричиняє помилку пропущених параметрів.

Ви повинні продовжити цей клас, щоб видалити перевірку. Потім існує великий сніжний ком ланцюга, змінюючи SOAPEncoder для використання модифікованого XMLEncoder, а потім змінюючи операцію, щоб використовувати модифікований SOAPEncoder, а потім придушити WebService для використання альтернативного класу операцій.

Я провела кілька годин на ньому, але потрібно рухатися далі. Ймовірно, це займе день-два.

Можливо, ви зможете просто виправити лінію XMLEncoder і виконати деякі звинувачення, щоб використовувати свій власний клас.

Я також додати, що якщо ви переключитесь до використання RemoteObject / AMF за допомогою ColdFusion, нуль перейде без проблем.


Оновлення 16.11.2013:

У мене є одне останнє доповнення до мого останнього коментарю про RemoteObject / AMF. Якщо ви використовуєте CF10; то властивості з нульовим значенням об'єкта видаляються з об'єкта на стороні сервера. Отже, перед доступом до нього слід перевірити існування властивостей або виникне помилка виконання. Перевірте, як це:

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

Це зміна поведінки від CF9; де нульові властивості перетворилися на пусті рядки.


Редагувати 6.12.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>

Вихідний сигнал:

нульова рядок не дорівнює нульовому зарезервованому слову, використовуючи! = умову

нульова рядок не дорівнює нульовому зарезервованому слову, використовуючи стан ==

Нульова рядок не дорівнює нульовому зарезервованому слову, використовуючи умову ===


125
2018-05-03 15:51



@ Reboog711 Прізвище працівника - це буквально рядок "Null", як в: "Мене звуть Pat Null" Ваша відповідь не дозволяє передавати прізвище працівника. Ви відповісте, просто приховує той факт, що "Нуль" невідповідно примушене до мовної концепції null методом appendChild (), як описано Беном Бернсом. Результатом залишається невдача системи мати справу з паном або пані Нуль. - Maxx Daymon
@MaxxDaymon Я думаю, ви неправильно вважають, що моя відповідь насправді. Це не представляє рішення; а скоріше пояснення причини виникнення проблеми; і цитує відповідний код з Flex Framework. Моя недавня редакція, мабуть, недоречна; оскільки він обговорює альтернативний підхід і не пов'язаний безпосередньо з початковим питанням. - JeffryHouser
Ви напевно на правильному шляху, але в той момент в коді content це рядок "null", а "null" == null повертає false, так що тест поводиться так, як передбачено. Натомість я вважаю, що проблема - це поєднання того, як XML.appendChild обробляє аргумент рядка, і як корінний XML-елемент, що містить тільки рядок "null", може бути примушений до буквальному null. - Ben Burns
@ Reboog711 Подивіться на мою скрипку. "null"! = null` повернення true бажана поведінка тут. Якщо відбулося зворотне, це призведе до відмови від ланцюжка "null" від процесу кодування, що фактично стане причиною проблеми. Однак, оскільки цей тест досягає успіху, кодер продовжує рухатись, поки XML.appendChild відкидає його через помилку примусу. - Ben Burns
Не хвилюйся. Якщо ви хочете побачити справжню проблему, додайте var xml:XML = <root>null</root>; var s:String = (xml == null) ? "wtf? xml coerced to null?!!" : "xml not coerced to null."; trace(s); до зразка коду. - Ben Burns


Перекласти всі символи в їх еквіваленти на шістнадцятковій одиниці. В цьому випадку, Null буде перетворено на &#4E;&#75;&#6C;&#6C;


62
2018-04-30 19:03



Будь ласка, не робіть цього. CDATA був створений для використання у випадках, коли вам потрібно уникнути всього блоку тексту. - Ben Burns
Я міг би помилятися, але я не думаю, що скорочується лише тому, що це не так твій Рішення - як він повинен працювати. Крім того, вам слід пам'ятати про проблеми, що вимагають евристичного рішення, оскільки не існує жодного очевидного способу, про що свідчить різноманітність опублікованих рішень. Нарешті, маючи на увазі, що я не знаю CF, чи не декодер просто прирівнює внутрішній текст <message> <! [CDATA [NULL]]> </ message> до внутрішнього тексту <message> NULL </ повідомлення>? Якщо це так, то CDATA дійсно є рішенням? - doogle
Я понищив, тому що це протизапальниця. Помилка у цьому випадку не в CF, це в ActionScript. Тим не менш, ви піднімаєте непоганий пункт тим не менш. Я додам тест на мою скрипку для кодування CDATA. - Ben Burns


Стиснення a null значення в ActionScript дасть струну "NULL". Моя підозра у тому, що хтось вирішив, що це, отже, хороша ідея для декодування рядка "NULL" як null, що спричиняє поломку, яку ви бачите тут, - ймовірно, тому що вони проходили null об'єкти та отримання рядків у базі даних, коли вони цього не хотіли (тому обов'язково перевірте таку помилку).


49
2018-04-28 20:15



Так, тут існує безліч можливостей, що вимагатиме більшої налагодження для звуження. 1) Чи використовується тут WSDL досить виразно, щоб розрізняти "NULL" як рядкове значення та фактичне нульове (або опущене) значення? 2) Якщо так, то чи клієнт правильно кодує прізвище (як рядок, а не нульовий буквеніл) 3) Якщо так, чи правильно інтерпретує службу "NULL" як рядок або примушує її до нульового значення? - pimlottc


Будучи хакером, ви можете розглянути особливу обробку на стороні клієнта, перетворюючи рядок Null на те, що ніколи не буде, наприклад, XXNULLXX і конвертувати назад на сервер.

Це не дуже добре, але це може вирішити проблему для такого граничного випадку.


36
2018-04-28 08:43



XXNULLXX також може бути ім'ям. Ти не знаєш Може, люди в Індонезії не мають прізвища та використовують варіант XXX як їх прізвище, коли це потрібно. - gb.
Або yanno, завжди CDATA ... - Ben Burns
Той же концепт, але оновіть всі імена в базі даних і передмову потім з деякими символами (1Null, 1Smith). Зніміть цей символ у клієнта. Звичайно, це може бути справою роботи, ніж рішення Reboog. - bobpaul
@ Бен Бернс Так, але якщо я хочу назвати свою дитину &#78;&#117;&#108;&#108;? - Sirens
@ Сіренс Це не проблема. Якщо моє ім'я "<& quot;>", то я очікував, що його буде правильно вилучено як "& quot; & gt;", що не має значення. Реальна проблема полягає в тому, що програма веде себе так, ніби вона використовує чорний список для імен. - Mr Lister


Ну, я гадаю, що реалізація Flex SOAP Encoder серіалізує нульові значення неправильно. Серіалізація їх як String Null, здається, не є хорошим рішенням. Формально правильна версія, здається, передає нульове значення як:

<childtag2 xsi:nil="true" />

Отже, значення "Null" буде нічим іншим, ніж дійсний рядок, який саме те, що ви шукаєте.

Я думаю, виправлення в Apache Flex не повинно бути таким важким, щоб це зробити. Я б рекомендував відкрити випуск Jira або зв'язатися з хлопцями списку розсилки apache-flex. Однак це лише виправляє клієнтську сторону. Я не можу сказати, чи зможе ColdFusion працювати з нульовими значеннями, закодованими таким чином.

Див. Також повідомлення блогу Раду Котеску Як надіслати нульові значення в запитах soapUI.


30
2017-07-17 07:56



Тут хороша інформація, тому я не зменшуся, але я вирішив, що варто коментувати. За замовчуванням XMLEncoder.as буде фактично кодувати істину null правильно оцінювати, встановлюючи xsi:nil="true" на елемент. Насправді, проблема полягає в тому, що ActionScript XML сам тип (а не кодер) обробляє рядок "null". - Ben Burns


Це жар, але припускаючи, що для нього є мінімальна довжина SEARCHSTRING, наприклад, 2 символи, substring в SEARCHSTRING параметр на другому символі і передавати його за два параметри: SEARCHSTRING1 ("Nu") і SEARCHSTRING2 ("ll").  Concatenate їх разом разом при виконанні запиту до бази даних.


21
2018-04-28 19:48



CDATA додано до специфікації XML, щоб уникнути цих типів. - Ben Burns
Немає необхідності вийти з "Null" за допомогою CDATA, немає нічого такого, як нульове ключове слово в XML. - eckes
Погодьтеся з @eckes. Я не розумію, чому все це розмова CDATA. CDATA корисний лише для виведення символів, які мають особливе значення в XML. Жоден з: n, u, l мати спеціальну семантику в XML. "NULL" і "<! [CDATA [NULL]]>" ідентичні аналізатору XML. - jasonkarns
@ jasonkarns - я згоден на 100% що там повинен Не будь особливою особливістю для вузла рядка / тексту NULL, але бути педантичним <blah>null</blah> і <blah><![CDATA[null]]>не є аналогічними для XML-аналізатора. Вони повинен виробляти ті ж результати, однак логічний потік для їх обробки відрізняється. Це такий ефект, що ми використовуємо як шлях до вирішення проблеми при реалізації гнучкої XML-версії. Я виступаю за це за інших підходів, оскільки він зберігає читаність тексту, і не має побічних ефектів для інших аналізаторів. - Ben Burns