Axis2 всегда получает нулевые параметры, даже если SOAP-запрос отправляется правильно? - PullRequest
2 голосов
/ 16 июня 2009

ОБНОВЛЕНИЕ: Я УСТАНОВИЛ ЭТУ ПРОБЛЕМУ СЕЙЧАС - ПОЖАЛУЙСТА, ПРОЧИТАЙТЕ ДНО ДЛЯ ИНФОРМАЦИИ О ИСПРАВЛЕНИИ

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

У меня есть веб-сервис, написанный на 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 ссылками на простые типы.

Пример ниже:

Метод и параметры автоматически сгенерированного 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>

По сути, вам следует отказаться от автоматически сгенерированных параметров и создать простые типы. Затем вы изменяете теги 'request', чтобы использовать 'type' вместо '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. Пока что это не вызвало у меня никаких проблем, но об этом следует знать, если у вас возникнут проблемы.

Ответы [ 6 ]

1 голос
/ 04 ноября 2010

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

До

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

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

1 голос
/ 29 июня 2009

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

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

0 голосов
/ 04 марта 2010

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

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

  • XMLNS: ns0 = "HTTP: /// XSD"
  • целевое пространство имен в конце тега wsdl: определений имеет косую черту
  • ns0 используется для выбора элементов, составляющих тег wsdl: message

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

0 голосов
/ 24 августа 2009

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

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

0 голосов
/ 26 июня 2009

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

<?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 перед фактическими параметрами запроса.

0 голосов
/ 16 июня 2009

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

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

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

...