上一篇blog里提到过,WSDL规范其实就好比是我们国家的法侓,它规定了公民(好比是SOAP消息)应该要怎么行使个人权力以及履行个人义务等,即具有指导性的意义。用比较规范的语言来说就是WSDL是用来描述一个异构组件如何被程远程未知平台调用的,即描述了SOAP消息的格式,在WEB服务中起到了服务端和服务客户端之间的契约作用。
在系列的第一篇文章里已经提到,系统的目标是:Web 服务客户机在事先不了解一个 Web 服务的组成的情况下可以动态地发现和调用该Web 服务。
那么,我们需要做什么才能动态地发现和调用这个服务?
首先,需要发现来自系统的服务资源库里关于此服务的信息,这个就是我在系列(六):Web服务搜索与执行引擎(六)--基于Lucene的Web服务检索 中写到的关于Web服务搜索模块如何从库里提取服务信息,一个最重要的信息是服务所对应的WSDL 文档的URL。
其次,需要阅读来自服务提供者的 WSDL文档并进行解析,以获取各种信息。这一步就是本篇文章所要关注的。
最后,我将拥有足够的信息来使用SAAJ发送和接收对 Web 服务实现的 SOAP 请求。这一步就是在后续文章里将要写到的。
那么我们就来看看如何阅读来自服务提供者的 WSDL文档并进行解析?
WSDL的常用处理方法:
- 基于 DOM 的方法:上一篇blog也说到了, WSDL 文件从本质上来讲是一个 XML 文件,现有的 DOM API(例如 Xerces)能够用来进行解析或者构建 WSDL 文件。这种方法是最通用的,但同时也是处理 XML 文件最费力的方法。尽管从技术上来讲是可行的,基于 DOM API 的实现对于代码敏感且容易出错。同时,这一解决方法迫使您不得不处理两个完全不同的模型:DOM 和 WSDL 模型。
- 基于特定 API 的方法: 利用 IBM 的 WSDL4J 来实现 WSDL 操作。这种方法倾向于 WSDL 模型,它允许您直接操作 WSDL 。这种方法的不足在于您不仅要处理 WSDL 本身,还要处理 WS-Addressing、WS-Policy 和扩展脚本。它同时还使用那些尚未成为标准的事物,这就意味着现有的一些 API 将会改变。这就意味着这种基于特定 API 的方法不得不掺杂一定数量的 DOM 处理。 但是这些不足跟前面提到的“倾向于 WSDL 模型,它允许您直接操作 WSDL”的好处比起来,我们还是觉得使用它是当前的最好选择。
- 基于 Java 生成的方法:因为描述我们实现的所有脚本都是标准的 XML 脚本,因此可以生成对应于这些脚本的 Java 类(支持 XML 编组和分组)。在这种情况下, WSDL 文件直接转化为 Java 类,然后作为 Java 对象来管理,使用这种方式一个缺陷就是使客户程序代码庞大,臃肿,不好管理,增加了系统的复杂性。
WSDL4J简介——解析和收集来自 WSDL 的信息
WSDL4J是用来解析WSDL文件的技术,很多WEB服务的底层实现都用了该技术。
但在传统的WEB服务实现方案中,该技术作为底层实现被屏蔽。而我们的项目为了能够动态的调用异构平台的未知服务,必须使用该技术。
所以说WSDL4J 包将被用于以编程方式表示 WSDL 文件的元素,所以我可以浏览和收集来自该文件的各种信息。
在服务资源库中查找 Web 服务
为了动态地调用 Web 服务,必须知道一些基本信息,如此Web服务的WSDL文档的URL、Web服务的名称。当服务消费者在同一种服务中,即搜索结果中选择一个后,可以根据服务ID,以及Vector totalservices获取一个Web服务对象,这个对象包含了有关远程Web服务的足够信息,注意是足够信息,当然有最起码的WSDL 文档的 URL。既然我知道了WSDL 实现的 URL,那我就可以继续用 WSDL4J 直接请求来自服务提供者的文档并对其进行解析,从而获得了下一步调用服务所需要的一个完全的Web服务信息,如操作的调用参数信息等等。
解析 WSDL
既然经过上面步骤我们拥有了用于 Web 服务的 WSDL文档的 URL,那么我们现在就可以用到WSDL4J来解析它了。为了使用 SAAJ构建SOAP消息调用该服务,我们将需要从 WSDL 收集下列最基本的信息:
目标名称空间
服务名称
端口名称
操作名称
操作输入参数
这时候如果大家对上面这些概念不太熟悉或者忘记了WSDL的详细细节,请翻看我上一篇blog: