Hallo zusammen!

Meine ersten Erfahrungen mit WebServices sind eigentlich recht erfolgreich, aber jetzt scheitere ich an einer automatischen Validierung des gesendeten XML...

Hier mal ein Minimalbeispiel:


Zunächst wäre da der eigentliche WebService:
Code java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
package de.myCompany.me.testStuff.webservice;
 
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
 
import com.sun.xml.internal.ws.developer.SchemaValidation;
 
@WebService(serviceName = "EchoWSService")
@SOAPBinding(style = Style.RPC)
@SchemaValidation
public class TestWebService {
 
    public String echo(@WebParam(name = "serviceData") final ServiceData data) {
        System.out.println(data.getValue());
        return data.getValue();
    }
}

Die ServiceData-Klasse ist völlig simpel, sei der Vollständigkeit wegen aber auch noch erwähnt:

Code java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package de.myCompany.me.testStuff.webservice;
 
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
 
@XmlAccessorType(XmlAccessType.FIELD)
public class ServiceData {
 
    @XmlElement(required = true)
    String value;
 
    public String getValue() {
        return value;
    }
 
    public void setValue(final String value) {
        this.value = value;
    }
 
}

Dann müssen wir das ja auch irgendwie starten. Nicht schön, aber schnell gemacht z.B. so:
Code java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package de.myCompany.me.testStuff.webservice;
 
import java.io.IOException;
 
public class main {
 
    public static void main(final String[] args) throws IOException {
        final HttpServer server = HttpServer.create(new InetSocketAddress(8080), 25);
        final HttpContext context = server.createContext("/jaxws/echo");
 
        final Endpoint endpoint = Endpoint.create(new TestWebService());
        endpoint.publish(context);
        server.start();
 
    }
}

So, ausführen und der WebService steht.

xsd und wsdl finden sich dann unter http://localhost:8080/jaxws/echo?wsdl bzw. http://localhost:8080/jaxws/echo?xsd=1:

xsd:
<?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. --><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0" targetNamespace="http://webservice.testStuff.me.myCompany.de/">

<xs:complexType name="serviceData">
<xs:sequence>
<xs:element name="value" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
Und die wsdl:

<?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. --><!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. --><definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://webservice.testStuff.me.myCompany.de/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://webservice.testStuff.me.myCompany.de/" name="EchoWSService">
<types>
<xsd:schema>
<xsd:import namespace="http://webservice.testStuff.me.myCompany.de/" schemaLocation="http://localhost:8080/jaxws/echo?xsd=1"></xsd:import>
</xsd:schema>
</types>
<message name="echo">
<part name="serviceData" type="tns:serviceData"></part>
</message>
<message name="echoResponse">
<part name="return" type="xsd:string"></part>
</message>
<portType name="TestWebService">
<operation name="echo">
<input message="tns:echo"></input>
<output message="tns:echoResponse"></output>
</operation>

</portType>
<binding name="TestWebServicePortBinding" type="tns:TestWebService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"></soap:binding>
<operation name="echo">
<soap:operation soapAction=""></soap:operation>
<input>
<soap:body use="literal" namespace="http://webservice.testStuff.me.myCompany.de/"></soap:body>
</input>
<output>
<soap:body use="literal" namespace="http://webservice.testStuff.me.myCompany.de/"></soap:body>
</output>
</operation>
</binding>
<service name="EchoWSService">
<port name="TestWebServicePort" binding="tns:TestWebServicePortBinding">
<soap:address location="http://localhost:8080/jaxws/echo"></soap:address>
</port>

</service>
</definitions>

Dann habe ich mir mit soapUi einen request erstellen lassen, der sieht so aus:

Code :
1
2
3
4
5
6
7
8
9
10
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservice.testStuff.me.myCompany.de/">
   <soapenv:Header/>
   <soapenv:Body>
      <web:echo>
         <serviceData>
            <value>Hallo</value>
         </serviceData>
      </web:echo>
   </soapenv:Body>
</soapenv:Envelope>

Nehme ich die Annotation @SchemaValidation im WebService raus, funnktioniert das ganze wie erwartet. Mit Validerung bekomme ich aber folgenden Fehler:

javax.xml.ws.WebServiceException: com.sun.istack.internal.XMLStreamException2: org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'web:echo'.
at com.sun.xml.internal.ws.util.pipe.AbstractSchemaValidationTube.doProcess(AbstractSchemaValidationTub e.java:230)
at com.sun.xml.internal.ws.util.pipe.AbstractSchemaValidationTube.processRequest(AbstractSchemaValidati onTube.java:199)
at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:587)
at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:546)
at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:531)
at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:428)
at com.sun.xml.internal.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:232)
at com.sun.xml.internal.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:460)
at com.sun.xml.internal.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:233)
at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handleExchange(WSHttpHandler.java:95)
at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handle(WSHttpHandler.java:80)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65)
at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:65)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:68)
at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:555)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65)
at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:527)
at sun.net.httpserver.ServerImpl$DefaultExecutor.execute(ServerImpl.java:119)
at sun.net.httpserver.ServerImpl$Dispatcher.handle(ServerImpl.java:349)
at sun.net.httpserver.ServerImpl$Dispatcher.run(ServerImpl.java:321)
at java.lang.Thread.run(Thread.java:619)
Caused by: com.sun.istack.internal.XMLStreamException2: org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'web:echo'.
at com.sun.xml.internal.ws.util.xml.StAXSource$1.parse(StAXSource.java:176)
at com.sun.xml.internal.ws.util.xml.StAXSource$1.parse(StAXSource.java:161)
at [...]
... 27 more
Ich glaube zu verstehen, dass irgendwas mit dem Namespace nicht passt - aber meiner Meinung nach sind die korrekt.

Google ergibt zwar, dass ich nicht der einzige mit diesem Problem zu sein scheine, aber eine Lösung habe ich nicht gefunden

Hoffe auf Hilfe...

Gruß,
RoCMe