Domanda

AGGIORNAMENTO: HO RISOLTO SUBITO QUESTO PROBLEMA - PER FAVORE SCORRI SOTTO PER INFORMAZIONI SU FIX

Ciao ragazzi,

Ho un servizio web scritto in Java, ospitato su un server Axis2 / Tomcat / Apache. Il mio software client è scritto in C #.

Ho avuto alcuni fastidiosi problemi con il modo in cui java2wsdl genera il file wsdl, il che mi ha causato alcuni mal di testa all'inizio, ma con questo problema sono completamente sconcertato.

Fondamentalmente ciò che sta accadendo è che il client vede bene il servizio web e invia una richiesta SOAP perfettamente valida (o almeno, mi sembra valida) con parametri.

Sul server viene eseguito il metodo web corretto, ma i parametri sono tutti nulli. Il mio servizio web lo rileva e crea una risposta, che il cliente riceve e comprende perfettamente.

Il mio sospetto è che Axis2 stia cadendo piatto sulla sua faccia da qualche parte, ma dati i mal di testa che ho avuto con java2wsdl, forse tutto ciò di cui ho bisogno è un cambiamento nel mio file wsdl.

Ecco il file 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>

Ed ecco una richiesta e una risposta di esempio:

Richiesta:

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

Risposta

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

Qualcuno ha idea di cosa potrebbe andare storto?

Il messaggio di errore nella risposta può essere inviato solo quando il parametro serialcode nella richiesta è vuoto / null, quindi immagino che ci sia qualcosa di sbagliato nel modo in cui Axis2 sta leggendo i miei parametri.

Qualsiasi aiuto è molto apprezzato.

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

COME FISSARE QUESTO:

Questo è in risposta alla richiesta di Aldo per ulteriori informazioni su come ho risolto questo problema.

Non sono sicuro del perché questa correzione funzioni - forse è solo un bug in Axis2 o qualcosa del genere. Ad ogni modo, YMMV come non so se il problema è stato causato dalla mia installazione o qualcos'altro. Tutto quello che posso dire è che, facendo quanto segue, tutto ha iniziato a funzionare.

In ogni caso, il file WSDL generato automaticamente crea tipi di elementi complessi per le richieste Web e i loro parametri, anche quando gli unici parametri sono tipi semplici come stringhe o numeri interi. Quello che ho fatto è stato passare attraverso e creare i corretti tag di tipo semplice per i parametri (come 'serialcode' o 'date-string'), quindi sostituire i riferimenti ai tipi complessi altrove nel file WSDL con riferimenti ai tipi semplici.

Un esempio è di seguito:

Metodo e parametri WSDL generati automaticamente

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

Fondamentalmente quello che dovresti fare è scartare i parametri generati automaticamente e creare tipi semplici. Quindi modificare i tag "richiesta" per utilizzare "tipo" anziché "elemento" e utilizzare i tipi semplici appena creati.

WSDL modificato / fisso

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

Ovviamente dipende da quali sono i tuoi parametri. Nel mio caso sono tutti tipi semplici standard come stringhe e numeri interi. Se si passa più di un parametro, potrebbe essere necessario giocare trattenendo gli elementi generati automaticamente ma assicurandosi che l'elemento si riferisca a tipi semplici anziché includere semplicemente l'attributo type come 'xs: string' o qualcosa del genere .

Mi scuso non posso essere più chiaro su questo, ma come ho detto prima - non so perché funzioni.

Un'ultima cosa: rimuovendo l'attributo di riferimento 'element' nei tag di richiesta, potresti ricevere un avviso parser nei tuoi log di Axis2. Finora questo non mi ha causato alcun problema, ma è qualcosa di cui essere consapevoli in caso di problemi.

È stato utile?

Soluzione

Ho risolto questo problema esaminando il mio file WSDL e, ove possibile, suddividendo gli elementi nelle loro controparti di tipo semplice e aggiornando i riferimenti tra gli elementi XML di conseguenza.

Non sono sicuro del perché funzioni, ma ha comunque risolto il mio problema.

Altri suggerimenti

Se avessi un attributo complesso, ecco come potresti farlo

Prima

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

Dopo

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

E poi cambia questo

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

Per

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

Dovrebbe essere! Lo ha fatto per me ....

Questo è solo un sospetto, ma forse stai riscontrando un problema con lo spazio dei nomi. Se ti concentri su questa parte di wsdl, nota che il tuo parametro ha un " ns0 " spazio dei nomi per gli elementi, ma nelle operazioni definite in seguito, sembra che tu stia utilizzando un " axis2 " namespace. Con tutti i miei WSDL generati da Axis2, questi due spazi dei nomi sono gli stessi.

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

Un'altra cosa che puoi controllare è verificare che il wsdl ottenuto da java2wsdl sia lo stesso generato da axis2. A meno che tu non abbia modificato l'impostazione predefinita di " useoriginalwsdl " nel tuo services.xml, questi wsdls possono " guardare " diverso. Non ho mai dovuto eseguire manualmente un java2wsdl per far funzionare correttamente il mio webservice ...

Quindi, fondamentalmente, premi l'URL del tuo servizio in un browser e punta su? wsdl alla fine dell'URL ... dovresti ottenere un wsdl per amor di confronto.

Inoltre, fai in modo che il tuo client generi stub dal server wsdl anziché da uno generato da java2wsdl (supponendo che tu abbia usato originariamente il wsdl da java2wsdl). Ancora una volta, non abbiamo mai dovuto passare un wsdl generato manualmente a nessuno ... hanno semplicemente consumato quello generato dinamicamente dal server ...

Hai provato a inviare una richiesta come questa?

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

Tutte le mie richieste hanno il tag richiesta prima dei parametri di richiesta effettivi.

prova questo:                        123456-654321               

Inserisci xmlns = " " nel parametro tag. Ho lo stesso problema e non so cosa posso modificare per ricevere il parametro senza xmlnx.

Ho un'altra correzione. Alla fine ho scoperto che se non avessi permesso al mio IDE (Netbeans 6.8) di generare il WSDL, il servizio web avrebbe funzionato. In alternativa, se l'ho eliminato, deselezionato l'opzione di generazione e ri-distribuito, ha funzionato.

Confrontando un WSDL generato da Netbeans con un server generato, ho notato le seguenti differenze:

  • xmlns: ns0 = " http: /// xsd "
  • spazio dei nomi di destinazione alla fine del wsdl: tag di definizioni con una barra finale
  • ns0 usato per scegliere gli elementi che compongono il tag wsdl: message

Rimozione di tutti questi e reimplementazione ha funzionato!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top