Java JAX-WS客户端:什么&x27;访问本地WSDL的正确路径是什么?

Java JAX-WS客户端:什么&x27;访问本地WSDL的正确路径是什么?,java,netbeans,client,jax-ws,Java,Netbeans,Client,Jax Ws,问题是我需要从提供给我的文件中构建一个web服务客户端。我已将此文件存储在本地文件系统中,虽然我将WSDL文件保存在正确的文件系统文件夹中,但一切正常。当我将其部署到服务器或从文件系统文件夹中删除WSDL时,代理找不到WSDL并引发错误。我在网上搜索了一下,找到了以下帖子,但我还是没能成功: 我使用的是NetBeans 6.1(这是一个遗留应用程序,我必须使用这个新的web服务客户端进行更新)。下面是JAX-WS代理类: @WebServiceClient(name = "SOAS

问题是我需要从提供给我的文件中构建一个web服务客户端。我已将此文件存储在本地文件系统中,虽然我将WSDL文件保存在正确的文件系统文件夹中,但一切正常。当我将其部署到服务器或从文件系统文件夹中删除WSDL时,代理找不到WSDL并引发错误。我在网上搜索了一下,找到了以下帖子,但我还是没能成功:


我使用的是NetBeans 6.1(这是一个遗留应用程序,我必须使用这个新的web服务客户端进行更新)。下面是JAX-WS代理类:

    @WebServiceClient(name = "SOAService", targetNamespace = "http://soaservice.eci.ibm.com/", wsdlLocation = "file:/C:/local/path/to/wsdl/SOAService.wsdl")
public class SOAService
    extends Service
{

    private final static URL SOASERVICE_WSDL_LOCATION;
    private final static Logger logger = Logger.getLogger(com.ibm.eci.soaservice.SOAService.class.getName());

    static {
        URL url = null;
        try {
            URL baseUrl;
            baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource(".");
            url = new URL(baseUrl, "file:/C:/local/path/to/wsdl/SOAService.wsdl");
        } catch (MalformedURLException e) {
            logger.warning("Failed to create URL for the wsdl Location: 'file:/C:/local/path/to/wsdl/SOAService.wsdl', retrying as a local file");
            logger.warning(e.getMessage());
        }
        SOASERVICE_WSDL_LOCATION = url;
    }

    public SOAService(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }

    public SOAService() {
        super(SOASERVICE_WSDL_LOCATION, new QName("http://soaservice.eci.ibm.com/", "SOAService"));
    }

    /**
     * @return
     *     returns SOAServiceSoap
     */
    @WebEndpoint(name = "SOAServiceSOAP")
    public SOAServiceSoap getSOAServiceSOAP() {
        return super.getPort(new QName("http://soaservice.eci.ibm.com/", "SOAServiceSOAP"), SOAServiceSoap.class);
    }

    /**
     * @param features
     *     A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy.  Supported features not in the <code>features</code> parameter will have their default values.
     * @return
     *     returns SOAServiceSoap
     */
    @WebEndpoint(name = "SOAServiceSOAP")
    public SOAServiceSoap getSOAServiceSOAP(WebServiceFeature... features) {
        return super.getPort(new QName("http://soaservice.eci.ibm.com/", "SOAServiceSOAP"), SOAServiceSoap.class, features);
    }

}

这是我使用代理的代码:

   WebServiceClient annotation = SOAService.class.getAnnotation(WebServiceClient.class);
   // trying to replicate proxy settings
   URL baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource("");//note : proxy uses "."
   URL url = new URL(baseUrl, "/WEB-INF/wsdl/client/SOAService.wsdl");
   //URL wsdlUrl = this.getClass().getResource("/META-INF/wsdl/SOAService.wsdl"); 
   SOAService serviceObj = new SOAService(url, new QName(annotation.targetNamespace(), annotation.name()));
   proxy = serviceObj.getSOAServiceSOAP();
   /* baseUrl;

   //classes\com\ibm\eci\soaservice
   //URL url = new URL(baseUrl, "../../../../wsdl/SOAService.wsdl");

   proxy = new SOAService().getSOAServiceSOAP();*/
   //updating service endpoint 
   Map<String, Object> ctxt = ((BindingProvider)proxy ).getRequestContext();
   ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192);
   ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, WebServiceUrl);
