Axis2 всегда получает нулевые параметры, даже если запрос SOAP отправлен правильно?

StackOverflow https://stackoverflow.com/questions/1000578

Вопрос

ОБНОВЛЯТЬ:Я РЕШИЛ ЭТУ ПРОБЛЕМУ СЕЙЧАС — ПОЖАЛУЙСТА, ПРОРУСТИТЕ ВНИЗ, ЧТОБЫ ПОЛУЧИТЬ ИНФОРМАЦИЮ ОБ ИСПРАВЛЕНИИ.

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

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

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

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

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

Я подозреваю, что 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>

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

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

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

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

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

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

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

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

Пример ниже:

Автоматически сгенерированный метод и параметры WSDL

<!--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>

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

Модифицированный/исправленный 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>

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

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

И последнее:Удалив атрибут ссылки «element» в тегах запроса, вы можете получить предупреждение синтаксического анализатора в журналах Axis2.Пока это не вызвало у меня никаких проблем, но об этом следует знать, если у вас возникнут проблемы.

Это было полезно?

Решение

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

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

Другие советы

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

До

 <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>

Вот и все!Это сделало это для меня....

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

<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.Если вы не изменили настройку по умолчанию «useoriginalwsdl» в файле Services.xml, эти wsdls могут «выглядеть» по-другому.Мне никогда не приходилось вручную выполнять java2wsdl, чтобы мой веб-сервис работал правильно...

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

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

Вы пробовали отправить такой запрос?

<?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>

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

попробуй это:123456-654321

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

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

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

  • xmlns:ns0="http:///xsd"
  • целевое пространство имен в конце тега wsdl:definitions имело завершающую косую черту
  • ns0 используется для выбора элементов, составляющих тег wsdl:message.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top