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

在此之前,我想让您知道我已经可以连接到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(不包括ObjectFactorypackage-info )。 同时, MyMethodMyMethodResponse也是用于设置Web服务方法/操作的请求和响应参数的bean。

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

我是否正确

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

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

现在回答你的问题:

我的上述假设是否正确?

是的,你是。

其他课程的function是什么?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

使用wsimport生成客户端时以及使用Axis2或Apache CXF生成客户端时有什么不同

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

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

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

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

这就是为什么在运行webservice的同一服务器中发布wsdl永远不是一个好主意