用于 JAX-RPC 应用程序的 Java 语言、WSDL 和 XML 之间的映射
Java™ API for XML-based Remote Procedure Call (JAX-RPC) 应用程序的数据作为可扩展标记语言 (XML) 传递。JAX-RPC 应用程序使用映射来描述 Java 语言与可扩展标记语言 (XML) 技术之间的数据转换,这些技术包括受应用程序服务器支持的 XML 模式、Web Service 描述语言 (WSDL) 和 SOAP。
对于 JAX-RPC 应用程序,Java 语言与 XML 之间的大多数映射是由 JAX-RPC 规范指定的。也支持一些可选的映射或 JAX-RPC 中未指定的映射。请复审 JAX-RPC 规范,以获取完整的 API 列表。 有关受支持的标准和规范的完整列表,请参阅 Web Service 规范和 API 文档。
符号约定
名称空间前缀 | 名称空间 |
---|---|
xsd | http://www.w3.org/2001/XMLSchema |
xsi | http://www.w3.org/2001/XMLSchema-instance |
soapenc | http://schemas.xmlsoap.org/soap/encoding/ |
wsdl | http://schemas.xmlsoap.org/wsdl/ |
wsdlsoap | http://schemas.xmlsoap.org/wsdl/soap/ |
ns | 用户定义的名称空间 |
apache | http://xml.apache.org/xml-soap |
wasws | http://websphere.ibm.com/webservices/ |
详细映射信息
以下部分标识支持的映射,包括:Java 到 WSDL 的映射
此部分概述了 Java 到 WSDL 的映射规则。Java 到 WSDL 的映射规则由 Java2WSDL 命令用于自下至上式的处理。 在自底向上式处理中,现有 Java 服务实现用于创建定义 Web Service 的 WSDL 文件。生成的 WSDL 文件可能由于以下原因需要其他手动编辑:- 不是所有 Java 类和构造都有到 WSDL 文件的映射。例如,不遵循 Java Bean 规范规则的 Java 类可能不映射到 WSDL 构造。
- 某些 Java 类和构造有多个到 WSDL 文件的映射。例如,java.lang.String 类可映射到 xsd:string 或 soapenc:string 构造。Java2WSDL 命令选择这些映射中的一个,但如果需要不同的映射,那么您必须编辑 WSDL 文件。
- 存在多个生成 WSDL 构造的方法。例如,您可在具有 type 或 element 属性的 wsdl:message 中生成 wsdl:part。Java2WSDL 命令根据 -style 和 -use 选项设置进行已知选择。
- WSDL 文件描述 SOAP 消息中发送的实例数据元素。如果您要修改在消息中使用的名称或格式,必须编辑 WSDL 文件。例如,Java2WSDL 命令将 Java Bean 属性映射为 XML 元素。在某些情况下,您可能要更改 WSDL 文件以将 Java Bean 属性映射为 XML 属性。
- 如果期望头或附件支持,那么需要编辑 WSDL 文件。
- 如果期望多重部件 WSDL 文件(使用 wsdl:import 构造),那么需要编辑 WSDL 文件。
- 包到名称空间的映射:
JAX-RPC 规范未指示 Java 包名称至 XML 名称空间的缺省映射。JAX-RPC 规范明确指定每个 Java 包都必须映射到单个 XML 名称空间。同样地,每个 XML 名称空间都必须映射到单个 Java 包。提供缺省映射算法,它通过将 Java 包名称反向和添加 http:// 前缀来构造名称空间。 例如,名为 com.ibm.webservice 的包会映射到 XML 名称空间 http://webservice.ibm.com。
可以使用 WSDL2Java 和 Java2WSDL 命令的 -NStoPkg 及 -PkgtoNS 选项来覆盖 XML 名称空间和 Java 包名之间的缺省映射。
- 标识映射:
Java 标识直接映射到 WSDL 和 XML 标识。
Java Bean 属性名映射到 XML 标识。例如,带有 getInfo 和 setInfo 方法的 Java Bean 映射到 XML 构造并带有名称 info。
如果可用,服务端点接口方法参数名直接映射到 WSDL 和 XML 标识。要了解更多,请参阅 WSDL2Java 命令 -implClass 选项的信息。
- WSDL 构造摘要:
表 2. Java 到 WSDL 或 XML 构造的映射. 描述从 Java 构造到相关 WSDL 和 XML 构造的映射。 Java 构造 WSDL 和 XML 构造 服务端点接口 wsdl:portType 方法 wsdl:operation 参数 wsdl:input、wsdl:message、wsdl:part Return wsdl:output、wsdl:message、wsdl:part 抛出 wsdl:fault、wsdl:message、wsdl:part 基本类型 xsd 和 soapenc 简单类型 Java Bean xsd:complexType Java Bean 属性 xsd:complexType 的嵌套 xsd:elements 数组 JAX-RPC 定义的 xsd:complexType 或带 maxOccurs="unbounded" 属性的 xsd:element 用户定义的异常 xsd:complexType - 绑定和服务构造
生成符合生成的 wsdl:portType 的 wsdl:binding。生成 wsdl:service,它包含引用生成的 wsdl:binding 的端口。绑定和服务的名称由 Java2WSDL 命令控制。
- Style 和 use使用 -style 和 -use 选项生成不同类型的 WSDL 文件。四个支持的组合是:
- -style DOCUMENT -use LITERAL
- -style RPC -use LITERAL
- -style DOCUMENT -use LITERAL -wrapped false
- -style RPC -use ENCODED
- DOCUMENT LITERAL:
Java2WSDL 命令生成遵循 Web Services 互操作性组织 (WS-I) 规范的 document-literal WSDL 文件。wsdl:binding 是用嵌入式 style="document" 和 use="literal" 属性生成的。为每个服务端点接口方法生成 xsd:element 以描述请求消息。为每个服务端点接口方法生成类似的 xsd:element 以描述响应消息。
- RPC LITERAL:
Java2WSDL 命令生成遵循 WS-I 的 rpc-literal WSDL 文件。wsdl:binding 是用嵌入式 style="rpc" 和 use="literal" 属性生成的。wsdl:message 构造是为每个服务端点接口方法的输入和输出生成的。此方法的参数由 wsdl:message 构造中的部分元素描述。
- 不合并的 DOCUMENT LITERAL:
Java2WSDL 命令生成遵循 JAX-RPC 规范的 document-literal WSDL 文件。此 WSDL 文件不遵循 .NET。DOCUMENT LITERAL 和不合并的 DOCUMENT LITERAL 之间的主要区别是使用 wsdl:message 构造定义请求和响应消息。
- RPC ENCODED:
Java2WSDL 命令生成遵循 JAX-RPC 规范的 rpc-encoded WSDL 文件。此 WSDL 文件不遵循 WS-I 规范。wsdl:binding 是用嵌入式 style="rpc" 和 use="encoded" 属性生成的。某些 soapenc 映射用于表示类型和数组。
许多 Java 类型直接映射到标准 XML 类型。例如,java.lang.String 映射到 xsd:string。这些映射在 JAX-RPC 规范中有所描述。
在 wsdl:types 部分中生成无法直接映射到标准 XML 类型的 Java 类型。与 Java Bean 模式匹配的 Java 类映射到 xsd:complexType。请复审 JAX-RPC 规范,以了解所有映射规则的描述。以下示例说明样本库和派生的 Java 类的映射。Java: public abstract class Base { public Base() {} public int a; // mapped private int b; // mapped via setter/getter private int c; // not mapped private int[] d; // mapped via indexed setter/getter public int getB() { return b;} // map property b public void setB(int b) {this.b = b;} public int[] getD() { return d;} // map indexed property d public void setD(int[] d) {this.d = d;} public int getD(int index) { return d[index];} public void setB(int index, int value) {this.d[index] = value;} public void someMethod() {...} // not mapped } public class Derived extends Base { public int x; // mapped private int y; // not mapped } Mapped to: <xsd:complexType name="Base" abstract="true"> <xsd:sequence> <xsd:element name="a" type="xsd:int"/> <xsd:element name="b" type="xsd:int"/> <xsd:element name="d" minOccurs="0" maxOccurs="unbounded" type="xsd:int"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="Derived"> <xsd:complexContent> <xsd:extension base="ns:Base"> <xsd:sequence> <xsd:element name="x" type="xsd:int"/> </xsd:sequence> </xsd:extension> </xsd:complexContent> </xsd:complexType>
- 不支持的类:
如果无法将类映射到 XML 类型,那么 Java2WSDL 命令发出消息并在 WSDL 文件中生成 xsd:anyType 参考。在这些情况下,可以修改 Web Service 实现以使用符合 JAX-RPC 的类。
WSDL 到 Java 的映射
WSDL2Java 命令使用 WSDL 文件中描述的信息生成 Java 类。
- 名称空间到包的映射:
JAX-RPC 不指定 XML 名称空间到 Java 包名称的映射。JAX-RPC 明确指定每个 Java 包都映射到单个 XML 名称空间。同样地,每个 XML 名称空间都必须映射到单个 Java 包。缺省映射算法省略任何来自 XML 名称空间的协议并将名称反转过来。例如,XML 名称空间 http://websphere.ibm.com 成为名为 com.ibm.websphere 的 Java 包。
XML 名称空间到 Java 包的缺省映射忽略上下文根。如果两个名称空间直到第一个斜杠是相同的,那么它们映射到相同的 Java 包。例如,XML 名称空间 http://websphere.ibm.com/foo 和 http://websphere.ibm.com/bar 映射到 com.ibm.websphere Java 包。可以使用 WSDL2Java 和 Java2WSDL 命令的 -NStoPkg 及 -PkgtoNS 选项来覆盖 XML 名称空间和 Java 包名之间的缺省映射。
XML 名称比 Java 标识更丰富。它们可以包含在 Java 标识中不允许的字符。请参阅 JAX-RPC 规范的附录 20,以了解将 XML 名称映射到 Java 标识的规则。
- Java 构造摘要:下表总结了 XML 到 Java 构造。请参阅 JAX-RPC 规范,以了解对这些映射的描述。
表 3. WSDL 或 XML 构造到 Java 的映射. 描述 XML 和 Java 构造之间的映射。 WSDL 和 XML 构造 Java 构造 xsd:complexType Java Bean 类、Java 异常类或 Java 数组 嵌套的 xsd:element/xsd:attribute Java Bean 属性 xsd:simpleType(枚举) JAX-RPC 枚举类 wsdl:message 方法参数特征符通常由 wsdl:message 确定。 服务端点接口方法特征符 wsdl:portType 服务端点接口 wsdl:operation 服务端点接口方法 wsdl:binding 存根 wsdl:service 服务接口 wsdl:port 服务接口中的端口 accessor 方法 - 映射标准 XML 类型:
- JAX-RPC 简单 XML 类型映射:
许多 XML 类型直接映射到 Java 类型。请参阅 JAX-RPC 规范,以了解对这些映射的描述。
WSDL2Java 命令生成在 wsdl:types 部分中定义的 XML 模式构造的 Java 类型。XML 模式语言比 JAX-RPC 规范中定义的必需或可选子集更广泛。WSDL2Java 命令支持必需的映射和大多数可选映射,以及 JAX-RPC 规范中不包括的某些 XML 模式映射。WSDL2Java 命令忽略它不支持的某些构造。例如,此命令不支持缺省属性。如果用缺省属性定义 xsd:element,那么忽略缺省属性。在某些情况下,此命令将不支持的构造映射到 Java 接口 javax.xml.soap.SOAPElement。
标准 Java Bean 映射在 JAX-RPC 规范的 4.2.3 节中定义。 xsd:complexType 定义此类型。xsd:sequence 或 xsd:all 组中的嵌套 xsd:elements 映射到 Java Bean 属性。例如:XML: <xsd:complexType name="Sample"> <xsd:sequence> <xsd:element name="a" type="xsd:string"/> <xsd:element name="b" maxOccurs="unbounded" type="xsd:string"/> </xsd:sequence> </xsd:complexType> Java: public class Sample { // .. public Sample() {} // Bean Property a public String getA() {...} public void setA(String value) {...} // Indexed Bean Property b public String[] getB() {...} public String getB(int index) {...} public void setB(String[] values) {...} public void setB(int index, String value) {...} }
- wsdl:portType 构造的映射:
wsdl:portType 构造映射到服务端点接口。wsdl:portType 构造的名称映射到服务端点接口的类名。
- wsdl:operation 构造的映射:wsdl:portType 中的 wsdl:operation 构造映射到服务端点接口的方法。wsdl:operation 的名称映射到方法的名称。wsdl:operation 包含使用 message 属性引用请求和响应 wsdl:message 构造的 wsdl:input 和 wsdl:output 元素。 wsdl:operation 可以包含 wsdl:fault 元素,此元素引用描述故障的 wsdl:message。这些故障被映射到扩展异常 java.lang.Exception 的 Java 类,如 JAX-RPC 规范的 4.3.6 节中所述。
- 合并的 document literal 格式的影响:如果 WSDL 文件使用合并的 document literal 格式,那么从包装器 xsd:element 映射方法参数。合并的 document literal 和 literal 格式由 WSDL2Java 命令自动检测。必须满足以下条件:
- WSDL 文件在它的 wsdl:binding 构造中必须有 style="document"。
- wsdl:binding 中操作的输入和输出构造必须包含其中包含 use="literal" 的 soap:body 元素。
- wsdl:operation 输入构造引用的 wsdl:message 必须有一个部分。
- 此部分必须使用 element 属性引用 xsd:element。
- 所引用的 xsd:element 或 wrapper 元素必须与 wsdl:operation 同名。
- wrapper 元素不能包含任何 xsd:attribute。
WSDL: <xsd:element name="myMethod"> <xsd:complexType> <xsd:sequence> <xsd:element name="param1" type="xsd:string"/> <xsd:element name="param2" type="xsd:int"/> </xsd:sequence> </xsd:complexType> </xsd:element> ... <wsdl:message name="response"/> <part name="parameters" element="ns:myMethod"/> </wsdl:message name="response"/> <wsdl:message name="response"/> ... <wsdl:operation name="myMethod"> <input name="input" message="request"/> <output name="output" message="response"/> </wsdl:operation> Java: void myMethod(String param1, int param2) ...
- 参数映射:
如果未检测到合并的 document 和 literal 格式,那么参数映射遵循 JAX-RPC 规范的 4.3.4 节中设置的常规 JAX-RPC 映射规则。
每个参数由从输入和输出元素引用的 wsdl:message 部分定义。- 请求 wsdl:message 中的 wsdl:part 映射到输入参数。
- 响应 wsdl:message 中的 wsdl:part 映射到返回值。如果响应消息中存在多个 wsdl:part,那么它们会映射到输出参数。
- 如 JAX-RPC 规范的 4.3.5 节中讨论的,为每个输出参数生成的 Holder 类。
- 同时是请求和响应 wsdl:message 的 wsdl:part 会映射到输入输出参数。
- 如 JAX-RPC 规范的 4.3.5 节中讨论的,为每个输入输出参数生成的 Holder 类。
- wsdl:operation parameterOrder 属性定义这些参数的顺序。
XML: <wsdl:message name="request"> <part name="param1" type="xsd:string"/> <part name="param2" type="xsd:int"/> </wsdl:message name="response"/> <wsdl:message name="response"/> ... <wsdl:operation name="myMethod" parameterOrder="param1, param2"> <input name="input" message="request"/> <output name="output" message="response"/> </wsdl:operation> Java: void myMethod(String param1, int param2) ...
- 合并的 document literal 格式的影响:
- wsdl:binding 的映射:WSDL2Java 命令使用 wsdl:binding 信息生成特定于实现的客户机端存根。WebSphere® Application Server 使用服务器端上的 wsdl:binding 信息来正确地对请求进行反序列化、调用 Web Service 以及对响应进行序列化。wsdl:binding 中的信息不影响服务端点接口的生成,除了使用合并的 document 和 literal 格式或有 MIME 附件之外。
- MIME 附件:对于遵循 WSDL 1.1 的 WSDL 文件,在绑定中定义为 MIME 附件的操作消息的一部分成为附件类型的参数,而无论所声明的部分是什么。例如:
JAX-RPC 规范需要对以下 MIME 类型的支持:XML: <wsdl:types> <schema ...> <complexType name="ArrayOfBinary"> <restriction base="soapenc:Array"> <attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:binary[]"/> </restriction> </complexType> </schema> </wsdl:types> <wsdl:message name="request"> <part name="param1" type="ns:ArrayOfBinary"/> <wsdl:message name="response"/> <wsdl:message name="response"/> ... <wsdl:operation name="myMethod"> <input name="input" message="request"/> <output name="output" message="response"/> </wsdl:operation> ... <binding ... <wsdl:operation name="myMethod"> <input> <mime:multipartRelated> <mime:part> <mime:content part="param1" type="image/jpeg"/> </mime:part> </mime:multipartRelated> </input> ... </wsdl:operation> Java: void myMethod(java.awt.Image param1) ...
表 4. MIME 类型和 Java 类型的映射. 描述 MIME 类型和 Java 类型之间的映射。 MIME 类型 Java 类型 image/gif java.awt.Image image/jpeg java.awt.Image text/plain java.lang.String multipart/* javax.mail.internet.MimeMultipart text/xml javax.xml.transform.Source application/xml javax.xml.transform.Source
- MIME 附件:
- wsdl:service 的映射:
wsdl:service 元素映射到生成的服务接口。生成的服务接口包含访问 wsdl:service 元素中每个端口的方法。生成的服务接口在 JAX-RPC 规范的 4.3.9、4.3.10 和 4.3.11 节中讨论。
另外,wsdl:service 元素映射到特定于 实现的 ServiceLocator 类,它是生成的服务接口的实现。
- JAX-RPC 简单 XML 类型映射:
请阅读 Java API for XML-based Remote Procedure Call (JAX-RPC) 应用程序的 WSDL2Java 命令行工具的内容,以了解有关此工具的更多信息。
WSDL 和 SOAP 消息之间的映射
WSDL 文件定义通过网络连接传输的 SOAP 消息的格式。WSDL2Java 命令和 WebSphere Application Server 运行时使用 WSDL 文件中的信息确保正确序列化和反序列化 SOAP 消息。
如果 wsdl:binding 元素表明使用 RPC 格式发送消息,那么 SOAP 消息包含一个定义此操作的元素。如果 wsdl:binding 元素表明使用文档格式发送消息,那么 SOAP 消息不包含操作元素。
如果 wsdl:part 元素是使用 type 属性定义的 ,那么在消息中使用此部分的名称和类型。 如果 wsdl:part 元素是使用 element 属性定义的,那么在消息中使用此元素的名称和类型。当 use="encoded" 时,JAX-RPC 规范不支持 element 属性。
DOCUMENT/LITERAL
WSDL:
<xsd:element name="c" type="xsd:int"/>
<xsd:element name="method">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="a" type="xsd:string"/>
<xsd:element ref="ns:c"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
...
<wsdl:message name="request">
<part name="parameters" element="ns:method"/>
</wsdl:message>
...
<wsdl:operation name="method">
<input message="request"/>
...
Message:
<soap:body>
<ns:method>
<a>ABC</a>
<c>123</a>
<ns:method>
</soap:body>
RPC/ENCODED
WSDL:
<xsd:element name="c" type="xsd:int"/>
...
<wsdl:message name="request">
<part name="a" type="xsd:string"/>
<part name="b" element="ns:c"/>
</wsdl:message>
...
<wsdl:operation name="method">
<input message="request"/>
...
Message:
<soap:body>
<ns:method>
<a xsi:type="xsd:string">ABC</a>
<element attribute is not permitted in rpc/encoded mode>
</ns:method>
</soap:body>
DOCUMENT/LITERAL not wrapped
WSDL:
<xsd:element name="c" type="xsd:int"/>
...
<wsdl:message name="request">
<part name="a" type="xsd:string"/>
<part name="b" element="ns:c"/>
</wsdl:message>
...
<wsdl:operation name="method">
<input message="request"/>
...
Message:
<soap:body>
<a>ABC</a>
<c>123</a>
</soap:body>