WebServiceClient annotation=SOAService.class.getAnnotation(WebServiceClient.class);
//正在尝试复制代理设置
URL baseUrl=com.ibm.eci.soaservice.soaservice.class.getResource(“”)//注意:代理使用“”
URL=newURL(baseUrl,“/WEB-INF/wsdl/client/SOAService.wsdl”);
//URL wsdlUrl=this.getClass().getResource(“/META-INF/wsdl/SOAService.wsdl”);
SOAService serviceObj=新的SOAService(url,新的QName(annotation.targetNamespace(),annotation.name());
proxy=serviceObj.getSOAServiceSOAP();
/*baseUrl;
//classes\com\ibm\eci\soaservice
//URL URL=新URL(baseUrl,“../../../../../wsdl/SOAService.wsdl”);
proxy=newsoaservice().getSOAServiceSOAP()*/
//更新服务端点
Map ctxt=((BindingProvider)proxy).getRequestContext();
put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE,8192);
put(BindingProvider.ENDPOINT\u ADDRESS\u属性,WebServiceUrl);
NetBeans将WSDL的副本放在web inf/WSDL/client/SOAService中,所以我也不想将其添加到META-inf中。服务类位于WEB-INF/classes/com/ibm/eci/soaservice/中,baseurl变量包含指向它的文件系统完整路径(c:\path\to\the\project…\soaservice)。上述代码引发错误:

javax.xml.ws.WebServiceException:无法访问位于以下位置的WSDL:文件:/WEB-INF/WSDL/client/SOAService.WSDL。失败的原因是: \WEB-INF\wsdl\client\SOAService.wsdl(找不到路径)

那么,首先,我应该更新代理类的wsdllocation吗?那么,我如何告诉WEB-INF/classes/com/ibm/eci/SOAService中的SOAService类在\WEB-INF\WSDL\client\SOAService.WSDL中搜索WSDL


已编辑:我找到了另一个链接-,它表示将WSDL放入类路径。我不好意思问:如何将其放入web应用程序类路径?

最好的选择是使用jax-ws-catalog.xml

<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system">
        <system systemId="http://localhost/wsdl/SOAService.wsdl"
                uri="wsdl/SOAService.wsdl"/>
    </catalog>
编译本地WSDL文件时,重写WSDL位置并将其设置为

http://localhost/wsdl/SOAService.wsdl 到

注意,URL构造函数中的文件://已更改为http://

现在是jax-ws-catalog.xml。如果没有jax-ws-catalog.xml,jax-ws确实会尝试从该位置加载WSDL http://localhost/wsdl/SOAService.wsdl 并且失败,因为没有这样的WSDL可用

但是使用jax-ws-catalog.xml,您可以在jax-ws试图访问WSDL时将其重定向到本地打包的WSDL@ http://localhost/wsdl/SOAService.wsdl

这里是jax-ws-catalog.xml

<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system">
        <system systemId="http://localhost/wsdl/SOAService.wsdl"
                uri="wsdl/SOAService.wsdl"/>
    </catalog>

您所做的是告诉jax-ws,当它需要从 http://localhost/wsdl/SOAService.wsdl ,它应该从本地路径wsdl/SOAService.wsdl加载它

现在,您应该将wsdl/SOAService.wsdl和jax-ws-catalog.xml放在哪里?这就是百万美元的问题,不是吗?
它应该位于应用程序jar的META-INF目录中

像这样的

ABCD.jar |__ META-INF |__ jax-ws-catalog.xml |__ wsdl |__ SOAService.wsdl ABCD.jar |__META-INF |__jax-ws-catalog.xml |__wsdl |__SOAService.wsdl 这样,您甚至不必覆盖访问代理的客户端中的URL。WSDL是从您的JAR中获取的,您可以避免在代码中使用硬编码的文件系统路径

有关jax-ws-catalog.xml的更多信息


希望这有帮助

