2

Вопрос по c#, soap, axis2, java, web-services – Axis2 всегда получает нулевые параметры, даже если SOAP-запрос отправляется правильно?

UPDATE: I HAVE SOLVED THIS PROBLEM NOW - PLEASE SCROLL TO BOTTOM FOR INFORMATION ABOUT FIX

Привет, ребята,

У меня есть веб-сервис, написанный на Java, размещенный на сервере Axis2 / Tomcat / Apache. Моя клиентская программа написана на C #.

У меня было несколько раздражающих проблем с тем, как java2wsdl генерирует файл wsdl, что вызывало у меня несколько головных болей на ранних стадиях, но с этой проблемой я полностью озадачен.

В основном происходит то, что клиент видит веб-сервис в порядке и отправляет совершенно правильный (или, по крайней мере, мне кажется) SOAP-запрос с параметрами.

На сервере выполняется правильный веб-метод, но все параметры имеют значение null. Мой веб-сервис обнаруживает это и создает ответ, который клиент получает и прекрасно понимает.

Я догадываюсь, что Axis2 где-то падает на лицо, но, учитывая головные боли, которые у меня были с java2wsdl, возможно, все, что мне нужно, это изменение в моем файле wsdl.

Вот файл wsdl:

    <?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:axis2="http://stws/" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:ns0="http://stws/xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://stws/">
    <wsdl:types>
        <xs:schema xmlns:ns="http://stws/xsd" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://stws/xsd">
            <xs:element name="GetGroups">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="0" name="serialcode" nillable="true" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="GetGroupsResponse">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element maxOccurs="unbounded" minOccurs="0" name="return" nillable="true" type="ns0:Group"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:complexType name="Group">
                <xs:sequence>
                    <xs:element minOccurs="0" name="ID" type="xs:int"/>
                    <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
            <xs:element name="GetMessages">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="0" name="serialcode" nillable="true" type="xs:string"/>
                        <xs:element maxOccurs="unbounded" minOccurs="0" name="groupids" type="xs:int"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="GetMessagesResponse">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element maxOccurs="unbounded" minOccurs="0" name="return" nillable="true" type="ns0:Message"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:complexType name="Message">
                <xs:sequence>
                    <xs:element minOccurs="0" name="date" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="group" type="xs:int"/>
                    <xs:element minOccurs="0" name="messageID" type="xs:int"/>
                    <xs:element minOccurs="0" name="text" nillable="true" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:schema>
    </wsdl:types>
    <wsdl:message name="GetMessagesRequest">
        <wsdl:part name="parameters" element="ns0:GetMessages"/>
    </wsdl:message>
    <wsdl:message name="GetMessagesResponse">
        <wsdl:part name="parameters" element="ns0:GetMessagesResponse"/>
    </wsdl:message>
    <wsdl:message name="GetGroupsRequest">
        <wsdl:part name="parameters" element="ns0:GetGroups"/>
    </wsdl:message>
    <wsdl:message name="GetGroupsResponse">
        <wsdl:part name="parameters" element="ns0:GetGroupsResponse"/>
    </wsdl:message>
    <wsdl:portType name="MyProjectPortType">
        <wsdl:operation name="GetMessages">
            <wsdl:input message="axis2:GetMessagesRequest" wsaw:Action="urn:GetMessages"/>
            <wsdl:output message="axis2:GetMessagesResponse" wsaw:Action="urn:GetMessagesResponse"/>
        </wsdl:operation>
        <wsdl:operation name="GetGroups">
            <wsdl:input message="axis2:GetGroupsRequest" wsaw:Action="urn:GetGroups"/>
            <wsdl:output message="axis2:GetGroupsResponse" wsaw:Action="urn:GetGroupsResponse"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="MyProjectSOAP11Binding" type="axis2:MyProjectPortType">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
        <wsdl:operation name="GetMessages">
            <soap:operation soapAction="urn:GetMessages" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="GetGroups">
            <soap:operation soapAction="urn:GetGroups" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:binding name="MyProjectSOAP12Binding" type="axis2:MyProjectPortType">
        <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
        <wsdl:operation name="GetMessages">
            <soap12:operation soapAction="urn:GetMessages" style="document"/>
            <wsdl:input>
                <soap12:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap12:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="GetGroups">
            <soap12:operation soapAction="urn:GetGroups" style="document"/>
            <wsdl:input>
                <soap12:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap12:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:binding name="MyProjectHttpBinding" type="axis2:MyProjectPortType">
        <http:binding verb="POST"/>
        <wsdl:operation name="GetMessages">
            <http:operation location="MyProject/GetMessages"/>
            <wsdl:input>
                <mime:content type="text/xml" part="GetMessages"/>
            </wsdl:input>
            <wsdl:output>
                <mime:content type="text/xml" part="GetMessages"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="GetGroups">
            <http:operation location="MyProject/GetGroups"/>
            <wsdl:input>
                <mime:content type="text/xml" part="GetGroups"/>
            </wsdl:input>
            <wsdl:output>
                <mime:content type="text/xml" part="GetGroups"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="MyProject">
        <wsdl:port name="MyProjectSOAP11port_http" binding="axis2:MyProjectSOAP11Binding">
            <soap:address location="http://localhost:8080/axis2/services/MyProject"/>
        </wsdl:port>
        <wsdl:port name="MyProjectSOAP12port_http" binding="axis2:MyProjectSOAP12Binding">
            <soap12:address location="http://localhost:8080/axis2/services/MyProject"/>
        </wsdl:port>
        <wsdl:port name="MyProjectHttpport" binding="axis2:MyProjectHttpBinding">
            <http:address location="http://localhost:8080/axis2/services/MyProject"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

