31

首先,我想让您知道我已经可以连接到 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

通过上面的类,我可以看出其中com.datamodel.xsd包含 Web 服务服务器使用的 bean(不包括ObjectFactoryand package-info)。同时,MyMethod也是MyMethodResponse用于设置 Web 服务方法/操作的请求和响应参数的 bean。

以下是我的问题:(如果您不知道我的某些问题的答案,您实际上不必回答所有问题。:) 请随时分享您认为我可能会觉得有用的任何信息。)

我是否正确

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

2 回答 2

46

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

现在回答你的问题:

我的上述假设是否正确?

是的,你是。

其他类的作用是什么?

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

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

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

MyWebService最后,如果您想调用 Web 服务,该类包含您需要的客户端存根。

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

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

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

address它从WSDL 中port读取。service它位于 WSDL 的末尾。

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

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

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

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

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

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

使用 wsimport 生成客户端和使用 Axis2 或 Apache CXF 生成客户端时有什么区别吗

就在这里。wsimport 更好,不要使用 wsdl2java。这是一个描述,为什么

于 2012-09-03T13:04:19.257 回答
3

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

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

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

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

于 2013-03-15T11:21:09.203 回答