Вопрос: Как передать «Null» (настоящую фамилию!) На веб-службу 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.


4462


источник


Ответы:


Отслеживание

Сначала я думал, что это ошибка принуждения, где nullбыл принужден к "null"и испытание "null" == nullпроходил. Это не. Я был близок, но очень, очень неправильно. Извини за это!

С тех пор я много сделал играя на wonderfl.net и отслеживание кода в mx.rpc.xml.*, На строке 1795 XMLEncoder(в источнике 3.5), в setValue, все XMLEncoding сводится к

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

который по существу такой же, как:

currentChild.appendChild("null");

Этот код, согласно моей оригинальной скрипке, возвращает пустой элемент XML. Но почему?

причина

По словам комментатора Justin Mclean о сообщении об ошибке 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 (или что-нибудь действительно) для «nullness».

Решение

Единственное разумное обходное решение, которое я могу придумать, не исправляя эту ошибку в каждой проклятой версии ActionScript, - это проверить поля для «null» и избегать их как Значения CDATA ,

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


1046



На примечание xkcd , Веб-сайт Bobby Tables имеет хорошие рекомендации по предотвращению неправильной интерпретации пользовательских данных (в данном случае строки «Null») в SQL-запросах на разных языках, в том числе Холодный синтез ,

Из вопроса не ясно, что это источник проблемы, и учитывая решение, указанное в комментарии к первому ответу (вложение параметров в структуру), кажется вероятным, что это было нечто другое.


283



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

(На стороне примечания, вы ожидаете сделать что-то полезное, если идентификатор сотрудника - Null, это не проблема проверки? Возможно, я ошибаюсь, так как я почти не знаю этого требования ...)


234



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

Решение состоит в том, чтобы изменить mx.rpc.xml.XMLEncoderфайл. Это строка 121

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

[Я посмотрел на Flex 4.5.1 SDK; номера строк могут отличаться в других версиях]

В принципе, проверка не выполняется, потому что «контент имеет значение NULL», и поэтому ваш аргумент не добавляется в исходящий пакет SOAP; что приводит к ошибке отсутствия параметра.

Вы должны расширить этот класс, чтобы удалить проверку. Затем происходит большой снежный ком по цепочке, изменяя SOAPEncoder, чтобы использовать измененный XMLEncoder, а затем изменяя операцию для использования вашего модифицированного SOAPEncoder, а затем moidfying WebService для использования вашего альтернативного класса Operation.

Я потратил несколько часов на это, но мне нужно двигаться дальше. Это, вероятно, займет день или два.

Вы можете просто исправить строку XMLEncoder и сделать некоторые исправления обезьян, чтобы использовать свой собственный класс.

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


Обновлено 11/16/2013 :

У меня есть еще одно последнее дополнение к моему последнему комментарию о RemoteObject / AMF. Если вы используете CF10; то свойства с нулевым значением для объекта удаляются из объекта на стороне сервера. Таким образом, перед доступом к нему необходимо проверить наличие свойств или получить ошибку времени выполнения. Проверьте следующее:

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

Это изменение поведения от CF9; где нулевые свойства превратятся в пустые строки.


Редактировать 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 string не равна нулевому зарезервированному слову, используя условие ==

null string не равно нулевому зарезервированному слову, используя условие ===


125



Переведите все символы в их эквиваленты с шестью сущностями. В этом случае, Nullбудет преобразован в &#4E;&#75;&#6C;&#6C;


62



Строгая nullзначение в ActionScript даст строку "NULL", Мое подозрение состоит в том, что кто-то решил, что поэтому рекомендуется декодировать строку "NULL"в виде null, вызывая разлом, который вы видите здесь, вероятно, потому, что они проходили мимо nullобъекты и получение строк в базе данных, когда они этого не хотят (так что не забудьте также проверить такую ​​ошибку).


49



В качестве взлома вы можете подумать о специальной обработке на стороне клиента, конвертируя строку «Null» в нечто, что никогда не произойдет, например, XXNULLXX и преобразование обратно на сервер.

Это не очень, но это может решить проблему для такого граничного случая.


36



Well, I guess that Flex' implementation of the SOAP Encoder seems to serialize null values incorrectly. Serializing them as a String Null doesn't seem to be a good solution. The formally correct version seems to be to pass a null value as:

<childtag2 xsi:nil="true" />

So the value of "Null" would be nothing else than a valid string, which is exactly what you are looking for.

I guess getting this fixed in Apache Flex shouldn't be that hard to get done. I would recommend opening a Jira issue or to contact the guys of the apache-flex mailinglist. However this would only fix the client side. I can't say if ColdFusion will be able to work with null values encoded this way.

See also Radu Cotescu's blog post How to send null values in soapUI requests.


30



It's a kludge, but assuming there's a minimum length for SEARCHSTRING, for example 2 characters, substring the SEARCHSTRING parameter at the second character and pass it as two parameters instead: SEARCHSTRING1 ("Nu") and SEARCHSTRING2 ("ll"). Concatenate them back together when executing the query to the database.


21