¿Axis2 siempre recibe parámetros nulos incluso si la solicitud SOAP se envía correctamente?

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

Pregunta

ACTUALIZACIÓN: HE RESUELTADO ESTE PROBLEMA AHORA - POR FAVOR, DESPLAZARSE PARA INFORMAR INFORMACIÓN SOBRE EL ARREGLO

Hola chicos,

Tengo un servicio web escrito en Java, alojado en un servidor Axis2 / Tomcat / Apache. El software de mi cliente está escrito en C #.

He tenido algunos problemas irritantes con la forma en que java2wsdl genera el archivo wsdl, lo que me causó algunos dolores de cabeza al principio, pero con este problema estoy completamente perplejo.

Básicamente, lo que está sucediendo es que el cliente ve bien el servicio web y envía una solicitud SOAP perfectamente válida (o al menos me parece válida) con parámetros.

En el servidor, se ejecuta el método web correcto, pero los parámetros son todos nulos. Mi servicio web detecta esto y genera una respuesta que el cliente recibe y comprende perfectamente.

Mi corazonada es que Axis2 está cayendo de bruces en alguna parte, pero debido a los dolores de cabeza que he tenido con java2wsdl, tal vez todo lo que necesito es un cambio en mi archivo wsdl.

Aquí está el archivo 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>

Y aquí hay un ejemplo de solicitud y respuesta:

Solicitud:

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

Respuesta

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

¿Alguien tiene alguna idea de lo que podría salir mal?

El mensaje de error en la respuesta solo se puede enviar cuando el parámetro del código de serie en la solicitud está vacío / nulo, así que supongo que hay algún problema con la forma en que Axis2 está leyendo mis parámetros.

Cualquier ayuda es muy apreciada.

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

CÓMO FIJAR ESTO:

Esto es en respuesta a la solicitud de Aldo para obtener más información sobre cómo solucioné este problema.

No estoy seguro de por qué funciona esta solución, quizás sea solo un error en Axis2 o algo así. De cualquier manera, YMMV ya que no sé si el problema fue causado por mi configuración u otra cosa. Todo lo que puedo decir es que al hacer lo siguiente, todo comenzó a funcionar.

De todos modos, el archivo WSDL generado automáticamente crea tipos de elementos complejos para solicitudes web y sus parámetros, incluso cuando los únicos parámetros son tipos simples como cadenas o enteros. Lo que hice fue pasar y crear las etiquetas correctas de tipo simple para parámetros (como 'serialcode' o 'date-string'), luego reemplazar las referencias a los tipos complejos en otras partes del archivo WSDL con referencias a los tipos simples.

A continuación se muestra un ejemplo:

Método y parámetros WSDL generados automáticamente

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

Básicamente, lo que debes hacer es descartar los parámetros generados automáticamente y crear tipos simples. Luego, modifica las etiquetas de 'solicitud' para usar 'tipo' en lugar de 'elemento', y usa los tipos simples que acaba de crear.

WSDL modificado / corregido

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

Obviamente, depende de cuáles sean sus parámetros en realidad. En mi caso, todos son tipos simples estándar, como cadenas y enteros. Si está pasando más de un parámetro, es posible que necesite jugar reteniendo los elementos generados automáticamente, pero asegurándose de que el elemento se refiera a tipos simples en lugar de simplemente incluir el atributo de tipo como 'xs: string' o algo por el estilo. .

Disculpas, no puedo ser más claro al respecto, pero como dije antes, no sé por qué funciona esto.

Una última cosa: al eliminar el atributo de referencia 'elemento' en las etiquetas de solicitud, puede recibir una advertencia de analizador en sus registros de Axis2. Hasta ahora, esto no me ha causado ningún problema, pero es algo a tener en cuenta en caso de que tenga problemas.

¿Fue útil?

Solución

Resolví este problema revisando mi archivo WSDL y, siempre que sea posible, desglosando los elementos en sus contrapartes de tipo simple y actualizando las referencias entre los elementos XML en consecuencia.

No estoy seguro de por qué funciona esto, pero de todos modos ha solucionado mi problema.

Otros consejos

Si tuviera un atributo complejo, así es como podría hacerlo

Antes

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

Después

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

Y luego cambia esto

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

A

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

¡Eso debería ser! Lo hizo por mí ...

Esto es solo una corazonada, pero tal vez tengas un problema de espacio de nombres. Si se enfoca en esta parte del wsdl, observe que su parámetro tiene un " ns0 " espacio de nombres para los elementos, pero en sus operaciones definidas más adelante, parece que está usando un " axis2 " espacio de nombres Con todos mis WSDL generados por Axis2, estos dos espacios de nombres son los mismos.

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

Otra cosa que puedes verificar es verificar que el wsdl que obtuviste de java2wsdl es el mismo generado por axis2. A menos que haya cambiado la configuración predeterminada de "useoriginalwsdl" en su services.xml, estos wsdls pueden '' verse '' diferente. Nunca tuve que realizar un java2wsdl manualmente para que mi servicio web funcionara correctamente ...

Básicamente, golpea la URL de tu servicio en un navegador y agrega el? wsdl al final de la url ... deberías obtener un wsdl para comparación.

Además, haga que su cliente genere stubs a partir del wsdl del servidor en lugar de uno generado por java2wsdl (suponiendo que originalmente utilizó el wsdl de java2wsdl). Una vez más, nunca tuvimos que pasar un wsdl generado manualmente a nadie ... simplemente consumieron el generado dinámicamente desde el servidor ...

¿Ha intentado enviar una solicitud como esta?

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

Todas mis solicitudes tienen la etiqueta solicitud antes de los parámetros de solicitud reales.

prueba esto:                        123456-654321               

Poner xmlns = " " en la etiqueta de parámetro. Tengo el mismo problema y no sé qué puedo modificar para recibir el parámetro sin el xmlnx.

Tengo otra solución. Finalmente descubrí que si no permitía que mi IDE (Netbeans 6.8) generara el WSDL, el servicio web funcionaba. Alternativamente, si lo eliminé, desactivé la opción de generar y volví a implementarlo, luego funcionó.

Al comparar un WSDL generado por Netbeans con un servidor generado, noté las siguientes diferencias:

  • xmlns: ns0 = " http: /// xsd "
  • espacio de nombres de destino al final de wsdl: la etiqueta de definiciones tenía una barra diagonal
  • ns0 solía elegir los elementos que componen la etiqueta wsdl: message

Eliminando todos estos y re-implementando funcionó!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top