xsd schema not presented by wsdl
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...
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>
Ok, here we go.
Into WSDL file to modificate something like this
<?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/">
On this little snippet important are xmlns tag. Those serve for deployment of schema XSD. Next
<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>
Into those tag below you'll get what you have in service.xsd
file or show it in http://localhost:8080/webService/servlet-url?xsd=1
we continue
<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>
Those above tag are show your method name. Next
<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>
Those above tar are for put your operation's. Continue
<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>
Next one :)
<wsdl:service name="webServiceExample">
<wsdl:port name="webServiceExamplePort" binding="tns:webServiceExamplePortBinding">
<soap:address location="REPLACE_WITH_ACTUAL_URL"/>
</wsdl:port>
And finally finished :)
Note that you have to change the current tag by tag <wsdl:...></wsdl:...>
You save it, the public and you have fun XSD schema is presented in the WSDL .
I hope help you. Ciao.
链接地址: http://www.djcxy.com/p/60602.html上一篇: AS3 TypeError:错误#1007:尝试对非实例化
下一篇: xsd模式不由wsdl提供