级别: 初级 Ping Wang, 资深软件工程师, IBM
2005 年 3 月 01 日 本文讲解了如何利用 IBM ®WebSphere® Application Server V6 来开发和部署定制数据绑定。它用来帮助 Web 服务开发者为 XML 脚本类型提供定制数据绑定,目前基于 XML RPC(JAX-RPC) 规范的 Java ™API 不支持那些 XML 脚本。
引言
通常, Web 服务以 XML 消息的形式交换数据,这种 XML 消息遵循特定的 XML 脚本。为直接使用 XML 脚本,已经习惯了 Java 对象的 Java 程序员,不得不使用底层的 XML API。在许多情况下,对于 Java 程序员来说,使用 XML API 例如文档对象模型 (DOM) 来开发 Web 服务应用很不方便,而操纵 Java 对象并通过运行时系统来处理底层的序列化和逆序列化要相对容易的多。
为实现上述操作,你不得不定义特定的规则来将 XML 脚本类型映射到 Java 类型以及将 Java 类型映射到 XML 脚本类型。将 XML 脚本类型映射到 Java 类型的过程有时被称为数据绑定。目前,已有几个公开的规范来定义 XML 到 Java 的数据绑定,例如基于 XML RPC(JAX-RPC) 的 Java API,XML 绑定的 Java Architecture (JAXB) (参见 参考资料)。然而,由于 XML 脚本的复杂性,并不是所有的 XML 脚本类型都支持这些开放规范。
JAX-RPC 规范通过一个特殊的方法突破了这一限制,即将所有不支持的脚本类型映射到一个通用的数据结构:javax.xml.soap.SOAPElement,或简称为 SOAPElement。与 DOM 元素相似,SOAPElement 是一个数据结构,程序员可利用支持 Java 的 SOAP Attachment API 来浏览 XML 内容 (参见 参考资料)。对那些不支持的脚本类型(参见 附录),JAX-RPC 要求程序员直接处理 XML 数据,而不是使用相似的 Java 类型。
尽管映射到 SOAPElement 对于特定的以数据为中心的应用是可以接受的,但对于强类型的系统通常不推荐这么做。另外,对于数据为中心的应用,SOAPElement 并不总是最佳选择。例如,你可能希望使用另外一种通用类型系统如服务数据对象 (SDO) (参见 参考资料)。即使对于已经支持的 XML 脚本类型,你也可能希望寻找另外一种替代的数据映射方法而不是缺省的 JAX-RPC 映射。这种选择特别重要,尤其当你需要将 XML 脚本类型映射到一些遗留类型时。
因此,对于特定的脚本类型,就需要扩展或覆盖现有的映射方式。本文讲述针对 WebSphere Application Server V6 的一个插件式机制来开发和部署定制数据绑定。
一个 SDO 脚本示例
清单 1 为一个通过服务数据对象 (SDO) 规范定义的 XML 脚本。
清单 1. SDO 定义的 XML 脚本
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:sdo="commonj.sdo"
targetNamespace="commonj.sdo">
<xsd:element name="datagraph" type="sdo:DataGraphType"/>
<xsd:complexType name="DataGraphType">
<xsd:complexContent>
<xsd:extension base="sdo:BaseDataGraphType">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="1"
namespace="##other" processContents="lax"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="BaseDataGraphType" abstract="true">
<xsd:sequence>
<xsd:element name="models" type="sdo:ModelsType" minOccurs="0"/>
<xsd:element name="xsd" type="sdo:XSDType" minOccurs="0"/>
<xsd:element name="changeSummary"
type="sdo:ChangeSummaryType" minOccurs="0"/>
</xsd:sequence>
<xsd:anyAttribute namespace="##other" processContents="lax"/>
</xsd:complexType>
<xsd:complexType name="ModelsType">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded"
namespace="##other" processContents="lax"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="XSDType">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded"
namespace="http://www.w3.org/2001/XMLSchema" processContents="lax"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ChangeSummaryType">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded"
namespace="##any" processContents="lax"/>
</xsd:sequence>
<xsd:attribute name="create" type="xsd:string"/>
<xsd:attribute name="delete" type="xsd:string"/>
</xsd:complexType>
</xsd:schema>
|
随着 SDO 在 Java 开发者团队中越来越受到欢迎,利用 SDO API 来开发 Web 服务应用程序的需要变得很明显。然而,当您利用上述脚本开发 Web 服务应用程序,很可能你在服务端点接口 (SEI) 看不到 SDO 类型,因为带有 QName {commonj.sdo}DataGraphType 的脚本类型以及包含 xsd:anyAttribute 的引用类型目前还不被 JAX-RPC 支持。
如果将这些 SDO 类型映射到 SOAPElement, 对于 SDO 程序员来说,很显然是不方便的。SDO 已经提供了各种 API 来操纵数据,在 SDO 和 SOAPElement API 之间 SDO 程序员将很难取舍。在本文中我们利用这一脚本为示例来说明如何为 DataGraphType 构建定制绑定以及如何来发布应用程序。
开发定制绑定
定制绑定是一个带有一组特定的 XML 脚本和 Java 类型函数。定制绑定定义了一组函数来在 Java 对象和 SOAPElement 之间进行转换。在定制转换插入运行时系统后,绑定通过以下面的方式使用 SOAPElement 来与运行时系统交互。
不同于传统的逆序列化,定制绑定不依赖底层的解析事件(例如来自运行时系统的 XML 简单 API(SAX))来构建 Java 对象。相反,运行时系统首先将接收的 SOAP 消息包装为一个合适的 SOAPElemen,然后将其传递到绑定进行进一步的解析。例如,如果接收的消息包含一个 SDO datagraph,运行时系统将:
- 识别出
<sdo:Datagraph> 片断。
- 为 datagraph 数据查询它的类型映射系统以定位到一个合适的定制绑定 (如 SDOCustomBinder) 。
- 构建一个合适的 SOAPElement,它代表接收的 SDO datagraph。
- 将 SOAPElement 传递到 SDOCustomBinder。
在逆序列化方法中,SDOCustomBinder 从传递的 SOAPElement 中提取出内容,然后利用 commonj.sdo.DataGraph 类型来构建一个固定的 DataGraph 对象。整个流程如图 1 所示。
图 1. Web 服务运行和定制绑定之间的交互
同样,当 Java 对象序列化的时候,运行时系统定位合适的绑定器,然后将 Java 对象转换为 SOAPElement。然后运行序列化 SOAPElement 为原始的消息。在这种情况下,SOAPElement 作为 SOAP 消息的一个中间格式,因此定制绑定不需要关心将原始的 XML 数据转换为输出流的细节。
CustomBinder 接口
WebSphere Application Server V6 定义了一个 CustomBinder 接口,程序员通过实现这个接口来为特定的 XML 脚本类型提供固定的定制绑定。如清单 2 所示,除了序列化和逆序列化方法,CustomBinder 还有 3 个属性,可以通过相应的 getter 方法来访问它们。这 3 个属性分别为 XML 脚本类型 的 QName 、QName 范围和要转换为的 Java 类型。
清单 2. CustomBinder 接口定义
package com.ibm.wsspi.webservices.binding;
public interface CustomBinder {
public final static String QNAME_SCOPE_ELEMENT = "element";
public final static String QNAME_SCOPE_COMPLEXTYPE = "complexType";
public final static String QNAME_SCOPE_SIMPLETYPE = "simpleType";
public javax.xml.namespace.QName getQName();
public String getQNameScope();
public String getJavaName();
public javax.xml.soap.SOAPElement serialize(
Object bean,
javax.xml.soap.SOAPElement rootNode,
CustomBindingContext context)
throws javax.xml.soap.SOAPException;
public Object deserialize(
javax.xml.soap.SOAPElement source,
CustomBindingContext context)
throws javax.xml.soap.SOAPException;
}
|
方法 getQName
getQName 方法返回目标 XML 脚本类型的 QName 。定制绑定仅仅与 root 级脚本类型定义一起工作,即 <xsd:complexType>、 <xsd:simpleType> 和不带类型属性的 <xsd:element>的全局定义。通常,前面两个称为命名类型,后面的称为匿名类型,因为嵌入在 <xsd:element> 定义中的类型定义没有真正的名字。
对于命名的类型,getQName方法返回脚本类型定义的 QName。对于匿名类型,getQName 方法返回封装元素的 QName。如果命名元素和匿名元素使用同样的 QName,他们通过 qnameScope 属性来区分。
方法 getQNameScope
getQNameScope 方法返回绑定的 qnameScope 属性,来说明脚本类型是命名类型还是匿名类型。通常,qnameScope 的值可以是元素(例如匿名类型)、复杂类型(如 xsd:complexType) 或简单类型 (如 xsd:simpleType) 。
由于命名类型和匿名类型的不同,qnameScope 属性将影响到定制绑定如何与运行时系统交互。对于匿名类型,绑定必须知道它的封装元素,因此,序列方法返回的 SOAPElement 与封装元素具有同样的 QName。对于命名类型,绑定不知道引用元素。运行负责将引用元素的有效 QName 传递到定制绑定。
方法 getJavaName
getJavaName 方法返回 Java 类型的全名,利用它 定制绑定进行工作。这个类既可以是个接口,也可以是个明确的类。逆序列化方法返回的对象与 getJavaName 方法返回的名称兼容。
方法 serialize
序列化方法返回一个定制绑定根据 Java 对象构建的 SOAPElement。Java 对象由运行时系统传递而来,且它的类型期望与 getJavaName 方法的返回值相匹配。SOAPElement 参数没有子元素除了一个有效的 QName。参数作为绑定的引用用来最终创建一个 SOAPElement。
在多数情况下,绑定实现将子元素添加到传递的 root SOAPElement。运行时系统保证 SOAPElement 的 QName 的正确性。因此,命名类型的定制绑定保持根元素的 QName,因为绑定对封装元素一无所知。对于匿名类型,绑定实现应该确保返回的 SOAPElement 的 QName 与定义的脚本类型匹配。CustomBindingContext 参数在 WebSphere Application Server V6 release 版本中没有任何明确的方法,这一参数目前主要作为将来版本的占位。
方法 deserialize
deserialize 方法返回定制绑定根据传递的 root SOAPElement 构建的 Java 对象。返回的 Java 对象的类型那必须与 getJavaName 方法的返回值相匹配。不同与 serialize 方法的参数,传递的 SOAPElement 包含带有所有必须的命名空间生命的原始 XML 数据。
示例: SDO DataGraph 绑定
清单 3 演示了一个 SDO DataGraph 绑定的实现,其中,convertToSDO 和 convertToSAAJ 是用来在 SOAPElement 和 SDO 对象间进行转换的实用方法。
清单 3. SDO DataGraph 绑定
package test.sdo.binder;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import com.ibm.wsspi.webservices.binding.CustomBinder;
import com.ibm.wsspi.webservices.binding.CustomBindingContext;
public class DataGraphBinder implements CustomBinder {
public QName getQName() {
return new QName("commonj.sdo", "DataGraphType");
}
public String getQNameScope() {
return CustomBinder.QNAME_SCOPE_COMPLEXTYPE;
}
public String getJavaName() {
return commonj.sdo.DataGraph.class.getName();
}
public javax.xml.soap.SOAPElement serialize(
Object bean,
SOAPElement rootNode,
CustomBindingContext context)
throws javax.xml.soap.SOAPException {
// convertToSAAJ is a utility method to convert
// the SDO DataGraph to the SOAPElement
return convertToSAAJ(bean, rootNode);
public Object deserialize(
SOAPElement source,
CustomBindingContext context)
throws javax.xml.soap.SOAPException {
// convertToSDO is a utility method to convert
// the SOAPElement to the SDO DataGraph
return convertToSDO(source);
}
}
|

