【问题标题】:Changing the URL on a webservice client generated with wsimport更改使用 wsimport 生成的 Web 服务客户端上的 URL
【发布时间】:2011-04-03 19:54:33
【问题描述】:

我正在尝试为访问 WSDL 描述的 web 服务的 Java 应用程序编写一个模块。源 WSDL 是直接从我认为是 ASP.NET Web 服务下载的;服务 URL 以 .asmx 扩​​展名结尾,在浏览器中查看服务 URL 会显示一个可用于下载 WSDL 的链接。

我的一个关键要求是能够在不重新编译的情况下切换服务 URL。给我的 URL 显然是一个测试服务器,我知道在生产中我会得到一个生产 URL 来使用。我还希望能够自己创建一个模拟服务器进行测试,并保留将来指定新 URL 的能力,而无需在移动服务时重新编译。事实上,我希望我们的应用程序能够在不同的 URL 上实例化 多个 的 web 服务实例。

但我的概念似乎与 wsimport 工具为我所做的不匹配。按照 f1sh 的回答 here,我使用以下命令从下载的 WSDL 生成 Java 代码:

wsimport -Xnocompile -keep -b binding.xml wsdlFile.wsdl

我发现生成的代码具有对我下载的 wsdlFile.wsdl 的硬编码引用,其中包含服务 URL。我们的应用程序不会以通过在运行时编辑 WSDL 文件来配置的方式运行。我需要在构建时将代码编译到我的应用程序中,并且可以在实例化时设置服务 URL。

我不完全确定为什么 WSDL 甚至需要在运行时进行解析;我的理解是 WSDL 提供了足够的信息来生成可以访问 web 服务的代码,所以我不确定它为生成的代码提供了什么而不是服务 URL,我不确定为什么没有提供服务 URL构造函数或可通过生成的 Web 服务类上的方法进行配置。我一定是错过了什么。

这种情况的一般做法是什么?大多数人是否会为他们将要使用的每个单独的 URL 重新生成代码?代码是在运行时生成的吗?我可以使用其他 WSDL 工具来构建具有可配置 URL 的客户端代码吗?

【问题讨论】:

    标签: java web-services wsdl wsimport


    【解决方案1】:

    这个答案已经让我想了好几天了,但不知何故,写这个问题的行为总是让我专注于寻找答案,而且还有更多的网络搜索指出了这一点:

    http://www.fransvanbuul.net/?p=98

    似乎 wsimport 创建了一个类 com.example.WebService,它扩展了 javax.xml.ws.Service。这个 WebService 类有两个构造函数。无参数构造函数使用 file:// URL 进行硬编码,以使用我生成的原始 WSDL。 (我想如果我在 wsimport 命令行上提供了 https:// URL,那将是硬编码的 URL。)或者,我可以使用两个参数的构造函数并在实例化时提供 WSDL URL!这种方法还需要我提供一个我还不理解的 javax.xml.namespace.QName 对象作为第二个参数。

    使用这个双参数构造函数可能会解决我的问题。

    我在 JDK 1.6 中使用的 wsimport 似乎是 JAX-WS 包的一部分。在最近的版本中,JDK 1.6 包含 JAX-WS 2.1,而 JAX-WS 2.2 将解决我在这个问题中提出的困难。

    我很乐意接受任何可以解释部分或全部其他情况的答案。我仍然不明白为什么在运行时需要 WSDL。更实际的是,如果有人向我展示如何使用双参数构造函数,或者如何使用 JDK 1.6 和 JAX-WS 2.2 生成我的代码,将会对我有所帮助。

    【讨论】:

      【解决方案2】:

      这种方法还需要我提供一个我还不理解的 javax.xml.namespace.QName 对象作为第二个参数。

      从您生成的源中复制一个。 QName 是 XML qualified name - 一个“唯一”身份。

      我仍然不明白为什么在运行时需要 WSDL。

      我不能肯定地说我知道,但是 WSDL 基本上是一个模式。通过提供它,我猜您为 JAX-WS 提供了一种机制来验证 SOAP 响应。我认为 JAXB 绑定不足以做到这一点。

      我总是在生成的服务中使用两个参数的构造函数,通过ClassLoader.getResource 方法提供一个 URL 来将 WSDL 嵌入到我的 jar 中。与任何架构一样,为此使用远程或文件系统 URL stupid 不是最佳的。

      this question for how to set the end-point at runtime:

      HelloService service = new HelloService();
      Hello port = service.getHelloPort();
      BindingProvider bindingProvider = (BindingProvider) port;
      bindingProvider.getRequestContext().put(
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
            "http://foo:8086/HelloWhatever");
      String response = port.sayHello(name);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-29
        • 2015-08-20
        • 1970-01-01
        • 2010-09-17
        • 1970-01-01
        相关资源
        最近更新 更多