SaNuelson / nswi145_web_services

0 stars 0 forks source link

Vlastné WSDL pridáva k vnútornému elementu interface namespace #1

Closed SaNuelson closed 2 years ago

SaNuelson commented 2 years ago

Ručne písané WSDL vygeneruje:

<soapenv:Envelope 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:int="http://interfaces/">
   <soapenv:Header/>
   <soapenv:Body>
      <int:GetByJobType>
         <int:jobType>knitting</int:jobType>
      </int:GetByJobType>
   </soapenv:Body>
</soapenv:Envelope>

Na čo príde response:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
         <faultcode>S:Server</faultcode>
         <faultstring>java.lang.NullPointerException</faultstring>
      </S:Fault>
   </S:Body>
</S:Envelope>

V prípade WSDL auto-generovaného webserverom je to:

<soapenv:Envelope 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:int="http://interfaces/">
   <soapenv:Header/>
   <soapenv:Body>
      <int:GetByJobType>
         <!--Optional:-->
         <jobType>knitting</jobType>
      </int:GetByJobType>
   </soapenv:Body>
</soapenv:Envelope>

a response je vtedy v poriadku:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <ns2:GetByJobTypeResponse xmlns:ns2="http://interfaces/">
         <freelancerId>100bdf4b-f00e-4ac3-af60-5ef114c78d8e</freelancerId>
         <freelancerId>b4301546-7ac4-4ed8-bec6-40daad567414</freelancerId>
         <freelancerId>338cf80c-f36a-4302-95dd-4c1b0485f9d3</freelancerId>
      </ns2:GetByJobTypeResponse>
   </S:Body>
</S:Envelope>

Očividne teda zavadzia namespace pri <jobType>, no nie som si istý ako sa ho zbaviť, a či vôbec je to správne riešenie. Pred týmto som menil samotný Java interface, kde som pridal @WebParam atribúty do interfaceov, aby som sa vyhol SOAPu obsahujúcemu <arg0>.... Nie som si teda istý, či to nespôsobuje to.

Po vŕtaní sa vo generovanom WSDL mi nie je jasné, prečo tam ten namespace chýba, keďže XSD tam používa ten istý namespace:

<xs:schema version="1.0" targetNamespace="http://interfaces/" xmlns:tns="http://interfaces/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xs:element name="GetByJobType" type="tns:GetByJobType"/>
   <!-- other definitions -->
   <xs:complexType name="GetByJobType">
      <xs:sequence>
         <xs:element name="jobType" type="xs:string" minOccurs="0"/>
      </xs:sequence>
   </xs:complexType>
</xs:schema>

versus moje:

<definitions 
    xmlns="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:tns="http://interfaces/" 
    targetNamespace="http://interfaces/">
   <types>
      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://interfaces/" elementFormDefault="qualified">
         <xs:element name="GetByJobType" type="tns:GetByJobTypeType">
            <xs:complexType>
               <xs:sequence>
                  <xs:element name="jobType" type="xs:string" minOccurs="1" maxOccurs="1" />
               </xs:sequence>
            </xs:complexType>
         </xs:element>
      </xs:schema>
   </types>
jakubklimek commented 2 years ago

Ten problém bude způsoben právě tím, že jste si argumenty přejmenoval na jména bez targetNamespace (nekvalifikovaná).

Generované schéma nemá nastaveno elementFormDefault kde default je unqualified, tedy nehledě na targetNamespace definované elementy nejsou kvalifikované. Vaše schéma má "qualified", a tedy elementy patří do namespace.

Tedy když si je pojmenováváte, zřejmě bude třeba také nastavit ten target namespace, viz třeba: https://stackoverflow.com/questions/16915962/how-can-i-configure-the-target-namespace-globally-in-jax-ws-web-services, nebo ze schématu vyhodit tu kvalifikovanou formu.

SaNuelson commented 2 years ago

Ďakujem za pomoc. Vyriešil som to nakoniec zmazaním elementFormDefault="qualified" z WSDL.

Pridaním targetNamespace do @WebService sa mi to nepodarilo úplne vyriešiť. Presnejšie sa tento namespace nepropagoval do @WebParam a podobne, kde ho bolo treba dodefinovať explicitne pre každý parameter a return value.... Pri ďalšom hľadaní problému som napr. narazil na: https://stackoverflow.com/questions/5793352/jax-ws-why-nested-elements-are-in-namespace kde sa odpoveď odkazuje na už neaktuálnu stránku ws-i.org, ktorý tvrdí, že je to proper behaviour, a síce že namespace sa používa iba na vonkajší element a vnútorné elementy sú bez ak sa nemýlim.

Ak by to nebolo v poriadku, prosím, dajte vedieť, skúsim sa na to ešte pozrieť. No v momentálnej podobe je to, ak sa nemýlim, plne funkčné.