2012-06-13 16 views
7

Sto sviluppando WebService con JAX-WS (sto usando l'obiettivo wsimport su jaxws-maven-plugin). Ho scritto un WSDL che importa uno schema XSD.schema xsd non presentato da wsdl

WEB-INF/wsdl/service.wsdl 
WEB-INF/wsdl/service.xsd 

Inoltre ho generato classi di servizi Web e creato endpoint e tutto. Tutto ha funzionato alla grande finora. Quando ho eseguito il mio servizio su Tomcat 7, tutto è ok. Posso accedere a una WSDL nel mio browser da:

http://localhost:8080/webService/servlet-url?wsdl 

ma non riesco a ottenere l'accesso a uno schema XSD. Il problema è in questo wsdl:

<xsd:schema> 
<xsd:import namespace="http://ws.service/domain/1.0" schemaLocation="service.xsd"/> 
</xsd:schema> 

Naturalmente durante la generazione di classi WSDL e XSD sono il percorso locale ma voglio che siano accessibili in remoto quando il servizio Web è in esecuzione. So che schemaLocation dovrebbe essere qualcosa del tipo "http: // localhost: 8080/webService/servlet-url? Xsd = 1".

In wsdl presentato in importazione del browser schould simile:

<xsd:schema> 
    <xsd:import namespace="http://ws.service/domain/1.0" schemaLocation="http://localhost:8080/webService/servlet-url?wsdl&resource=service.xsd"/> 
    </xsd:schema> 

localhost: 8080/webService/servlet wsdl mi dà:?

wsdl:definitions targetNamespace="http://ws.serv.com/Service/1.0" name="emuiaService">   
<wsdl:types> 
    <xsd:schema> 
     <xsd:import namespace="http://ws.serv.com/Service/domain/1.0" schemaLocation="schema.xsd"/> 
    </xsd:schema> 
</wsdl:types> 
<wsdl:message name="halloMsg"> 
    <wsdl:part name="parameters" element="dom:halloRequest"/> 
</wsdl:message> 
<wsdl:message name="halloResponseMsg"> 
    <wsdl:part name="return" element="dom:halloResponse"/> 
</wsdl:message> 

e così via ...

risposta

4

Quasi non riesco a credere che questo fosse un problema così difficile da risolvere!

Sono stato googling come un matto per trovare una soluzione esattamente a questo problema! Quindi ho faticato molto per trovare una soluzione da solo. Tramite debugger-stepping attraverso l'implementazione javax.xml.ws.sp.Provider predefinita di java-6-openjdk (la "factory" nel JRE che crea gli oggetti javax.xml.ws.Endpoint che si utilizzano per la pubblicazione di servizi Web) I finalmente imparato alcune cose, che mi ha aiutato a creare una soluzione che almeno funziona in Java SE, almeno nel mio attuale JRE, che è:

java version "1.6.0_33" 
OpenJDK Runtime Environment (IcedTea6 1.13.5) (6b33-1.13.5-1ubuntu0.12.04) 
OpenJDK Server VM (build 23.25-b01, mixed mode) 

se questa soluzione è utilizzabile in Java EE non so ancora.

Ecco come ho risolto:

package myservice; 

import java.io.IOException; 
import java.io.InputStream; 
import java.net.URL; 
import java.util.Arrays; 
import javax.xml.transform.Source; 
import javax.xml.transform.stream.StreamSource; 
import javax.xml.ws.Endpoint; 

public class App 
{ 
    private static final String MY_SERVICE_XSD = "/wsdl/MyService.xsd"; 

    public static void main(String[] args) 
    { 
     Endpoint ep = Endpoint.create(new MyEndpointImpl()); 

     ep.setMetadata(Arrays.asList(sourceFromResource(MY_SERVICE_XSD))); 

     ep.publish("http://localhost:8080/svc/hello"); 
    } 

    private static Source sourceFromResource(String name) { 
     URL resource = App.class.getResource(name); 
     String systemId = resource.toExternalForm(); 
     InputStream inputStream; 
     try { 
      inputStream = resource.openStream(); 
     } catch (IOException e) { 
      throw new RuntimeException("Failed to create InputStream from resource \""+ name +"\"", e); 
     } 
     return new StreamSource(inputStream, systemId); 
    } 
} 

La cosa fondamentale è che io primo metodo uso Endpoint # creo (non endpoint # pubblicano) per ottenere un inedito Endpoint. Quindi aggiungo il file XSD come "metadati" all'endpoint (ancora non pubblicato) (codice "ep.setMetaData (...)"). Quindi Io pubblico l'endpoint (codice "ep.publish (...)").

Ora, quando accedo http://localhost:8080/svc/hello?wsdl ottengo:

<definitions targetNamespace="http://somewhere.net/my/namespace" name="MyService"> 
     <types> 
      <xsd:schema> 
       <xsd:import namespace="http://somewhere.net/my/namespace" 
          schemaLocation="http://localhost:8080/svc/hello?xsd=1"/> 
      </xsd:schema> 
     </types> 
        ... 
    </definitions> 

e la mia XSD-file è disponibile da http://localhost:8080/svc/hello?xsd=1!

Si noti che il mio file MyService.wsdl su disco contiene ancora:

  <xsd:schema> 
       <xsd:import namespace="http://somewhere.net/my/namespace" 
          schemaLocation="MyService.xsd"></xsd:import> 
      </xsd:schema> 
+0

Davvero non ricordo cosa ho fatto ... probabilmente sono passato al contratto ma grazie per averlo risolto. Spero che aiuti qualcuno prima o poi;) – bemol