 |

|
定义定制绑定的提供者
定制绑定定义了序列化和逆序列化运行时的行为。剩下的问题是如何将定制绑定插入开发工具和运行时系统来确保开发工具能够产生合适的构件,运行时系统能够将定制绑定添加到现有类型映射系统,并在适合的时候调用。
定制绑定通常与一个特定的 XML 脚本类型一起工作,然而实际的应用程序经常调用几个相关的 XML 脚本类型。因此,您需要一个机制来聚合并声明各种定制绑定来提供一个完整的定制绑定解决方案。这里引入定制绑定提供者的概念来定义一个声明模型,以将一组定制绑定插入开发工具或运行时系统中。
本节介绍如何创建一个定制绑定提供者和它的元数据文件,以及如何将绑定提供者应用到开发中。
定制绑定提供者
定制绑定提供者是一个带有声明元数据文件的定制绑定类的包。它的主要目的是通过聚合相关的定制绑定来支持特定的用户场景。一个典型的例子就是为一个特定的应用程序创建绑定提供者,这个应用程序有几个 XML 脚本类型是不被 JAX-RPC 规范支持的。通常,XML 脚本文件和绑定提供者间建立一对一的关系,XML 脚本文件包含绑定提供者管理的脚本类型。然而,这种关系并不是严格的,创建一个绑定提供者来支持多个 XML 脚本文件也是合法的。
声明元数据文件 CustomBindingProvider.xml 是一个 XML 文件, 它通常与定制绑定类一起打包到一个 Java 文档 (JAR) 文件中并放置在 /META-INF/services/ 目录。在提供者 Jar 文件打包后,它包含了所有需要的信息(二进制文件和元数据文件),并可被加入开发工具或运行时系统。
定制绑定提供者脚本
清单 4 是文件 CustomBindingProvider.xml 的 XML 脚本。顶级类型是 providerType,它包含一个映射元素列表,每一个映射元素对应一个相关的定制绑定和一些属性如 xmlQName、javaName 和 qnameScope,这些属性对应的值由关联的定制绑定来定义。providerType 还有一个称为 scope 的属性,它的值可以是服务器、应用程序或模块。scope 属性用来在服务器部署时来解决冲突和实现定制绑定层次。
清单 4. CustomBindingProvider.xml 的脚本定义
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
targetNamespace=
"http://www.ibm.com/webservices/customdatabinding/2004/06"
xmlns:customdatabinding=
"http://www.ibm.com/webservices/customdatabinding/2004/06"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="qualified">
<xsd:element name="provider" type="customdatabinding:providerType"/>
<xsd:complexType name="providerType">
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element name="mapping" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element name="xmlQName" type="xsd:QName"/>
<xsd:element name="javaName" type="xsd:string"/>
<xsd:element name="qnameScope"
type="customdatabinding:qnameScopeType"/>
<xsd:element name="binder" type="xsd:string"/>
</xsd:sequence>
/xsd:complexType>
</xsd:element>
<xsd:attribute name="scope"
type="customdatabinding:ProviderScopeType" default="module"/>
</xsd:sequence>
</xsd:complexType
<xsd:simpleType name="qnameScopeType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="simpleType"/>
<xsd:enumeration value="complexType"/>
<xsd:enumeration value="element"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ProviderScopeType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="server"/>
<xsd:enumeration value="application"/>
<xsd:enumeration value="module"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
|
SDO DataGraph 示例的 CustomBindingProvider.xml
清单 5 是前面我们提到的 SDO DataGraph 脚本的 CustomBindingProvider.xml 文件的示例。在示例中,它在脚本类型 DataGraphType 和 Java 类型 commonj.sdo.DataGraph 间定义了一个映射。实现映射的绑定名称 test.sdo.SDODataGraphBinder。
清单 5. CustomBindingProvider.xml 文件示例
<cdb:provider
xmlns:cdb="http://www.ibm.com/webservices/customdatabinding/2004/06"
xmlns:sdo="commonj.sdo">
<cdb:mapping>
<cdb:xmlQName>sdo:DataGraphType</cdb:xmlQName>
<cdb:javaName>commonj.sdo.DataGraph</cdb:javaName>
<cdb:qnameScope>complexType</cdb:qnameScope>
<cdb:binder>test.sdo.SDODataGraphBinder</cdb:binder>
</cdb:mapping>
</cdb:provider>
|
应用绑定提供者来生成开发构件
定制数据绑定影响如何从 Web服务描述语言 (WSDL) 文件来生成开发构件。与 WebSphere Application Server V6 一起捆绑发售的开发工具 WSDL2Java (参见参考资料)可以使用绑定提供者的 Jar 文件来产生对应的开发构件,如服务端点接口 (SEI),JSR109 映射元数据等等。
清单 6. 引用 SDO DataGraph 脚本的示例 WSDL 文件
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://sdo.test"
xmlns:impl="http://sdo.test"
xmlns:intf="http://sdo.test"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:sdo="commonj.sdo">
<wsdl:types>
<schema elementFormDefault="qualified" targetNamespace="http://sdo.test"
xmlns="http://www.w3.org/2001/XMLSchema" xmlns:sdo="commonj.sdo">
<import namespace="commonj.sdo" schemaLocation="sdo.xsd"/>
</schema>
</wsdl:types>
<wsdl:message name="echoResponse">
<wsdl:part element="sdo:datagraph" name="return"/>
</wsdl:message>
<wsdl:message name="echoRequest">
<wsdl:part element="sdo:datagraph" name="parameter"/>
</wsdl:message>
<wsdl:portType name="EchoService">
<wsdl:operation name="echo">
<wsdl:input message="impl:echoRequest" name="echoRequest"/>
<wsdl:output message="impl:echoResponse" name="echoResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="EchoServiceSoapBinding" type="impl:EchoService">
<wsdlsoap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="echo">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="echoRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="echoResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="EchoServiceService">
<wsdl:port binding="impl:EchoServiceSoapBinding" name="EchoService">
<wsdlsoap:address location="http://<uri>"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
|
没有定制数据绑定,运行 WSDL2Java 命令生成 SEI 如清单 7 所示,其中它的参数类型,按照 JAX-RPC 规范 为 javax.xml.soap.SOAPElement。
清单 7. 参数类型为 javax.xml.soap.SOAPElement 的 SEI
package test.sdo
public interface EchoService extends java.rmi.Remote {
public javax.xml.soap.SOAPElement
echo(javax.xml.soap.SOAPElement parameter)
throws java.rmi.RemoteException;
}
|
假设 SDO DataGraph 脚本的提供者 Jar 文件为 sdobinder.jar。您可以在 WSDL2Java 工具中使用 -classpath 选项来应用定制数据绑定。WSDL2Java 以 /META-INF/services/CustomBindingProvider.xml 中的文件路径来搜索类路径以定位所有的文件,运行 WSDL2Java 命令生成的 SEI,如清单 8 所示,其中的参数类型为期望的 commonj.sdo.Datagraph。
WSDL2Java -role develop-server -container web -classpath sdobinder.jar echo.wsdl
清单 8. 参数类型为 commonj.sdo.Datagraph 的 SEI 。 package test.sdo
public interface EchoService extends java.rmi.Remote {
public commonj.sdo.DataGraph
echo(commonj.sdo.DataGraph parameter)
throws java.rmi.RemoteException;
}
|
自然,提供者 Jar 文件在运行时必须可以访问以实现成功地客户端调用,不管它是基于存根的客户还是动态调用接口 (DII) 客户。对服务也同样如此,提供者 Jar 文件必须在运行时可以访问。
发布定制绑定
在定制绑定被实现且打包后,它们可以与各种应用程序一起发布。本节首先讨论定制数据绑定相关的各种角色,随后列出几个关于如何发布定制数据绑定的通用模式。
定制数据绑定相关的角色
有 4 个角色与定制数据绑定相关,每一个角色各有一套自己的职责。角色定义如下,在一定程度上,是由 J2EE™ 规范 (参见 参考资料)定义的。
-
定制绑定提供者 -- 绑定提供者负责实现需要的定制绑定,在
CustomBindingProvider.xml 文件中声明这些绑定,并将各种绑定类打包到 Jar 文件中供调用。
-
应用程序开发者 -- 应用程序开发者负责应用定制绑定提供者 Jar 文件并生成相应的开发构件。
-
应用程序集成者 -- 应用程序集成者负责根据定制数据绑定来理解应用程序需求并决定是否以及如何将提供者 Jar 文件作为应用程序的一部分打包。
-
应用程序发布者 -- 如果提供者 Jar 文件没有被打包到应用程序中,应用程序发布者负责配置共享库使得应用程序可以获得定制绑定支持。如果应用程序还没有发布,当应用程序被安装的时候,部署者还要负责运行 Web 服务发布工具。
常见使用模式
定制数据绑定可以以多种方式发布来提供除了标准 JAX-RPC 映射之外的灵活性。发布定制数据绑定存在 3 种基本模式:
- 第一种使用模式是在服务器级发布定制绑定,因此,所有运行在服务器上的应用程序都会受到发布的定制数据绑定的影响。如果需要引入一些基本的 XML 类型,且它们又不被标准 JAX-RPC 映射支持的情况下,这种模式非常有用。这种情况通常发生在一些新的 Web 服务规范上,因为它们通常定义一些新的脚本类型。例如 WS-Addressing 规范 (请参阅参考资料)定义了一个 EndpointReferenceType 脚本类型,它就是不被 JAX-RPC 映射规则支持。因为这种模式经常需要扩大服务器类路径,因此它对服务器的运行以及所有安装在服务器上的应用程序具有明显的影响。这一模式通常仅适合 WebSphere Application Server 内部组件。
- 第二种使用模式是为一个或多个应用程序发布定制绑定,因此,只有这些应用被发布的定制绑定影响。当相关的 XML 脚本类型被应用到一组应用程序时,这种模式非常有效。通过应用这种模式,你可以在一组应用程序间共享定制绑定,且在不同组的应用程序间实现隔离。
- 第三种使用模式是为一个应用程序的特定 Web 模块发布定制绑定,因此只有那个 Web 模块受到发布的定制绑定的影响。当定制绑定需要最小粒度时,这种模式非常有效。这种模式不适用于 EJB 模块,因为类加载器对 EJB 模块是自动选择的,即 EJB 模块以及它的引用库是属于整个应用程序的。(参见 参考资料)。
发布任务
本节将给出更多关于如何发布定制绑定的细节,对应与前面定义的 3 种模式。
对于第一种使用模式, 设置声明的绑定提供者的 scope 属性为 server。 如果在服务器和应用程序间存在冲突的话,这种设置保证了声明的绑定具有更高的优先权。把提供者 Jar 文件放在一个合适的位置,使得它可以在服务器运行时被访问。配置服务器的路径来确保提供者 Jar 文件作为服务器类路径的一部分。关于如何配置服务器类路径请参阅参考资料。
对于第二种使用模式,设置声明的绑定提供者的 scope 属性为 application。 如果在应用程序和模块间存在冲突的话,这种设置保证了声明的绑定具有更高的优先权。如果定制绑定被不止一个库使用,将这些引用的库配置为共享库。参阅参考资料来了解如何配置共享库。如果定制绑定仅被一个应用程序使用,发布者可以选择重新打包提供者 Jar 文件,这样就可以避免配置。
对于第三种使用模式,设置声明的绑定提供者的 scope 属性为 module。 这种模式使用定制绑定的唯一方法是与 Web 模块一起重新打包提供者 Jar 文件。例如,将 Jar 文件放入 /WEB-INF/lib 目录。
结束语
本文引入了关于数据绑定的背景和概念信息,解释了为什么定制数据绑定对于处理特定的 XML 脚本类型是必须的,并对在各种用途场景下如何发布定制绑定提供了详细描述。附录描述了如何开发并打包定制绑定。
附录: JAX-RPC 1.1 不支持的脚本类型
JAX-RPC 1.1 不支持的脚本类型如下所示,但并不仅限于以下:
- 带有
mixed=true 的复杂数据类型
- 包含
xsd:choice, xsd:group, xsd:attributeGroup, xsd:anyAttribute 的复杂数据类型
- 被继承的复杂数据类型 (除了 arrayType 的
约束,例如
<complexType name="DerviedType">
<complexContent>
<restriction base="BaseType>
...
</restriction>
</complexContent>
</complexType>
|
-
sequence 具有 maxOccurs > 1 的复杂数据类型,例如
<complexType name="Foo">
<sequence maxOccurs="2">
...
</sequence>
</complexType>
|
-
all 具有 maxOccurs > 1 的复杂数据类型,例如
<complexType name="Foo">
<all maxOccurs="2">
...
</all>
</complexType>
|
- 单一复杂类型中的嵌套内容模型,例如
<complexType name="NestedType">
<sequence>
<element name="elem1" type="string"/>
<element name="elem2">
<complexType>
<sequence>
<element name="elem3" type="string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
|
- 标志符限制 (key、 keyref 和 unique)
- 联合简单数据类型
参考资料
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文。
-
阅读 JAX-RPC 规范
-
阅读 JAXB 规范
- 阅读 SAAJ 规范
-
阅读 SDO 规范
-
阅读 WSDL2Java 命令参考
-
阅读 J2EE 规范
-
获取 WS-Addressing 脚本
-
理解 WebSphere 类加载器
-
学习如何配置 WebSphere Application Server 类路径
-
学习如何配置 WebSphere Application Server 的共享库路径
其它参考资料
关于作者  | 
|  |
Ping Wang 是 IBM WebSphere Web 服务引擎的开发者之一。在此之前,作为 WebSphere Application Server System Management 的一名开发人员,主要关注如何通过 Java Management Extension (JMX)来管理分布式进程。你可以通过 pacific@us.ibm.com 联系 Ping 。 |
对本文的评价
|