Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

xsd schema not presented by wsdl

Tags:

wsdl

xsd

jax-ws

I'm developing WebService with JAX-WS(i'm using wsimport goal on jaxws-maven-plugin). I wrote a WSDL that imports a XSD schema.

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

Also I generated web service classes and created endpoint and all. Everything worked great so far. When I ran my service on Tomcat 7 everything is ok. I can access a wsdl in my browser from:

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

but I cannot get access to a xsd schema. The problem is in this wsdl:

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

Of course during generation of classes wsdl and xsd are on local path but i want them to be remotely accessible when web service is running. I know that schemaLocation should be something like this "http://localhost:8080/webService/servlet-url?xsd=1".

In wsdl presented in browser import schould look like:

<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 gives me:

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>

and so on...

like image 823
bemol Avatar asked Jun 13 '12 11:06

bemol


People also ask

How do I get XSD for WSDL?

xsd using following steps : Create library (optional) > Right Click , New Message Model File > Select SOAP XML > Choose Option 'I already have WSDL for my data' > 'Select file outside workspace' > 'Select the WSDL bindings to Import' (if there are multiple) > Finish. This will give you the . xsd and .

Does WSDL contain XSD?

The difference I noticed is that WSDL contains XSD and in WSDL we can declare operations, but not in XSD .


1 Answers

I almost can't believe that this was such a difficult problem to solve!

I've been googling like mad to find a solution to exactly this problem! Then I've been struggling really hard to find a solution on my own. By debugger-stepping through the java-6-openjdk's default javax.xml.ws.spi.Provider implementation (the "factory" in the JRE that creates the javax.xml.ws.Endpoint objects that you use for publishing web services) I finally learnt some things, which helped me to craft a solution that at least works in Java SE, at least in my current JRE, which is:

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)

Whether this solution is usable in Java EE I don't know yet.

Here is how I solved it:

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

The crucial thing is that I first use method Endpoint#create (not Endpoint#publish) to get an unpublished Endpoint. Then I add the XSD-file as "meta data" to the (still unpublished) Endpoint (code "ep.setMetaData(...)"). Then I publish the endpoint (code "ep.publish(...)").

Now when I access http://localhost:8080/svc/hello?wsdl I get:

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

and my XSD-file is available from http://localhost:8080/svc/hello?xsd=1!

Note that my MyService.wsdl file on disk still contains:

            <xsd:schema>
                <xsd:import namespace="http://somewhere.net/my/namespace"
                            schemaLocation="MyService.xsd"></xsd:import>
            </xsd:schema>
like image 90
Mikko Östlund Avatar answered Dec 29 '22 05:12

Mikko Östlund