Как передать "Null" (настоящая фамилия!) для веб-службы SOAP в ActionScript 3?
у нас есть сотрудник, фамилия которого равна нулю. Наше приложение поиска сотрудников убивается, когда эта фамилия используется в качестве поискового термина (что случается довольно часто в настоящее время). Ошибка получена (спасибо скрипач!) это:
<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 (МЫЛО)
- Flex 3.5
- ActionScript 3
- ColdFusion 8
обратите внимание, что ошибка не происходит при вызове webservice как объекта со страницы ColdFusion.
9 ответов:
следопыт
сначала я подумал, что это ошибка принуждения, где
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, содержащий null, принуждается к типу null, либо тип null принуждается к корневому элементу xml, содержащему строку "null", и тест проходит там, где он, возможно, должен потерпеть неудачу. Одним из исправлений может быть всегда использовать строгое равенство тесты при проверке XML (или что угодно) для - ничтожество."решение
Единственное разумное решение, которое я могу придумать, кроме исправления этой ошибки в каждой чертовой версии ActionScript, - это проверить поля на "null" и избежать их как значения CDATA.значения CDATA являются наиболее подходящим способом для изменения всего текстового значения, которое в противном случае вызвало бы проблемы кодирования/декодирования. шестнадцатеричное кодирование, например, предназначено для отдельных символов. Значения CDATA предпочтительны, когда вы экранируете весь текст элемента. Самая большая причина этого заключается в том, что он поддерживает читаемость человека.
на xkcd Примечание на Бобби таблицы веб-сайт имеет хороший совет, чтобы избежать неправильной интерпретации пользовательских данных (в данном случае строки "Null") в SQL-запросах на разных языках, в том числе ColdFusion.
из вопроса не ясно, что это источник проблемы, и учитывая решение, отмеченное в комментарии к первому ответу (встраивание параметров в структуру), кажется вероятным, что это было что-то еще.
проблема может быть в SOAP-кодере Flex. Попробуйте расширить кодировщик SOAP в приложении Flex и отладить программу, чтобы увидеть, как обрабатывается нулевое значение. Я предполагаю, что это передается как NaN (Не число). Это испортит процесс unmarshalling SOAP message когда-нибудь (особенно в JBoss сервер 5...). Я помню, как расширял кодер SOAP и выполнял явную проверку того, как обрабатывается NaN.
(на стороне записки, вы должны сделайте что-нибудь полезное, если идентификатор сотрудника равен нулю, это не проблема проверки? Я могу ошибаться, так как я едва знаю требование...)
@doc_180 имел правильную концепцию, за исключением того, что он сосредоточен на числах, тогда как оригинальный плакат имел проблемы со строками.
решение состоит в том, чтобы изменить . Это строка 121
if (content != null) result += content;[Я посмотрел на Flex 4.5.1 SDK; номера строк могут отличаться в других версиях]
в принципе, проверка не выполняется, потому что "содержимое равно null", и поэтому ваш аргумент не добавляется в исходящий пакет SOAP; таким образом, вызывая ошибку отсутствующего параметра.
вы должны расширить этот класс, чтобы удалить проверки. Затем есть большой снежок вверх по цепочке, изменяя SOAPEncoder для использования вашего модифицированного XMLEncoder, а затем изменяя операцию, чтобы использовать ваш модифицированный SOAPEncoder, а затем moidfying 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
поскольку здесь был вопрос о том, как обрабатываются нули, это быстрый пример приложения, чтобы продемонстрировать, как строка "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>вывод трассировки:
пустая строка не равно нулю зарезервированное слово с помощью != условие
нулевая строка не равна нулевому зарезервированному слову, используя условие==
нулевая строка не равна нулевому зарезервированному слову, используя условие===
перевести все символы в их hex-эквивалентные сущности. В этом случае
Nullбудет преобразован вE;KC;C;
Stringifying a
nullзначение ActionScript даст строку"NULL". Мое подозрение, что кто-то решил, что это, следовательно, хорошая идея, чтобы декодировать строку"NULL"какnull, вызывая поломку вы видите здесь-вероятно, потому что они проходили вnullобъекты и получение строк в базе данных, когда они этого не хотели (так что не забудьте проверить и такую ошибку).
в качестве взлома вы можете рассмотреть возможность специальной обработки на стороне клиента, преобразования строки "Null" в то, что никогда не произойдет, например, XXNULLXX и преобразования обратно на сервер.
Это не очень красиво, но это может решить проблему для такого граничного случая.
Ну, я думаю, что реализация Flex кодировщика SOAP, похоже, сериализует нулевые значения неправильно. Сериализация их в виде строки Null не кажется хорошим решением. Формально правильная версия, похоже, передает нулевое значение как:
<childtag2 xsi:nil="true" />таким образом, значение "Null" будет не чем иным, как допустимой строкой, что именно то, что вы ищете.
Я думаю, что это исправлено в Apache Flex не должно быть так сложно сделать. Я бы рекомендовал Открытие проблемы Jira или связаться с ребятами из Apache-flex mailinglist. Однако это будет только исправить на стороне клиента. Я не могу сказать, сможет ли ColdFusion работать с нулевыми значениями, закодированными таким образом.
см. также сообщение в блоге Раду Котеску как отправить нулевые значения в soapUI запросы.
это Клудж, но предполагая, что есть минимальная длина для
SEARCHSTRING, например 2 знака,substringtheSEARCHSTRINGпараметр на втором символе и передать его в виде двух параметров вместо этого:SEARCHSTRING1 ("Nu")иSEARCHSTRING2 ("ll").Concatenateих вместе при выполнении запроса к базе данных.
Comments