我正在使用JAX-WS开发WebService(我在jaxws-maven-plugin上使用wsimport目标).我编写了一个导入XSD架构的WSDL.
WEB-INF/wsdl/service.wsdl
WEB-INF/wsdl/service.xsd
Run Code Online (Sandbox Code Playgroud)
我还生成了Web服务类并创建了端点和所有.到目前为止,一切都很顺利.当我在Tomcat 7上运行我的服务时一切正常.我可以从我的浏览器访问wsdl:
http://localhost:8080/webService/servlet-url?wsdl
Run Code Online (Sandbox Code Playgroud)
但我无法访问xsd架构.问题出在这个wsdl中:
<xsd:schema>
<xsd:import namespace="http://ws.service/domain/1.0" schemaLocation="service.xsd"/>
</xsd:schema>
Run Code Online (Sandbox Code Playgroud)
当然,在生成类时,wsdl和xsd位于本地路径上,但我希望在Web服务运行时可以远程访问它们.我知道schemaLocation应该是这样的"http:// localhost:8080/webService/servlet-url?xsd = 1".
在wsdl中显示的浏览器导入schould看起来像:
<xsd:schema>
<xsd:import namespace="http://ws.service/domain/1.0" schemaLocation="http://localhost:8080/webService/servlet-url?wsdl&resource=service.xsd"/>
</xsd:schema>
Run Code Online (Sandbox Code Playgroud)
localhost:8080/webService/servlet?wsdl给了我:
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>
Run Code Online (Sandbox Code Playgroud)
等等...
我几乎不敢相信这是一个很难解决的问题!
我一直在google搜索拼了命的找到解决的正是这种问题!然后,我一直在努力寻找自己的解决方案。通过调试器逐步执行java-6-openjdk的默认javax.xml.ws.spi.Provider实现(在JRE中创建用于发布Web服务的javax.xml.ws.Endpoint对象的“工厂”),终于学到了一些东西,这帮助我制定了至少在Java SE中,至少在当前的JRE中有效的解决方案:
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)
Run Code Online (Sandbox Code Playgroud)
我尚不知道此解决方案是否可在Java EE中使用。
这是我解决的方法:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
至关重要的是,我首先使用Endpoint#create方法(而非Endpoint#publish)来获取未发布的 Endpoint。然后,将XSD文件作为“元数据”添加到(仍未发布的)端点(代码“ ep.setMetaData(...)”)。然后,我发布端点(代码“ ep.publish(...)”)。
现在,当我访问时,http://localhost:8080/svc/hello?wsdl我得到:
<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>
Run Code Online (Sandbox Code Playgroud)
我的XSD文件可以从那里获得http://localhost:8080/svc/hello?xsd=1!
请注意,磁盘上的MyService.wsdl文件仍然包含:
<xsd:schema>
<xsd:import namespace="http://somewhere.net/my/namespace"
schemaLocation="MyService.xsd"></xsd:import>
</xsd:schema>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17291 次 |
| 最近记录: |