简介
Woden项目是Apache Web Services项目演化而来的一个子项目,主要用来开发用于读/写、操作、创建WSDL文档的Java类库,在初始阶段支持WSDL2.0,但是随着开发的继续,将会支持各种版本的WSDL。
Woden主要包含了两部分内容,API和API的实现。Woden API包含了Java接口的集合。基于WSDL2.0规范的Woden API会与W3C的WSDL2.0规范相兼容。接口的实现会具有很好的性能,并且直接在其他的Apache项目中使用,例如Axis2。
下载
用户指南
1. 简介
本指南用于解释如何使用Woden的外部接口。这些外部接口目前包括Woden API,但是随着开发的进展,Woden可能还会包含其他的配置技术,命令行工具和基于脚本的工具,例如Ant任务。Woden的用户都是其他工具和技术的开发人员,他们使用Woden来解析和操作WSDL文档。
本指南不会讨论Woden的内部实现,而是讨论如何使用Woden,在这当中可能会涉及到Woden的设计原则。
2. Woden概述
Woden项目的初衷是开发一个实现了W3C WSDL 2.0规范的WSDL 2.0 处理器,以便满足开发工作组对实现的需求。这包括定义和实现相分离的Woden API,以便其他工程在维护外部接口时可以修改或者替换Woden实现。下一步的目标是包含支持高性能的XML解析和对WSDL1.1的支持。
完成上述目标的目的是:
® 开发一个WSDL解析器(最早是基于DOM的),用于序列化和反序列化WSDL 2.0文档
® 定义与W3C WSDL 2.0兼容的WSDL对象模型,包括支持WSDL和类型系统扩展功能
® 使创建和修改WSDL可以通过对象模型来编程完成
® 使Woden成为一个可配置的,可扩展的框架,来支持特定实现例如自定义的对象工厂、验证和错误处理
® 开发一个框架扩展机制,可以使用不同的XML解析器来支持不同的性能需求和使用方案,然后开发一个WSDL解析器实现,基于XML流的PULL解析器,例如StAX
® 支持反序列化WSDL 1.1文档,并且将其转换为WSDL 2.0 对象模型
® 支持反序列化WSDL 1.1文档,并且可以使用JWSDL对象模型表示它们
® 开发可理解的基于JUnit的测试
在本指南中描述的目前Woden包含的功能包括:
® 用于获取WSDL reader(或者解析器)对象的工厂机制
® 基于Apache Xerces的reader的DOM实现
® 配置WSDL reader的属性,例如是否开启验证
® 使用reader来解析(反序列化)WSDL文档
® 两种类型的WSDL 2.0对象模型:一个表示WSDL 2.0抽象组件模型,另外一个映射到XML元素和WSDL命名空间中的属性
® 解析WSDL 2.0命名空间中几乎所有的所有的元素和属性
® 使用WSDL 2.0规范定义的断言来进行WSDL的部分验证,目前的验证包括Types、Interface和Binding。
® 使用WSDL 2.0对象模型操作WSDL
® 支持扩展元素和属性
® 在WSDL 2.0规范中定义的SOAP绑定扩展中使用这种扩展机制
® 自定义的错误处理机制,用于报告警告,错误和致命错误
上属于计划中的功能,在目前的Weden中还不包含的有:
® 解析HTTP绑定扩展
® SAOP、HTTP绑定扩展、Service、import、include元素的WSDL验证
® 处理包含实体或者catalog resolver的URL
® 扩展Woden,以便支持其他XML解析器的机制
® 这种解析器扩展机器的StAX实现
® 扩展Woden使其支持W3C以外的类型系统,例如DTD、RelaxNG
® 序列化WSDL对象模型到WSDL,即写入WSDL文档
® 解析WSDL 1.1文档并将其转换为WSDL 2.0对象模型
® 解析WSDL 1.1文档并使用JWSDL对象模型表示
3. 下载和安装
通过以下两种方式下载Apache Woden WSDL处理器:
获取Woden源代码,然后编译源代码
获取二进制发布包
Woden的基于DOM的XML解析依赖于Apache Xerces 2.7.1。它的XML Schema支持它依赖于schema解析器和对象模型,由Apache Web Services Commons XMLSchema项目实现。
阶段性构建包包含了所有需要的类库,下面的类库必须被添加到类路径中:
woden.jar包含了Woden类库
xercesImpl.jar和xml-apis.jar包含了Apache Xerces 2.7.1
XmlSchema-SNAPSHOT.jar包含了Apache ws-commons XmlSchema
如果是使用Woden源代码,而不是发布包,那么需要下载Apache Xerces 2.7.1。
最后,Woden需要使用Java 1.4或者以上的版本。
4. Getting Started
本部分包含了一些样例代码,用来描述Woden编程模型。
下面的代码演示了如何获取WSDLFactory对象,WSDLFactory对象用于获取WSDLReader对象(WSDL解析器)。是否进行WSDL验证被设置为true,然后调用readWSDL方法,从指定的URL中读取WSDL文档,并返回DescriptionElement对象,该对象代表了WSDL <description>元素和它包含的对象,它声明了映射到XML元素和属性的API。这将作为Element API。toComponent方法返回Description对象,Description对象表示WSDL 2.0 组件模型总的Description模型。Description声明的API和其包含的对象被作为Component API。
WSDLFactory factory = WSDLFactory.newInstance();
WSDLReader reader = factory.newWSDLReader();
reader.setFeature(WSDLReader.FEATURE_VALIDATION, true);
// <-- the <description> element
DescriptionElement descElem = reader.readWSDL(wsdlurl);
// <-- the Description component
Description descComp = descElem.toComponent();
wsdl参数是一个String类型的URL,例如:
wsdlurl="http://ws.org.apache/woden/services/Booking.wsdl"
wsdlurl="C:/woden/services/Booking.wsdl"
可以通过如下的方法获取顶层WSDL元素:
InterfaceElement[] interfaces = descElem.getInterfaceElements();
BindingElement[] bindings = descElem.getBindingElements();
ServiceElement[] services = descElem.getServiceElements();
这个例子展示了如何获取全局的schema元素声明(由Apache ws-commons XmlSchema中的XmlSchemaElement类表示)
InterfaceElement interfaceElem = interfaces[0];
InterfaceFaultElement[] faults = \
interfaceElem.getInterfaceFaultElements();
XmlSchemaElement xsElem = faults[0].getElement();
当WSDL文档时通过多个WSDL文档组成的时(通过使用<import>和<include>元素),可以通过调用DescriptionElement的getImportElements方法和getIncludeElements方法来遍历WSDL模块:
ImportElement[] imports = descElem.getImportElements();
DescriptionElement importedDescElem = \
imports[0].getDescriptionElement();
Description组件同样包含了用于获取顶层WSDL组件的方法,但是和DescriptionElement的方法不同,这些方法的返回值是WSDL中的flatten元素,也就是说返回顶层组件的初始描述以及所有imported和included描述:
Interface[] allInterfaces = descComp.getInterfaces();
Binding[] allBindings = descComp.getBindings();
Service[] allServices = descComp.getServices();
下面的例子演示了如何根据Description组件获取所有的ElementDeclaration和typeDefinition组件。这些表示了WSDL <types>中或者imported的XML Schema的全局schema元素声明和类型定义。同样,这也是flattened视图,包含了schema组件:
ElementDeclaration[] elemDecls = descComp.getElementDeclarations();
TypeDefinition[] typeDefs = descComp.getTypeDefinitions();
5. Woden API
本部分提供了一个Woden API的概要。
Woden WSDL处理器是作为一个框架被实现的,用户可以添加自定义的特征到框架中来对框架进行扩展。这种实现的细节被woden API隐藏。只有扩展点在Woden API中被显示,作为可以被再次实现的Java接口或者作为可以被继承的Java类。有了基于API的Woden扩展和编程模型,用户不需要引用Woden实现类的代码。
Woden API包含了两个子API,在Getting Started中已经介绍过了,代表了两种不同的WSDL 2.0对象模型。
Element API代表了WSDL 2.0名称空间中的XML元素和属性的模型。
Component API代表了抽象的WSDL组件模型。
但是Element和Component API主要用于WSDL的表示和操作,而其他的Woden API主要用于如何使用、配置和扩展WSDL处理器。Woden API主要包含了这些更一般的特征和WSDL特定的特征。但是如果需要讨论这些WSDL特定的API的话,就可能需要使用Element或者Component API了。
API
Woden API是由Java接口和一小部分Java类组成的,它们的包名以org.apache.woden开头。woden实现的包的名字以org.apache.woden.interval,以便和API的包进行区分。所有其他的org.apache.woden包都是Woden API的一部分。下面是一些最重要的API:
org.apache.woden:包含了Woden WSDL处理器的核心组件 – WSDLFactory、WSDLReader、WSDLException、ErrorReporter、ErrorHandler。
org.apache.woden.schema:包含了表示XML Schemas(内含的和导入的)的接口。这些表示了<xs:schema>和<xs:import>格式的XML Schemas。这两种格式的元素都可以直接出现在WSDL的<types>元素。
org.apache.woden.wsdl20.extensions:表示了支持扩展元素和属性的扩张框架。包含了注册用户自定义序列器和反序列器以及用于扩展的Java映射的机制。
org.apache.woden.wsdl20.extensions.soap:包含了映射到SOAP绑定扩展的Java类。
org.apache.woden.wsdl20:包含了组成Component API的Java接口。
org.apache.woden.wsdl20.xml:包含了组成Element API的Java接口。
核心API特征
Woden API的核心特征包括:
创建Woden对象的工厂机制
通过设置WSDLReader的features或者properties来配置Woden的行为
自定义错误处理
注册自定义的扩展
操作基于XML的WSDL元素和属性的模型(通过Element API)
操作抽象的WSDL组件模型(通过Component API)
WSDLFactory类包含了静态的newInstance()和newInstance(String className)方法,用于创建工厂对象。没有参数的方法根据策略来搜索用户配置的工厂类名称,如果没有找到自定义的工厂类,那么使用默认的Woden提供的工厂类。搜索策略如下:首先检查Java系统属性,然后检查JAVA-HOME/lib目录的一个属性文件(开发人员希望可以在MEATA-INF/services目录中查找,但是尚未实现)。这个类的Javadoc提供了详细的系统属性和属性文件的名字。带参数的方法允许开发人员指定要被实例化的工厂类,这个工厂类对象用于创建一些Woden编程时关键的对象,例如WSDLReader、DescriptionElement和ExtensionRegistry。
Woden的解析方法可以通过设置WSDLReader对象的属性来进行配置。注意,这是Woden特定的配置内容,不要和WSDL Feature和Property组件相混淆。Reader的特性通过setFeature方法来配置,方法的参数为feature名和boolean值,来表示feature是否启用。getFeature方法用来查询特定的feature是否被启用。Reader的property通过setProperty方法来设置,方法的参数为property名和属性值(一个对象,用来表示属性)。同样,getProperty方法用来返回特定属性名的属性值。Woden定义的features和properties都定义为WSDLReader接口的public static final常量。更多内容可以参考Javadoc。
Woden API通过4个接口和WSDLException类提供了错误处理。如果发生系统配置错误,那么统一抛出WSDLException,并且包含合适的错误信息。WSDL解析错误通过ErrorReporter类来报告,ErrorReporter类将报告的样式指派给ErrorHandler,ErrorHandeler识别三种类型的错误:warnings、errors和fatal errors。Woden提供了默认的错误处理器实现,将3种类型的消息打印到System.out,如果是fatal errors的话,那么结束处理,并抛出WSDLException。用户可以提供自定义的ErrorHandler实现来自定义错误处理。ErrorReporter的setErrorHandler方法用于指定用户自定义的错误处理实现。用于定义的Woden扩展可以使用ErrorReporter,通过来报告错误,或者获取格式化的错误信息。错误消息需要包含一个错误id和一些文本错误信息,但是用户可以定义丰富格式的信息,或者使用带参数的Java ResourceBunder。ErrorInfo定义了数据对象,包含了传递到ErrorHandler的错误信息。这当中包含了ErrorLocator,用于指定WSDL源文档的URI,以及发生错误位置的行号和列号。
扩展元素和属性(WSDL 2.0名称空间之外的元素和属性)通过Woden扩张框架来进行处理。对于每个扩展元素,用户定义的ExtensionDeserializer和ExtensionSerializer接口实现会将元素映射到/从一些用户定义的ExtensionElement,ExtensionElement表示元素。反序列器、序列器和Java映射类都是通过ExtensionRegistry来进行注册,这样WSDLReader(或者WSDLWriter—尚未实现)在遇到这样的元素时,就会知道如何进行处理。Woden API包含了ExtensionElement实现,用来表示SOAP绑定扩展(WSDL 2.0规范中定义)。如果要处理没有被注册的扩展元素,那么就会使用默认的处理器,UnknowDeserializer、UnknowSerializer和UnknowExtensionElement类。Woden定义的扩展(SOAP和位置)和在ExtensionRegistry预注册。
org.apache.woden.xml包含了表示更普通的扩展属性值类型(string、QName、boolean等等)。这些都是XMLAttr类的子类,这个类定义了init方法用于解析扩展属性值,toExternalForm方法使用string来表示值。用户可以扩展XMLAttr类来支持其他类型的值。XMLAttr的子类必须使用父类名字和扩展属性的QName来注册。这样WSDLReader就可以有足够的信息来正确的解析。在WSDL 2.0规范中定义的扩展属性会使用XMLAttr的子类在ExtensionRegistry中进行预定义。
下面讨论一下Element和Component API。
Element API
Element API可以嵌套的查看WSDL文档中出现的WSDL元素。例如,DescriptionElement声明了getInterfaceElements、getBindingElements和getServiceElements提供了访问WSDL顶层元素的方法。InterfaceElement声明了getInterfaceFaultElements和getInterfaceOperationElements方法。
在org.apache.woden.wsdl20.xml中,每个WSDL元素都使用Java接口来表示。每个WSDL元素中的WSDL属性通过那些接口的适当的方法来表示,例如,DescriptionElement接口包含了getTargetNamespace方法。
注意,Element API不包括对混合结构的WSDL进行flatten。例如getServiceElements方法返回<description>下面的<service>元素,但不是那些通过Imported和included元素中的<service>。为了获取所有混合结构的WSDL中的ServiceElement,需要使用DescriptionElement元素的getImportElements和getIncludeElements方法。
Component API
Component API表示WSDL 2.0规范定义的抽象WSDL组件模型。这和Element API的区别在于特定的WSDL XML的方面不再Component模型中表示。在Component模型中不获取<documentation>元素。<types>元素和特殊的类型系统,例如XML Schema都不被表示,但是,Component API包含ElementDeclaration和TypeDefinition,它们提供了全局元素声明和类型定义的泛化表示,例如在XML Schema中所使用的。
WSDL中通过<import>和<include>元素完成的结构不在Component模型中表示。取而代之的是,Description组件代表了整体,混合WSDL结构和它的属性(表示顶层WSDL组件,例如Interface、Binding和Service),包含了WSDL的flattened表示。例如,Description的getInterfaces方法会不仅返回description元素中的interfaces,同时也返回在任何imported和included元素中定义的interfaces。
WSDL元素到API的映射
WSDL element Element API Component API
<description> DescriptionElement Description
<documentation> DocumentationElement
<import> ImportElement
<include> IncludeElement
<types> TypesElement
<interface> InterfaceElement Interface
<fault> InterfaceFaultElement InterfaceFault
<operation> InterfaceOperationElement InterfaceOperation
<input> InterfaceMessageReferenceElement InterfaceMessageReference
<output> InterfaceMessageReferenceElement InterfaceMessageReference
<infault> FaultReferenceElement InterfaceFaultReference
<outfault> FaultReferenceElement InterfaceFaultReference
<binding> BindingElement Binding
<fault> BindingFaultElement BindingFault
<operation> BindingOperationElement BindingOperation
<input> BindingMessageReferenceElement BindingMessageReference
<output> BindingMessageReferenceElement BindingMessageReference
<infault> FaultReferenceElement BindingFaultReference
<outfault> FaultReferenceElement BindingFaultReference
<service> ServiceElement Service
<endpoint> EndpointElement Endpoint
<feature> FeatureElement Feature
<property> PropertyElement Property
XML Schema element
<xs:import> ImportedSchema
<xs:schema> InlinedSchema
<xs:element name=".."> ElementDeclaration
<xs:complexType name=".."> TypeDefinition
6. Woden URI处理器
这允许使用不同的URI来表示WSDL 2.0 和XML Schema文档。Woden自带了这样一个处理器,同时提供了定义不同实现的API。
用户可以自由的创建自定义URI Resolvers,通过实现org.apache.woden.resolver.URIResolver。
resolver应该在调用WSDLReader的readWSDL方法之前被注册。样例:
URIResolver myResolver = new CustomURIResolver();
WSDLFactory factory = WSDLFactory.newInstance();
WSDLReader reader = factory.newWSDLReader();
reader.setURIResolver(myResolver);
...
reader.readWSDL(…);
SimpleURIResolver
这是Woden发布包中包含的URI Resolver实现,它也是默认的实现。当请求WSDLReader对象时,SimpleURIResolver会自动的被初始化,并注册到WSDLReader对象。也就是说,下面的语句会隐式的调用:
reader.setURIResolver(new SimpleURIResolver());
在必要的时候,可以以编程的方式注册自定义的resolver。
Catalog文件模式
catalog文件遵循Java属性文件的语法。但是,在catalog中,表达式左边和右边的含义是不一样的。
<resolve-from URI>=<resolve-to URI>
resolve-from URI是解决的主题,resolve-to URI是resolver查找资源的目标位置。resolve-to URI需要是一个合法的URL。
根据约定,URI catalog文件名包含后缀.catalog,但是这不是必须的。
注意,每个实体行的第一个”:”必须被转移。
在SimpleURIResolver被实例化的时候,schema catalog会按顺序被读入。如果一个resolve-from URI存在多个对应的实体,使用最后一个。
样例:
A.绝对路径
资源存在于NTFS文件系统:
http\://test.com/interface.wsdl=file:///c:/resources/interface.wsdl
资源存在于Un*x文件系统:
http\://test.com/interface.wsdl=file:///resources/interface.wsdl
资源存在于远程服务器,通过http访问:
http\://test.com/interface.wsdl=http://aplace.org/resources/interface.wsdl
B.相对路径
如果想对URI出现在resolve-to实体中,那么将使用一个检索路径来将它们转换为绝对路径。任何包含协议的resolve-to被认为是相对的,否则就是绝对的。
默认情况下,将从左到右在Java classpath中搜索一个base URI来使相对URI完整。然而,在classpath中预先设置用户自定义的base locations列表会更加有效。系统属性org.apache.woden.resolver.simpleresolver.baseURIs可以用来制定这个列表。
例如,假设希望处理两个保存在文件系统上的文件:/wsdl/resouces/interface.wsdl,/xsd/resources/schema.xsd和一个包含在/mydocs.jar中的文件/wibble/random.wsdl。这是设置org.apache.woden.resolver.simpleresolver.baseURIs属性的值为file:///wsdl/;file:///xsd/;file:///mydocs.jar。注意结尾的”;”之前的”/”表示这是一个base URI。如果省略的话,那么实体被假设为一个JAR文件的URL。现在我们可以使用如下的定义:
http\://test.com/importinterface.wsdl=resources/interface.wsdl
http\://test.com/myschema.xsd=resources/schema.xsd
http\://test.com/random.wsdl=wibble/random.wsdl
注意,当resolver创建resolution table的时候,对于每个相对路径,baseURI列表会从左到右的被匹配。
典型的配置是将baseURI设置为单衣路径,而所有的相对URI都使用这个基路径。
C.JAR文件URLs
有些资源被保存在jar文件中,并且可能被作为绝对的resolve-to URL。
http\://test.com/doit.wsdl=jar:file:///wibble/pling.jar!/doit.wsdl
Configuration Properties
当SimpleURIResolver被实例化后,就会检查两个系统属性:
org.apache.woden.resolver.simpleresolver.catalog
org.apache.woden.resolver.simpleresolver.baseURIs
第一个属性应该包含一个表示用户catalog文件的URL。如果没有设置的话,就不会发生URI resolving,除非在woden schema catalog中定义了。
使用Woden WSDLReader的程序可以使用下面的代码片断来配置URI Resolver来解析WSDL文档:
System.setProperty(“org.apache.woden.resolver.simpleresolver.catalog”,
”file:///myplace/myresolves.catalog”);
System.setProperty(“org.apache.woden.resolver.simpleresolver.baseURIs”,
“file:///wsdl/;file:///xsd/;file:///mydocs.jar”);
// instantiates the default resolver
WSDLReader reader = factory.newWSDLReader();
// this is also a candidate for the resolver
reader.readWSDL(“file:///mydoc.wsdl”);
自动schema处理 – schema.catalog
Woden schema catalog是预定义的catalog,在SimpleURIResolver实例化的时候会被自动加载。在用户自定义的catalog之前被加载。
Woden schema catalog包含了标准XML Schema,WSDL 2.0 Schema,可以在没有网络的情况下使用这些schema。由于用户定义的catalog是后加载的,所以可以通过重新定义来覆盖这些schema。
默认的schema catalog放在META-INF/schema.catalog。
发表于 @ 2008年06月05日 11:17:22|编辑|收藏