【问题标题】:xsd schema not presented by wsdlwsdl 未提供 xsd 架构
【发布时间】:2012-06-16 08:07:44
【问题描述】:

我正在使用 JAX-WS 开发 WebService(我在 jaxws-maven-plugin 上使用 wsimport 目标)。我编写了一个导入 XSD 模式的 WSDL。

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

我还生成了 Web 服务类并创建了端点等。到目前为止一切都很好。当我在 Tomcat 7 上运行我的服务时,一切正常。我可以通过以下方式在浏览器中访问 wsdl:

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

但我无法访问 xsd 架构。问题出在这个 wsdl 中:

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

当然,在生成类 wsdl 和 xsd 的过程中,它们位于本地路径上,但我希望在 Web 服务运行时可以远程访问它们。我知道 schemaLocation 应该是这样的“http://localhost:8080/webService/servlet-url?xsd=1”。

在浏览器导入的 wsdl 中应该是这样的:

<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 给我:

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>

等等……

【问题讨论】:

    标签: xsd wsdl jax-ws


    【解决方案1】:

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

    我一直在疯狂地搜索这个问题的解决方案!然后我一直在努力寻找自己的解决方案。通过调试器单步执行 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)
    

    这个解决方案是否可以在 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);
        }
    }
    

    关键是我首先使用方法 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>
    

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

    【讨论】:

    • 我真的不记得我做了什么...可能最后切换到合同但感谢您解决它。我希望有一天它对某人有所帮助;)
    【解决方案2】:

    好的,我们开始吧。

    到 WSDL 文件中修改类似这样的内容

    <?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/">
    

    在这个小sn-p 上重要的是xmlns 标签。这些用于部署模式 XSD。下一个

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

    在下面的标签中,您将获得service.xsd 文件中的内容或在http://localhost:8080/webService/servlet-url?xsd=1 中显示它,我们继续

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

    上面的标签显示你的方法名称。下一个

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

    上面的那些 tar 用于放置您的操作。继续

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

    下一个:)

       <wsdl:service name="webServiceExample">
         <wsdl:port name="webServiceExamplePort" binding="tns:webServiceExamplePortBinding">
           <soap:address location="REPLACE_WITH_ACTUAL_URL"/>
    </wsdl:port>
    

    终于完成了:)

    注意必须逐个标签改变当前标签 &lt;wsdl:...&gt;&lt;/wsdl:...&gt;

    您保存它,公众和您玩得开心XSD 架构在 WSDL 中呈现

    希望能帮到你。咻。

    【讨论】:

    • 不幸的是,这不起作用。仍然没有通过 http 呈现模式 xsd。
    • 请告诉我你是怎么做的,并给我看你的 WSDL 文件。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 2014-01-22
    相关资源
    最近更新 更多