我们成功采取的另一种方法是使用wsimport(从Ant,作为Ant任务)生成WS-client代理代码,并指定wsdlLocation属性

<wsimport debug="true" keep="true" verbose="false" target="2.1" sourcedestdir="${generated.client}" wsdl="${src}${wsdl.file}" wsdlLocation="${wsdl.file}">
</wsimport>
注意:确保WSDL文件使用的是对任何导入的XSD的相对引用,而不是http URL:

  <types>
    <xsd:schema>
      <xsd:import namespace="http://valueobject.common.services.xyz.com/" schemaLocation="YourWebService_schema1.xsd"/>
    </xsd:schema>
    <xsd:schema>
      <xsd:import namespace="http://exceptions.util.xyz.com/" schemaLocation="YourWebService_schema2.xsd"/>
    </xsd:schema>
  </types>

也许这也有帮助。这只是一种不同的方法,不使用“目录”方法。

存在与本文描述的问题完全相同的问题。按照上面的例子,无论我做了什么来更改WSDL文件的位置(在我们的例子中是从web服务器),它仍然引用嵌入在服务器进程的源树中的原始位置

尝试调试这个问题很多个小时后,我注意到异常总是从完全相同的行抛出(在我的示例41中)。最后,今天早上,我决定将我的源客户机代码发送给我们的贸易伙伴,这样他们至少可以理解代码的外观,但也许可以构建自己的代码。令我震惊的是,在我的客户机源代码树中,我发现一堆类文件与我的.java文件混合在一起。真奇怪!!我怀疑这是JAX-WS客户端生成器工具的副产品

一旦我删除了那些愚蠢的.class文件,并对客户端代码进行了彻底的清理和重建,一切都会完美地工作!!好极了

YMMV,
Andrew

