我按照以下步骤创建了一个网络服务:
- 使用 @WebService 和 @WebMethod 注释创建服务接口(interface)和实现
- 已部署服务
- 使用 wsimport 生成客户端 stub
通过客户端程序调用 Web 服务,如下所示:
public static void main(String[] args) throws Exception { URL url = new URL("http://SERVER:PORT/HelloWorldPOC/HelloWorldPOCImplService?wsdl"); QName qname = new QName("http://helloworld.poc.com/", "HelloWorldPOCImplService"); Service service = Service.create(url, qname); HelloWorldPOCImpl hello = service.getPort(HelloWorldPOCImpl.class); hello.execute("hello"); System.out.println("Done"); }
问题:
- WSDL 位置在客户端程序中提供。 WSDL 位置也硬编码在 wsimport 生成的客户端 stub 中。为什么要进行这种冗余?
我使用 wsimport 使用“localhost”路径创建了客户端 stub :
wsimport -keep http://localhost:9080/HelloWorldPOC/HelloWorldPOCImplService?wsdl
- 我从本地主机运行客户端测试程序,URL 服务器部分为“localhost”。有效。然后从另一个系统运行相同的客户端,其中服务器部分作为服务器的主机名。它起作用了。
- 这意味着生成的客户端 stub 中的 WSDL 位置未使用?
- 我们可以在本地主机上生成 WSDL 并将其部署到任何地方,而无需重新生成客户端 stub 吗?只有调用者客户端需要从已部署的服务器检索 WSDL。这是可接受的做法还是我们需要为每个部署的服务器重新生成客户端?
最佳答案
- 您可以将其理解为默认位置,该位置将被 99% 覆盖。在我生成的代码中,也可以在没有指定 wsdl URL 的情况下创建服务,因此将使用默认 URL。
- 当你覆盖wsdl文件的默认URL地址时,它当然不会被使用。很多时候,webservice 生产者只给我们 wsdl 文件,然后我们从放置在本地硬盘上的 wsdl 生成 stub ,因此我们始终需要覆盖默认值。
PS:我可以闲聊另一种技术,如何在不生成 stub 的情况下调用 Web 服务。您只需要客户端上可用的“远程接口(interface)”之类的东西(由服务器类实现)。当您负责生成和使用 Web 服务时,这是非常高效的。当接口(interface)演变时它非常高效,因为当你改变它时,你不需要重新生成 stub 。以下示例使用 JBoss 7 (JAX-WS) 作为服务器,并在客户端上使用 Apache CXF 库: http://www.mastertheboss.com/jboss-web-services/developing-web-services-on-jboss-as-7
关于JAX-WS 部署最佳实践 : WSDL location and client generation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12278327/