А вот пример запроса и ответа:

Запрос:

<?xml version='1.0' encoding='utf-8'?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap:Body>
    <GetGroups xmlns="http://stws/xsd">
      <serialcode>123456-654321</serialcode>
    </GetGroups>
  </soap:Body>
</soap:Envelope>

отклик

<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <GetGroupsResponse xmlns="http://stws/xsd">
      <return>
        <ID>-101</ID>
        <name>ERROR: Empty Serial</name>
      </return>
    </GetGroupsResponse>
  </soapenv:Body>
</soapenv:Envelope>

Кто-нибудь знает, что может пойти не так?

Сообщение об ошибке в ответе может быть отправлено только тогда, когда параметр serialcode в запросе пуст / пуст, поэтому я предполагаю, что что-то не так с тем, как Axis2 считывает мои параметры.

Буду признателен за любую оказанную помощь.

============================================================

КАК ИСПРАВИТЬ ЭТО:

Это в ответ на запрос Aldo для получения дополнительной информации о том, как я исправил эту проблему.

Я не уверен, почему это исправление работает - возможно, это просто ошибка в Axis2 или что-то в этом роде. В любом случае, YMMV, поскольку я не знаю, была ли проблема вызвана моей настройкой или чем-то еще. Все, что я могу сказать, что, выполнив следующее, все начало работать.

В любом случае, автоматически сгенерированный файл WSDL создает типы сложных элементов для веб-запросов и их параметров, даже если единственными параметрами являются простые типы, такие как строки или целые числа. Я прошел через создание и создание правильных тегов простого типа для параметров (таких как «serialcode» или «date-string»), а затем заменил ссылки на сложные типы в других местах файла WSDL ссылками на простые типы.

Пример ниже:

Auto Generated WSDL method and parameters

<!--Requests-->    
<wsdl:message name="RegisterClientRequest">
    <wsdl:part name="parameters" element="ns0:RegisterClient"/>
</wsdl:message>
<wsdl:message name="GetGroupsRequest">
    <wsdl:part name="parameters" element="ns0:GetGroups"/>
</wsdl:message>

<!--Parameters-->
<xs:element name="RegisterClient">
    <xs:complexType>
        <xs:sequence>
           <xs:element minOccurs="0" name="serialcode" nillable="true" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:element name="GetGroups">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" name="serialcode" nillable="true" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
 </xs:element>

По сути, вам следует отказаться от автоматически сгенерированных параметров и создать простые типы. Затем вы изменяете «запрос»; теги для использования "типа" а не «элемент» и используйте только что созданные вами простые типы.

Modified / Fixed WSDL

<!--Requests-->    
<wsdl:message name="RegisterClientRequest">
    <wsdl:part name="parameters" type="ns0:SerialCode"/>
</wsdl:message>
<wsdl:message name="GetGroupsRequest">
    <wsdl:part name="parameters" type="ns0:SerialCode"/>
</wsdl:message>

<!--Parameters-->
<xs:simpleType name="SerialCode">
    <xs:restriction base="xs:string"/>
</xs:simpleType>

Очевидно, это зависит от того, каковы ваши параметры на самом деле. В моем случае это все стандартные простые типы, такие как строки и целые числа. Если вы передаете более одного параметра, вам может понадобиться поиграть, сохранив автоматически сгенерированные элементы, но убедившись, что элемент ссылается на простые типы, а не просто включает атрибут типа как & apos; xs: string & apos; или что-то в этом роде.

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

И последнее: удалите «элемент»; Ссылочный атрибут в тегах запроса - вы можете получить предупреждение парсера в ваших журналах Axis2. До сих пор это не вызывало у меня никаких проблем, но это то, что нужно знать, если у вас возникнут проблемы.

Какой компонент выполняет проверку и генерирует это сообщение об ошибке? Если это ваш код, можете ли вы проверить, что данные запроса отсутствуют к тому времени, когда они заходят так далеко?

Jun 16, 2009, 11:58 AMот

Сами веб-методы выполняют быструю проверку (в действительности, единственная причина, по которой проверка существует в первую очередь, заключается в том, что я получаю нулевые возвраты - это просто дает мне простой способ признать, что входные данные были нулевыми!). Простое модульное тестирование кода веб-службы не создает этой проблемы, и собственный SOAPMonitor Axis2 показывает, что клиент действительно отправляет требуемые параметры - но по какой-то причине параметры обнуляются к тому времени, когда Axis2 вызывает веб-методы.