0

Ok, eccoci qui.

in un file WSDL per modificare il ritiro qualcosa di simile

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<wsdl:definitions 
     targetNamespace="http://service.wsr.company.com/" 
     name="webServiceExample" 
     xmlns="http://schemas.xmlsoap.org/wsdl/" 
     xmlns:tns="http://servicio.wsr.baz.com/" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
     xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> 

Su questo piccolo frammento importante sono tag xmlns. Quelli servono per l'implementazione dello schema XSD. Successivo

<wsdl:types> 
    <xs:schema 
     xmlns:tns="http://service.wsr.company.com/" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     targetNamespace="http://service.wsr.company.com/" version="1.0"> 

     ... 

    </xs:schema> 
</wsdl:types> 

in quelle tag di seguito si otterrà quello che hai in service.xsd file o mostrarlo in http://localhost:8080/webService/servlet-url?xsd=1 continuiamo

<wsdl:message name="your_method_name"> 
     <wsdl:part name="parameters" element="tns:your_method_name"/> 
    </wsdl:message> 
    <wsdl:message name="your_method_nameResponse"> 
     <wsdl:part name="parameters" element="tns:your_method_nameResponse"/> 
    </wsdl:message> 

Coloro tag sopra sono mostrare il nome del metodo. Successivo

<wsdl:portType name="webServiceExample"> 
      <wsdl:operation name="your_method_name"> 
      <wsdl:input message="tns:your_method_name"/> 
       <wsdl:output message="tns:your_method_nameResponse"/> 
      </wsdl:operation> 
    </wsdl:portType> 

Quelle sopra tar sono per mettere le vostre operazioni. Continuare

<wsdl:binding name="webServiceExamplePortBinding" type="tns:webServiceExample"> 
     <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> 
     <wsdl:operation name="your_method_name"> 
      <soap:operation soapAction=""/> 
      <wsdl:input> 
       <soap:body use="literal"/> 
      </wsdl:input> 
      <wsdl:output> 
       <soap:body use="literal"/> 
      </wsdl:output> 
     </wsdl:operation> 
    </wsdl:binding> 

Prossimo :)

<wsdl:service name="webServiceExample"> 
    <wsdl:port name="webServiceExamplePort" binding="tns:webServiceExamplePortBinding"> 
     <soap:address location="REPLACE_WITH_ACTUAL_URL"/> 
</wsdl:port> 

E finalmente finito :)

Si noti che è necessario modificare il tag corrente per tag<wsdl:...></wsdl:...>

Si salva, il pubblico e ci si diverte Lo schema XSD è presentato nel WSDL.

Spero di aiutarti. Ciao.

+0

Purtroppo non ha funzionato. Ancora lo schema xsd non viene presentato tramite http. – bemol

+0

Per favore, mostrami come stai e mostrami il tuo file WSDL. :) – hekomobile