非常感谢Bhaskar Karambelkar的回答,详细解释并解决了我的问题。但我也想用三个简单的步骤为那些急于修复的人重新表述答案

  • 将您的wsdl本地位置引用设置为
    wsdlLocation=”http://localhost/wsdl/yourwsdlname.wsdl“
  • 在src下面创建一个META-INF文件夹。将wsdl文件放在META-INF下的文件夹中,比如META-INF/wsdl
  • 在META-INF下创建一个xml文件jax-ws-catalog.xml,如下所示

    
    

  • 现在打包你的罐子。不再引用本地目录,它都是包
    MyApp.jar
    |__META-INF
       |__wsdl
          |__YourWebServiceName.wsdl
          |__YourWebServiceName_schema1.xsd
          |__YourWebServiceName_schmea2.xsd
    
      <types>
        <xsd:schema>
          <xsd:import namespace="http://valueobject.common.services.xyz.com/" schemaLocation="YourWebService_schema1.xsd"/>
        </xsd:schema>
        <xsd:schema>
          <xsd:import namespace="http://exceptions.util.xyz.com/" schemaLocation="YourWebService_schema2.xsd"/>
        </xsd:schema>
      </types>
    
    /**
     * This class was generated by the JAX-WS RI.
     * JAX-WS RI 2.2-b05-
     * Generated source version: 2.1
     * 
     */
    @WebServiceClient(name = "YourService", targetNamespace = "http://test.webservice.services.xyz.com/", wsdlLocation = "/META-INF/wsdl/YourService.wsdl")
    public class YourService_Service
        extends Service
    {
    
        private final static URL YOURWEBSERVICE_WSDL_LOCATION;
        private final static WebServiceException YOURWEBSERVICE_EXCEPTION;
        private final static QName YOURWEBSERVICE_QNAME = new QName("http://test.webservice.services.xyz.com/", "YourService");
    
        static {
            YOURWEBSERVICE_WSDL_LOCATION = com.xyz.services.webservice.test.YourService_Service.class.getResource("/META-INF/wsdl/YourService.wsdl");
            WebServiceException e = null;
            if (YOURWEBSERVICE_WSDL_LOCATION == null) {
                e = new WebServiceException("Cannot find '/META-INF/wsdl/YourService.wsdl' wsdl. Place the resource correctly in the classpath.");
            }
            YOURWEBSERVICE_EXCEPTION = e;
        }
    
        public YourService_Service() {
            super(__getWsdlLocation(), YOURWEBSERVICE_QNAME);
        }
    
        public YourService_Service(URL wsdlLocation, QName serviceName) {
            super(wsdlLocation, serviceName);
        }
    
        /**
         * 
         * @return
         *     returns YourService
         */
        @WebEndpoint(name = "YourServicePort")
        public YourService getYourServicePort() {
            return super.getPort(new QName("http://test.webservice.services.xyz.com/", "YourServicePort"), YourService.class);
        }
    
        /**
         * 
         * @param features
         *     A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy.  Supported features not in the <code>features</code> parameter will have their default values.
         * @return
         *     returns YourService
         */
        @WebEndpoint(name = "YourServicePort")
        public YourService getYourServicePort(WebServiceFeature... features) {
            return super.getPort(new QName("http://test.webservice.services.xyz.com/", "YourServicePort"), YourService.class, features);
        }
    
        private static URL __getWsdlLocation() {
            if (YOURWEBSERVICE_EXCEPTION!= null) {
                throw YOURWEBSERVICE_EXCEPTION;
            }
            return YOURWEBSERVICE_WSDL_LOCATION;
        }
    
    }
    
    <wsdlLocation>classpath:META-INF/webservice.wsdl</wsdlLocation>
    
    <wsdlDirectory>src/main/resources/mydir</wsdlDirectory>
    <wsdlLocation>/mydir/my.wsdl</wsdlLocation>
    
    MyPort myPort = new MyPortService().getMyPort();
    
    <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>2.5</version>
    
    <dependencies>
        <dependency>
            <groupId>org.jvnet.jaxb2_commons</groupId>
            <artifactId>jaxb2-fluent-api</artifactId>
            <version>3.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.ws</groupId>
            <artifactId>jaxws-tools</artifactId>
            <version>2.3.0</version>
        </dependency>
    </dependencies>
    
    <executions>
        <execution>
            <id>wsdl-to-java-generator</id>
            <goals>
                <goal>wsimport</goal>
            </goals>
            <configuration>
                <xjcArgs>
                    <xjcArg>-Xfluent-api</xjcArg>
                </xjcArgs>
                <keep>true</keep>
                <wsdlDirectory>src/main/resources/package</wsdlDirectory>
                <wsdlLocation>/package/my.wsdl</wsdlLocation>
                <sourceDestDir>${project.build.directory}/generated-sources/annotations/jaxb</sourceDestDir>
                <packageName>full.package.here</packageName>
            </configuration>
        </execution>
    </executions>
    
    <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>2.6</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>wsimport</goal>
            </goals>
            <configuration>
                <bindingDirectory>${basedir}/src/main/resources/jaxws</bindingDirectory>
                <bindingFiles>
                    <bindingFile>binding.xjb</bindingFile>
                </bindingFiles>
                <wsdlDirectory>${basedir}/src/main/resources/wsdl</wsdlDirectory>
                <wsdlFiles>
                    <wsdlFile>VN_PCSApplicationManagementService_v21.xml</wsdlFile>
                    <wsdlFile>VN_PCSApplicationOfferManagementService_v7.xml</wsdlFile>
                    <wsdlFile>VN_PCSOnlineDebtService_v2.xml</wsdlFile>
                </wsdlFiles>
            </configuration>
        </execution>
    </executions>
    
    @Bean
    public ApplicationOfferManagementWSV7 getAppOfferWS() {
        String wsdlLocation = OnlineDebtWSv2Soap11QSService.class.getAnnotation(WebServiceClient.class).wsdlLocation().replaceFirst(".+wsdl/", "/wsdl/");
        URL url = this.getClass().getResource(wsdlLocation);
        ApplicationOfferManagementWSV7 applicationManagementWSV21 = new ApplicationOfferManagementWSV7Soap11QSService(url)
                .getApplicationOfferManagementWSV7Soap11QSPort();
    
        BindingProvider binding = (BindingProvider) applicationManagementWSV21;
        binding.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, username);
        binding.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
        binding.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, offerEndpoint);
    
        return applicationManagementWSV21;
    }