Jun 16, 2009, 12:44 PMот

6ответов

0

try this: 123456-654321

Поместите xmlns = & quot; & quot; в теге параметра. У меня та же проблема, и я не знаю, что я могу изменить, чтобы получить параметр без xmlnx.

0

У меня есть другое исправление. В конце концов я обнаружил, что если я не позволил моей IDE (Netbeans 6.8) генерировать WSDL, то веб-служба работала. Кроме того, если я удалил его, снял флажок сгенерировать и повторно развернул, то это сработало.

Сравнивая NetBeans, сгенерированный WSDL, с сервером, сгенерированным я заметил следующие различия:

  • xmlns:ns0="http:///xsd"
  • target namespace at the end of the wsdl:definitions tag had a trailing slash
  • ns0 used to choose the elements that make up the wsdl:message tag

Удаление всего этого и повторное развертывание работали!

1

Если у вас был сложный атрибут, вот как вы могли бы это сделать

До

 <xs:element name="getMyMenu">
            <xs:complexType>
                <xs:sequence>
                    <xs:element minOccurs="0" name="number" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="var2" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="var3" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="var4" nillable="true" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>

После

            <xs:complexType name="getMyMenu">
                <xs:sequence>
                    <xs:element minOccurs="0" name="number" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="var2" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="var3" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="var4" nillable="true" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>

А потом измени это

<wsdl:message name="getMyMenuRequest">
    <wsdl:part name="parameters" type="ns0:getUssdMenu"/>
</wsdl:message>

к

<wsdl:message name="getMyMenuRequest">
    <wsdl:part name="parameters" type="ns:getUssdMenu"/>
</wsdl:message>

Так и должно быть! Он сделал это для меня ....

0

Это всего лишь догадка, но, возможно, у вас проблема с пространством имен. Если вы сосредоточитесь на этой части wsdl, обратите внимание, что у вашего параметра есть & quot; ns0 & quot; пространство имен для элементов, но в ваших операциях, определенных позже, похоже, что вы используете «axis2» Пространство имен. Со всеми моими сгенерированными Axis2 WSDL эти два пространства имен одинаковы.

<wsdl:message name="GetMessagesRequest">
    <wsdl:part name="parameters" element="ns0:GetMessages"/>
</wsdl:message>
<wsdl:message name="GetMessagesResponse">
    <wsdl:part name="parameters" element="ns0:GetMessagesResponse"/>
</wsdl:message>
<wsdl:message name="GetGroupsRequest">
    <wsdl:part name="parameters" element="ns0:GetGroups"/>
</wsdl:message>
<wsdl:message name="GetGroupsResponse">
    <wsdl:part name="parameters" element="ns0:GetGroupsResponse"/>
</wsdl:message>

<wsdl:portType name="MyProjectPortType">
    <wsdl:operation name="GetMessages">
        <wsdl:input message="axis2:GetMessagesRequest" wsaw:Action="urn:GetMessages"/>
        <wsdl:output message="axis2:GetMessagesResponse" wsaw:Action="urn:GetMessagesResponse"/>
    </wsdl:operation>
    <wsdl:operation name="GetGroups">
        <wsdl:input message="axis2:GetGroupsRequest" wsaw:Action="urn:GetGroups"/>
        <wsdl:output message="axis2:GetGroupsResponse" wsaw:Action="urn:GetGroupsResponse"/>
    </wsdl:operation>
</wsdl:portType>

Другая вещь, которую вы можете проверить, это убедиться, что wsdl, полученный вами от java2wsdl, является тем же, который генерируется axis2. Если вы не изменили настройку по умолчанию & quot; useoriginalwsdl & quot; в вашем services.xml эти wsdls могут & quot; выглядеть & quot; разные. Мне никогда не приходилось выполнять java2wsdl вручную, чтобы мой веб-сервис функционировал правильно ...

Таким образом, в основном, нажмите URL вашего сервиса в браузере и нажмите на «wsdl» в конце URL-адреса ... вы должны получить wsdl для сравнения.

Кроме того, пусть ваш клиент генерирует заглушки из wsdl сервера вместо того, который генерируется java2wsdl (при условии, что вы изначально использовали wsdl из java2wsdl). Опять же, нам никогда не приходилось передавать сгенерированный вручную wsdl кому-либо ... они просто потребляли динамически сгенерированный файл с сервера ...

0

Вы пытались отправить запрос, как это?

<?xml version='1.0' encoding='utf-8'?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap:Body>
    <request>
      <GetGroups xmlns="http://stws/xsd">
        <serialcode>123456-654321</serialcode>
      </GetGroups>
    </request>
  </soap:Body>
</soap:Envelope>

Все мои запросы имеютrequest тег перед фактическими параметрами запроса.

1

Я решил эту проблему, просматривая мой файл WSDL и, где это возможно, разбивая элементы на их аналоги простого типа и соответственно обновляя ссылки между элементами XML.

Я не уверен, почему это работает, но это все равно решило мою проблему.

RelatedQuestions