wsimport 生成的客户端如何工作?

2022-09-01 09:46:12

在进行其他任何操作之前,我希望您知道我已经可以连接到 Web 服务服务器。我问这个问题是因为我想更深入地了解wsimport生成的客户端是如何工作的。根据我的研究,wsimport使用JAXWS。请注意,我对JAXWS一无所知。

我使用wsimport生成了我的客户端。我使用的 WSDL 来自 Axis2 Web 服务,由 Axis2 自动生成。以下类是wsimport的结果:

com.datamodel.xsd

  • DataBeanRequest.java
  • DataBeanResponse.java
  • ObjectFactory.java
  • package-info.java

com.service

  • MyWebService.java
  • MyWebServicePortType.java
  • MyMethod.java
  • MyMethodResponse.java
  • ObjectFactory.java
  • package-info.java

通过上面的类,我可以分辨出它包含Web服务服务器使用的bean(不包括和)。同时,也用于设置Web服务方法/操作的请求和响应参数。com.datamodel.xsdObjectFactorypackage-infoMyMethodMyMethodResponse

以下是我的问题:(如果你不知道我的一些问题的答案,你真的不必回答所有的问题。:)请随时分享您认为我可能会发现有用的任何信息。

我是对的吗

  • 我上面的假设是否正确?
  • 其他类的功能是什么?
  • 我检查了一下,它包含一个注释,引用了我用于生成客户端的WSDL的绝对位置。在客户端中指定 的相关性是什么?客户端如何使用该信息?MyWebServicewsdllocation
  • 我注意到 Web 服务的实际 URL 未在生成的任何类中声明。客户端如何知道它需要连接到的位置?
  • 是否对 WSDL 文件进行了批注,以便客户端可以在连接时读取 WSDL 文件上的 URL?如果是这样,那么这是否意味着在必须建立新连接时始终读取 WSDL 文件?
  • 由于我需要编译应用程序并将其安装在其他服务器上,因此将变得无效。是否可以将其设置为相对路径而不是绝对路径?如何?(答:是的,可以将其设置为相对路径。wsimport 命令具有 wsdllocation 属性,其中可以指定 wsdllocation 的值。
  • 如果我需要连接到 HTTPS,该怎么办?如何设置服务器证书?
  • 当我使用wsimport生成我的客户端和使用Axis2或Apache CXF生成它时,有什么区别吗?

答案 1

在我回答这些问题之前,请先澄清一下:JAX-WS 是一个在 Java 中实现 Web 服务的规范。它描述了如何将 WSDL 工件映射到 Java 类,以及如何使用注释应用此映射。您可以在此处下载规范。工具 wsimport 是此规范的参考实现的一部分,而参考实现是 Java 类库的一部分。有几种替代实现,如Axis2,CXF或Metro,它们增强了基本的JAX-WS支持,并支持其他标准,如WS-ReliableMessaging或WS-Security。

现在回答您的问题:

我上面的假设是否正确?

是的,你是。

其他类的功能是什么?

的存在是为了将 Web 服务中使用的 XML 命名空间映射到实现类所在的包。命名空间通常看起来与 Java 包名称不同(通常,它是一个 URL),这使得映射成为必要。package-info

允许您创建服务发送和接收的任何消息。如果你想在存根类前面挂接代码,提供修改后的消息或类似的东西,你需要这个。ObjectFactory

我看不到你的类的内容,但是如果我理解正确的话,它是一个类似于你的WSDL中的界面。也就是说,它将 WSDL 中的操作及其签名映射到 Java 方法。如果你想提供服务(你不这样做,你是在询问客户端),你需要实现这个接口。实现客户端时,只需使用它即可。MyWebServicePortTypeportType

最后,该类包含要调用 Web 服务时所需的客户端存根。MyWebService

我检查了MyWebService,它包含一个注释,引用了我用于生成客户端的WSDL的绝对位置。在客户端中指定 wsdllocation 有什么意义?客户端如何使用该信息?

您生成的接口包含服务的签名,但它没有说明如何与服务通信。这是 WSDL 中绑定的一部分。最基本的设置是通过 HTTP 使用 SOAP 的消息的文档/文本样式。其他配置(如基于 JMS 的 SOAP)是可能的,并且您的客户端需要知道要使用哪种协议。因此,它需要绑定 WSDL。此外,正如您稍后所述,Java 文件中没有端点地址。此地址也从 WSDL 读取。portType

我注意到 Web 服务的实际 URL 未在生成的任何类中声明。客户端如何知道它需要连接到的位置?

它从 WSDL 中的 读取 。它位于 WSDL 的末尾。addressportservice

是否对 WSDL 文件进行了批注,以便客户端可以在连接时读取 WSDL 文件上的 URL?

不,它是具体 Web 服务终结点的典型元素。这里没有什么特别需要的。port

如果是这样,那么这是否意味着在必须建立新连接时始终读取 WSDL 文件?

好吧,客户端可能有缓存(我不知道这个参考实现的细节)。从概念的角度来看:是的,是的。

如果我需要连接到 HTTPS,该怎么办?如何设置服务器证书

这可能很棘手,我不能给你一个开箱即用的答案。我建议通读有关此主题的问题,例如本问题

当我使用wsimport生成我的客户端和使用Axis2或Apache CXF生成它时,有什么区别吗?

是的,有。wsimport 更好,不要使用 wsdl2java。这是一个描述,为什么


答案 2

你问:我注意到Web服务的实际URL没有在生成的任何类中声明。客户端如何知道它需要连接到的位置?

如果 WSDL 是使用浏览器下载的,并作为输入传递给 wsimport,则本地 wsdl 文件位置将嵌入到生成的代码中。这就是您在生成的代码中看不到实际服务位置的原因。这也意味着,如果您删除了 wsdl 文件的本地副本,则生成的代码将不起作用(当使用 main 方法进行 inovk 时)。

如果 wsdl 的 URL 作为输入传递给 wsimport,则该 URL 将嵌入到生成的代码中,该代码将进一步用于获取实际的服务位置。这个想法是WSDL位置是固定的。它们应位于 UDDI 中或作为本地文件。这允许实际的服务四处移动,如果它们确实移动,则只需单独修改 wsdl 文件的本地副本或更新 UDDI 中的 wsdl。[大多数情况下,这不会发生,因为服务位置从来都不是IP,而是DNS名称]

这就是为什么在运行 Web 服务的同一台服务器上发布 wsdl 从来都不是一个好主意


推荐