Почему один и тот же SOAP-запрос работает в одном проекте Flex, а не в другом? - PullRequest
0 голосов
/ 15 февраля 2010

Это довольно странная ситуация у меня здесь. Я использовал кусок кода для взаимодействия с бэкэнд-сервисом SOAP в течение нескольких месяцев - он работает отлично. Я опробовал его в другом проекте (сначала в виде библиотеки swc, а затем просто вырезая и вставляя), и он просто не работает.

Если я попробую точно такой же код в исходном проекте flex, подключившись к тому же бэкэнд-сервису, все будет нормально. В новом проекте я могу вызывать операции, которые принимают в качестве параметров простые обертки с литералами документа (у них нет реальных параметров), но если у операции есть сложный параметр внутри обертки с литералом документа, произойдет сбой в этом новом проекте. Вот пример, который потерпит неудачу:

var service:WebService = new WebService();
service.wsdl = wsdlURL;
var operation:AbstractOperation = service.getOperation( "addNewUser" );

var param:XML = <AddNewUserRequest/>
param.setNamespace( myNameSpace );

param.user.username( username );
param.user.email( email );

operation.send( param );

А вот пример, который будет работать в новом проекте:

var service:WebService = new WebService();
service.wsdl = wsdlURL;
var operation:AbstractOperation = service.getOperation( "getUsers" );

var param:XML = <GetUsersRequest/>
param.setNamespace( myNameSpace );

operation.send( param );

Вот несколько вещей, которые я сделал, чтобы попробовать разыскать этот:

-Проверил сообщения в firebug из обоих проектов и не вижу разницы (это означает, что код, по-видимому, генерирует одинаковый запрос SOAP в обоих проектах (как и ожидалось) -Я проверил, что запросы должны работать с использованием SOAPui для прямого запроса веб-службы

Внутренний сервис - это веб-сервис Apache CXF, и здесь приведен пример ошибки, которую он генерирует:

org.apache.cxf.interceptor.Fault: Найден элемент {http://www.w3.org/2001/XMLSchema}user, но не найден соответствующий RPC / литеральный элемент

Все, что я знаю, заставляет меня верить, что пользователь должен находиться в пространстве имен http://www.w3.org/2001/XMLSchema - и, честно говоря, я считаю, что ключом здесь является то, что код работает в одном проекте, а не в другом. Может ли это быть настройка XML? Один из статических, таких как ignoreWhitespace? Я играл с изменениями вокруг - без удачи.

Есть идеи вообще? Это сводит меня с ума !!!

UPDATE:

Я сузил это до следующего: новый проект создает заголовок, подобный этому:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

и тот, который работает, создает это:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

Почему разница в одной и той же версии flex & flex builder? То, что работает, очевидно, правильно (xmlns: xsd = "http://www.w3.org/2001/XMLSchema") - веб-служба корректна, чтобы отклонить запрос, который помещает все в запрос в пространство имен xsd.

Ответы [ 2 ]

2 голосов
/ 19 мая 2010

Причина, по которой он добавляет xmlns="http://www.w3.org/2001/XMLSchema" в конверт SOAP вместо xmlns:xsd="http://www.w3.org/2001/XMLSchema", заключается в том, что именно так он определен в классе rpc.xml.SchemaConstants. В какой-то момент в поврежденном проекте вы импортировали xsd в класс rpc.xml.SchemaManager, который определяет xmlns="http://www.w3.org/2001/XMLSchema", который переопределяет определение по умолчанию в SchemaConstants.

Попробуйте проверить все xsds, которые вы используете, и убедитесь, что они не содержат xmlns="http://www.w3.org/2001/XMLSchema".

1 голос
/ 16 февраля 2010

Вы жестко кодируете свой запрос как XML, и я предполагаю, что ваше пользовательское пространство имен не имеет префикса, поэтому оно конфликтует с пространством имен по умолчанию для XSD, объявленным в вашем заголовке. Почему у вас разные заголовки, я не знаю, но вы, вероятно, компилируете свой проект с разными версиями SDK.

Несколько вещей, которые нужно попробовать:

  • Убедитесь, что вы используете пакет SDK для компиляции обоих проектов (последние, с которыми вы можете справиться, поскольку исправления в стеке SOAP входят практически в каждый выпуск)

  • Установите явный префикс для вашего пространства имен, используя:

    var myNameSpace:NameSpace = new NameSpace("my","http://something.com/foo/ns");

  • Вместо создания XML-запроса, создайте его как простые объекты AS3, например:

    var request:Object = {GetUsersRequest: {parm1: foo, parm2:bar }};

    ... и пусть Flex сделает всю кодировку за вас. Множество людей (включая меня) потратили бесчисленные часы на то, чтобы стек SOAP Flex работал хорошо с объектами AS3 вместо XML-запросов, созданных вручную, почему бы не позволить SDK выполнить работу по созданию вашего запроса за вас?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...