此策略将 XML 业务文档表示为 SOAP 消息的附件。使用附件表示的 SOAP 消息 (SwA) 定义了如何使用 MIME Multipart/Related 包发送 XML 消息包含的二进制数据和其他附件。因此,SOAP 消息实际上可以包含一个或多个使用 MIME 编码的附件,通常称为复合消息。以附件而不是以 SOAP 消息正文的形式发送信息,其效率很高,因为 SOAP 消息正文越小,处理的速度越快,并且因为消息只包含了对数据的引用而不是数据本身,因而会减少将数据映射到 Java 对象的转换时间。
JAX-RPC 使用 JavaBeans[TM] 激活框架处理 SOAP 附件。解除将此消息配置为 Java 时,JAX-RPC 运行环境可以使用两种映射技术。
DataHandlers
和 DataContentHandlers
执行相反的操作。javax.activation.DataHandler
,反之亦然。 简单地说,这意味着如果服务端点中的方法使用表 1 中的标准数据类型,则运行环境会将该类型映射到 SOAP 消息的 MIME 附件中。使用
javax.activation.DataHandler
时,可以使用 DataHandler
中的 getContent()
提取附件内容。如果安装的 DataContentHandler
无法识别内容类型,则它会返回包含原始字节的 java.io.InputStream
对象。
MIME |
类型 |
image/gif |
java.awt.Image |
image/jpeg |
java.awt.Image |
text/plain |
java.lang.String |
multipart/* |
javax.mail.internet.MimeMultipart |
text/xml or application/xml |
javax.xml.transform.Source |
附件所具有的一个问题是在 WSDL 中没有标准的附件规范。此外,供应商之间就使用 SOAP 信封外部的 MIME 包问题未达成一致。WS-I Attachment Profile 1.0 在一定程度上解决了这一问题,它目前定义了附件处理的互操作性要求,并且完全受 J2EE 1.4 SDK(以及 JWSDP 1.4)的支持。从 WSDL 使用 MIME 绑定开始,可以生成可互操作的、符合 WS-I 的、基于附件的 Web 服务。WS-I Attachment Profile 1.0 还定义了一个新类型 "swaRef" 用来引用附件类型,可以使用该类型处理未在 WSDL 中定义的附件。
以下示例描述了一个服务,该服务能够接收作为附件发送给它的 XML 文档。代码示例 1 中的 WSDL 片段显示了 MIME 绑定。
<types>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsi="http://ws-i.org/profiles/basic/1.1/xsd"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="urn:AttachmentPurchaseOrderService">
<import
namespace="http://ws-i.org/profiles/basic/1.1/xsd"
schemaLocation="WS-ISwA.xsd"/>
<element name="statusmessage"
type="wsi:swaRef"/>
<element name="InvalidPOException"
type="string"/>
</schema>
</types>
...
<message
name="AttachmentPurchaseOrderServiceSEI_submitPO">
<part
name="attachment_1" type="xsd:hexBinary"/>
</message>
<message
name="AttachmentPurchaseOrderServiceSEI_submitPOResponse">
<part name="response"
element="ns1:statusmessage"/>
</message>
<message name="InvalidPOException">
<part
name="InvalidPOException" element="ns1:InvalidPOException"/>
</message>
...
<portType
name="AttachmentPurchaseOrderServiceSEI">
<operation name="submitPO">
<input
message="tns:AttachmentPurchaseOrderServiceSEI_submitPO"/>
<output
message="tns:AttachmentPurchaseOrderServiceSEI_submitPOResponse"/>
<fault name="InvalidPOException"
message="tns:InvalidPOException"/>
</operation>
</portType>
<binding
name="AttachmentPurchaseOrderServiceSEIBinding"
type="tns:AttachmentPurchaseOrderServiceSEI">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="submitPO">
<input>
<mime:multipartRelated>
<mime:part>
<soap:body
use="literal"/>
</mime:part>
<mime:part>
<mime:content part="attachment_1" type="text/xml"/>
</mime:part>
</mime:multipartRelated>
</input>
<output>
<mime:multipartRelated>
<mime:part>
<soap:body
parts="response" use="literal"/>
</mime:part>
</mime:multipartRelated>
</output>
<fault name="InvalidPOException">
<soap:fault name="InvalidPOException"
use="literal"/>
</fault>
</operation>
</binding>
public interface
AttachmentPurchaseOrderServiceSEI extends Remote {
public URI submitPO(Source attachment_1) throws
InvalidPOException,
RemoteException;
}
代码示例 2:服务端点接口
使用附件策略的一些弊端是会损害互操作性。并不是所有的工具包都支持 Attachment Profile 1.0。Attachment Profile 1.0 不是 WS-I Basic Profile 1.0 的一部分,但是它将包含在 Basic Profile 的未来版本中。实际上,目前还无法为 .NET 平台提供 MIME 附件支持。因此,如果设计需要由 C# 客户端使用的 Web 服务,则目前使用附件传递 XML 文档不是一个很好的选择。