2012-06-13 15 views
7

Estoy desarrollando WebService con JAX-WS (estoy usando el objetivo wsimport en jaxws-maven-plugin). Escribí un WSDL que importa un esquema XSD.esquema xsd no presentado por wsdl

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

También genere clases de servicio web y extremo creado y todo. Todo funcionó muy bien hasta ahora. Cuando ejecuté mi servicio en Tomcat 7, todo está bien. Puedo tener acceso a un WSDL en mi navegador de:

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

pero no puedo acceder a un esquema XSD. El problema es que en este WSDL:

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

Por supuesto, durante la generación de las clases WSDL y XSD son en ruta local pero quiero que sean accesibles de forma remota cuando el servicio Web se está ejecutando. Sé que schemaLocation debería ser algo así como "http: // localhost: 8080/webService/servlet-url? Xsd = 1".

En WSDL presentado en la importación navegador schould aspecto:

<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 me da:?

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> 

y así sucesivamente ...

Respuesta

4

¡Casi no puedo creer que haya sido un problema tan difícil de resolver!

¡He estado buscando en Google como loco para encontrar una solución a este problema exactamente! Entonces he estado luchando muy duro para encontrar una solución por mi cuenta. Al depurar paso a paso la implementación javax.xml.ws.spi.Provider predeterminada de java-6-openjdk (la "fábrica" ​​en el JRE que crea los objetos javax.xml.ws.Endpoint que usa para publicar servicios web) I finalmente aprendido algunas cosas, lo que me ayudó a diseñar una solución que al menos funciona en Java sE, al menos en mi JRE actual, que es:

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) 

si esta solución es utilizable en Java EE no sé todavía.

Aquí es cómo lo resolví:

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); 
    } 
} 

Lo crucial es que por primera vez utilice el método de punto final # crea (no de punto final # publican) para obtener una inédito punto final. Luego agrego el archivo XSD como "metadatos" al Endpoint (aún no publicado) (código "ep.setMetaData (...)"). Luego Publico el punto final (código "ep.publish (...)").

Ahora cuando accedo a http://localhost:8080/svc/hello?wsdl me sale:

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

y mi XSD-archivo está disponible en http://localhost:8080/svc/hello?xsd=1!

Tenga en cuenta que mi archivo MyService.wsdl en el disco aún contiene:

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

Realmente no recuerdo lo que hice ... probablemente cambié al último contrato, pero gracias por resolverlo. Espero que ayude a alguien algún día;) – bemol

0

Está bien, aquí vamos.

en el archivo WSDL para modificate algo como esto

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

En este pequeño fragmento importante son etiquetas xmlns. Esos sirven para la implementación del esquema XSD. Siguiente

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

En los siguiente etiqueta que obtendrá lo que tiene en service.xsd archivo o mostrarlo en http://localhost:8080/webService/servlet-url?xsd=1 seguimos

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

Aquellos etiqueta de arriba son muestre su nombre del método. Siguiente

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

Los mencionados tar son para poner su operación. Continuar

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

Siguiente una :)

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

Y finalmente terminado :)

Tenga en cuenta que usted tiene que cambiar la etiqueta por etiqueta actual<wsdl:...></wsdl:...>

Lo guarda, el público y usted se divierte El esquema XSD se presenta en WSDL.

Espero que lo ayuden. Ciao.

+0

Desafortunadamente eso no funcionó. Todavía schema xsd no se presenta a través de http. – bemol

+0

Por favor, muéstrame cómo te va y muéstrame tu archivo WSDL. :) – hekomobile

Cuestiones relacionadas