更改使用wsimport生成的Web服务客户端上的URL

时间:2010-08-25 15:57:06

标签: java web-services wsdl wsimport

我正在尝试为访问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的客户端代码吗?

2 个答案:

答案 0 :(得分:10)

这个答案一直困扰着我几天,但不知怎的,写这个问题的行为总是把我集中在寻找答案上,还有几个网络搜索指出了它:

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

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

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

似乎我在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生成我的代码。

答案 1 :(得分:6)

  

这种方法要求我提供一个我还不了解的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);