xsd模式不是由wsdl呈现的

bem*_*mol 7 xsd wsdl jax-ws

我正在使用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)

等等...

Mik*_*und 5

我几乎不敢相信这是一个很难解决的问题!

我一直在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)