2012-06-13 14 views
7

Zajmuję się tworzeniem WebService z JAX-WS (używam bramki wsimport na jaxws-maven-plugin). Napisałem plik WSDL, który importuje schemat XSD.Schemat xsd nie przedstawiony przez wsdl

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

Wygenerowałem również klasy usług internetowych i utworzony punkt końcowy i wszystko. Wszystko do tej pory działało świetnie. Kiedy uruchomiłem moją usługę na Tomcat 7, wszystko jest w porządku. mam dostępu do WSDL w przeglądarce od:

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

ale nie mogę uzyskać dostęp do schematu XSD. Problem polega na tym WSDL:

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

Oczywiście podczas generowania klas WSDL i XSD są na lokalnej drogi, ale chcę, żeby być zdalnie dostępne, gdy serwis internetowy jest uruchomiony. Wiem, że obiekt schemaLocation powinien wyglądać tak: http: // localhost: 8080/webService/servlet-url? Xsd = 1 ".

w WSDL przedstawiono w imporcie przeglądarki schould wyglądać następująco:

<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/Zestawienie/servlet WSDL daje mi:

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> 

i tak dalej ...

Odpowiedz

4

Prawie nie mogę uwierzyć, że to był tak trudny problem do rozwiązania!

Zgłosiłem się do pracy jak szalony, aby znaleźć rozwiązanie tego problemu! Wtedy bardzo trudno było znaleźć rozwiązanie na własną rękę. Przez debugger - przechodzenie przez domyślną implementację javax.xml.ws.spi.Provider java-6-openjdk ("fabryka" w środowisku JRE, która tworzy obiekty javax.xml.ws.Endpoint używane do publikowania usług sieci Web). w końcu nauczyłem się kilku rzeczy, które pomogły mi, by stworzyć rozwiązania, które przynajmniej działa w Java SE, przynajmniej w moim obecnym JRE, który jest:

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) 

czy to rozwiązanie jest użyteczne w Java EE nie wiem jeszcze.

Oto jak rozwiązać go:

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

Zasadniczą rzeczą jest to, że metoda pierwsze użycie Endpoint # tworzyć (nie Endpoint # publikować), aby uzyskać niepublikowane końcowego. Następnie dodaję plik XSD jako "dane meta" do (wciąż nieopublikowanego) punktu końcowego (kod "ep.setMetaData (...)"). Następnie Publikuję punkt końcowy (kod "ep.publish (...)").

Teraz kiedy mam dostępu http://localhost:8080/svc/hello?wsdl uzyskać:

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

i mój XSD-plik jest dostępny od http://localhost:8080/svc/hello?xsd=1!

Zauważ, że mój plik MyService.wsdl na dysku nadal zawiera:

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

Naprawdę nie pamiętam, co zrobiłem ... prawdopodobnie przerzuciłem się na ostatni kontrakt, ale dziękuję za rozwiązanie. Mam nadzieję, że pomoże to komuś kiedyś;) – bemol

0

Ok, zaczynamy.

do pliku WSDL służących do modyfikacji coś w tym

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

Na tym małym fragmencie ważne są tag xmlns. Te służą do wdrażania schematu XSD. Następny

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

do tych tagu poniżej dostaniesz co masz w service.xsd pliku lub pokazać go w http://localhost:8080/webService/servlet-url?xsd=1 nadal

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

tych powyżej tag są pokazać swoją nazwę metody. Następne:

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

Te powyższe tar są przeznaczone do wykonania operacji. Kontynuuj

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

Następny jeden :)

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

I wreszcie skończył :)

Należy pamiętać, że trzeba zmienić obecny tag po tagu<wsdl:...></wsdl:...>

Zapisujesz, publiczność i dobrze się bawisz. Schemat XSD został przedstawiony w dokumencie WSDL.

Mam nadzieję, że ci pomogę. Cześć.

+0

Niestety to nie działa. Wciąż schemat xsd nie jest prezentowany przez http. – bemol

+0

Proszę, pokaż mi, jak się masz i pokaż mi swój plik WSDL. :) – hekomobile