In WebSphere Enterprise Service Bus (WESB) 6.2.0.1, the most common usage of SOAP with attachments, known as unreferenced attachment. It is a type of SOAP Message with Attachments and is called unreferenced because in the SOAP envelope you can not locate any references to the attachments. The code in listing 1 below is a sample of an unreferenced SOAP attachment. For additional detail, please refer to http://www.w3.org/TR/SOAP-attachments.
Listing 1. Sample code of unreferenced SOAP attachment
MIME-Version: 1.0
Content-Type: Multipart/Related; boundary=MIME_boundary; type=text/xml;
start="<http://claiming-it.com/claim061400a.xml>"
Content-Description: This is the optional message description.
--MIME_boundary
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: 8bit
Content-ID: <http://claiming-it.com/claim061400a.xml>
Content-Location: http://claiming-it.com/claim061400a.xml
<?xml version='1.0' ?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
..
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
--MIME_boundary
Content-Type: image/tiff
Content-Transfer-Encoding: binary
Content-ID: unreferencedPart
...binary image...
--MIME_boundary--
|
WESB 6.2.0.1 supports binary attachments and can access unreferenced attachment data and headers via Service Message Object (SMO) programming model through JAX-WS based Web service binding. In this article, we will focus on the following features in WESB 6.2.0.1:
- Attach an attachment in SMO
- Detach an attachment in SMO
- Converting a binary element in a SOAP body to an attachment
In the following example, we define an interface named AttachmentIntf with 2 operations to demonstrate the features. In the flow of operation1 we plan to show how to attach and detach attachments in SMO while in operation2 flow we will show the transformation from a binary element to an attachment. We need 3 mediation modules to implement it. In AttachmentClient, we do more work on the initialization. In other words, we prepare the binary data for the attachment or the binary element. In the mean time, attaching an attachment in SMO will also be shown in operation1. We create another mediation module named AttachmentMediation in which we implement operation1 to detach the attachment sent from AttachmentClient. And in operation2 we will convert the binary element in BO to an attachment with XSLTransformation. If you want to examine the SOAP attachments sent from AttachmentMediation, you can see in TCP/IP monitor or check the detailed SMO in a third mediation module, for example, AttachmentServer. Notes that we use JAX-WS based web services binding between all the mediation modules.
Figure 1. Description of the modules
First, we provide the data structure for SOAP attachment in SMO. See the schema listed below. In SMO, we add a field named attachments with type AttachmentType. In AttachmentType the field contentID records the contentId of the attachment. contentType is for the type of the attachment while data is of type base64Binary and contains the content of attachments.
Code 2. Type definition for SMO and AttachmentType
<complexType name="ServiceMessageObject">
<sequence>
..
<!-- List of attachments -->
<element name="attachments" type="smo:AttachmentType"
minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="AttachmentType">
<sequence>
<element name="contentID" type="anyURI"/>
<element name="contentType" type="token"/>
<choice>
<element name="data" type="base64Binary"/>
..
</choice>
</sequence>
</complexType>
|
If in your SMO there is some data in attachments, the JAX-WS based web services binding will create attachments in the outbound SOAP message. So for the various ways of attaching or detaching the SOAP attachments below, the essential idea is to manipulate SMO/attachments.
As describe above, an interface with 2 operations is required. Any type of parameter is permitted. In this example, the interface is AttachmentIntf and is located in a library named AttachmentLib. Once the interface is determined, we begin to build the mediation module. We will use an XML file named a.xml as our attachment. Store the a.xml file in <Profile_Root>/temp/attFiles. This file can be easily found in the directory with the API System.getProperty("user.dir"). It is highly recommended that you download AttachmentPI.zip first to see the detailed information about this example. Complete the following steps to attach the SOAP message in SMO.
- Create a mediation module named AttachmentClient with adding AttachmentLib in its dependencies;
- Implement operation1 in AttachmentClient and add a CustomMediation;
- Add the codes below to the CustomMediation;
Code 3. Sample code of attaching attachment
commonj.sdo.DataObject __smo = (commonj.sdo.DataObject)smo;
try
{// print BO to log
ServiceManager sm = new ServiceManager();
BOFactory bof = (BOFactory) sm.locateService("com/ibm/websphere/bo/BOFactory");
//add attachment to SMO
DataObject atBOSMO = bof.create
("http://www.ibm.com/websphere/sibx/smo/v6.0.1","AttachmentType");
String sep = System.getProperty("file.separator");
String inputDir = System.getProperty("user.dir") + sep + "temp" + sep + "attFiles";
System.out.println("inputDir: " + inputDir);
File file = new File(inputDir + sep + "a.xml");
FileInputStream stream = new FileInputStream(file);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int n;
while((n=stream.read(buffer))!=-1){
out.write(buffer, 0, n);
}
stream.close();
byte[] bytes = out.toByteArray();
out.close();
atBOSMO.setString("contentID", "contentid1");
atBOSMO.setString("contentType", "application/octet-stream");
atBOSMO.setBytes("data", bytes);
java.util.List attListSMO = (java.util.List)__smo.getList("attachments");
attListSMO.add(atBOSMO);
com.ibm.websphere.bo.BOXMLSerializer srv = (com.ibm.websphere.bo.BOXMLSerializer)
new com.ibm.websphere.sca.ServiceManager().
locateService("com/ibm/websphere/bo/BOXMLSerializer");
commonj.sdo.Type type = __smo.getType();
srv.writeDataObject(__smo, type.getURI(), type.getName(), java.lang.System.out);
System.out.println("over");
}
catch(Exception ex){
ex.printStackTrace();
}
out.fire(__smo);
|
- Some comments regarding the codes:
- Create a data object of type AttachmentType to contain the contentID, contentType and data of SOAP attachment. Codes around atBOSMO are doing so.
- Insert in the content of the attachment from a disk file. We have to convert it to a byte array to satisfy the base64binary type from the definition of AttachmentType. Codes around file and stream are doing this.
- Then we need to set values to atBOSMO/contentID and atBOSMO/contentType as your wish and set the byte array to atBOSMO/data. Do not forget to add atBOSMO to smo/attachments.
- Codes around srv.writeDataObject are for printing the SMO.
- When the SMO is sent out through a JAX-WS based web services binding, we can see an attachment is successfully added to the SOAP request.
This is one of the methods to attach attachments to SOAP message. In the next section, we will see another method to convert an element in BO to the attachment.
This is similar to 2.3. The only difference is to get data from smo/attachments and remember to remove the attachment off from SMO if you do not want to propagate it any more. See below:
Figure 2. Detach request flow
In CustomMediation1, we use codes similar to code 3. Some key difference are:
Code 4. Sample code detach attachment
java.util.List attListSMO = (java.util.List)__smo.getList("attachments");
DataObject atSMO = (DataObject)attListSMO.get(0);
byte[] bytes = atSMO.getBytes("data");
|
Now we have the content of the attachment stored in a byte array. You can use it as your wish, such as save it to disk. If you do not want to propagate the attachment, you can either remove it from SMO or use an XSLT like below. Just link the fields that you need and leave smo/attachments unlinked.
Figure 3. XSLT in detach flow
Some of our customers used to store the attachment content in an element of binary type in BO which is a workaround in the previous version with no SOAP attachments support. Now they can simply use an XSLT to convert the BO element to a real SOAP attachment. There is a limitation that XSLT can only be used to an element of base64Binary type.
- We will use similar code in 2.3 to set attachment content to a BO element. The key modification is that we will store the byte array in body/operation2/input1/field3.
- Then in operation2 flow in AttachmentMediation, add an XSLTransformation and a CustomMediation in. See below.
Figure 4. Convert request flow
- In XSLTransformation1, link the fields as your wish. Move field3 to smo/attachments/data, notes that in Cardinality you should set 1 for the first attachment. Also remember to assign value to smo/attachments/contentID and smo/attachments/contentType. Also set cardinality to 1.
Figure 5. XSLT in convert flow
- In CustomMediation1 we just print out the whole SMO for checking.
- You can add another mediation module to receive the SOAP request sent from AttachmentMediation. In this article, AttachmentServer does this work.
Notes that you can use BOMap instead of XSLTransformation. This time the BO element type can be either base64Binary or HexBinary.
In this part, we will provide 2 types of SOAP attachment message.
- SMO message:
Code 5. SMO message
<?xml version="1.0" encoding="UTF-8"?>
<p:ServiceMessageObject xsi:type="p:ServiceMessageObject"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:intf="wsdl.http://AttachmentLib/AttachmentIntf"
xmlns:intf_1="http://AttachmentLib/AttachmentIntf"
xmlns:p="http://www.ibm.com/websphere/sibx/smo/v6.0.1">
<context/>
<headers>
<SMOHeader>
<MessageUUID>2F03EE7F-0121-4000-E000-0D4409BA754D</MessageUUID>
<Version>
<Version>6</Version>
<Release>2</Release>
<Modification>0</Modification>
</Version>
<MessageType>Request</MessageType>
</SMOHeader>
</headers>
<body xsi:type="intf:operation1RequestMsg">
<intf_1:operation1>
<input1>
<field1>field1</field1>
<field2>field2</field2>
</input1>
</intf_1:operation1>
</body>
<attachments>
<contentID>contentid1</contentID>
<contentType>application/octet-stream</contentType>
<data>
PHNvYXBlbnY6RW52ZWxvcGUgeG1sbnM6c29hcGVudj0iaHR0cDovL3NjaGVtYXMueG1sc29hc
C5vcmcvc29hcC9lbnZlbG9wZS8iIHhtbG5zOnNvYXBlbmM9Imh0dHA6Ly9zY2hlbWFzLnhtbH
NvYXAub3JnL3NvYXAvZW5jb2RpbmcvIiB4bWxuczp4c2Q9Imh0dHA6Ly93d3cudzMub3JnLzI
wMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2No
ZW1hLWluc3RhbmNlIj48c29hcGVudjpIZWFkZXIvPjxzb2FwZW52OkJvZHk+PGluOmhhbmRsZ
VJlc3VsdCB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3
RhbmNlIiB4bWxuczpibz0iaHR0cDovL2JvLmludGVyZmFjZXMud2VzYi52Z29wLmJtY2MuY29
tIiB4bWxuczppbj0iaHR0cDovL2ludGVyZmFjZXMud2VzYi52Z29wLmJtY2MuY29tIj48aW46
aGFuZGxlUmVzdWx0UmVxIHhzaTp0eXBlPSJibzpIYW5kbGVPcmRlclJlc3VsdFJlcSI+PGJvO
mhlYWRlciB4c2k6dHlwZT0iYm86SGVhZGVyIj48Ym86c2VuZF9BZGRyZXNzIHhzaTp0eXBlPS
JibzpBZGRyZXNzSW5mbyI+PGJvOnByb3ZUeXBlPnByb3ZUeXBlMzwvYm86cHJvdlR5cGU+PGJ
vOnBsYXRUeXBlPnBsYXRUeXBlMzwvYm86cGxhdFR5cGU+PC9ibzpzZW5kX0FkZHJlc3M+PGJv
Om1zZ05hbWU+bXNnTmFtZTwvYm86bXNnTmFtZT48Ym86dHJhbnNhY3Rpb25JZD4xMjM0NTY3O
Dk8L2JvOnRyYW5zYWN0aW9uSWQ+PGJvOnZlcnNpb24+MS4wPC9ibzp2ZXJzaW9uPjxibzpkZX
N0X0FkZHJlc3MgeHNpOnR5cGU9ImJvOkFkZHJlc3NJbmZvIj48Ym86cHJvdlR5cGU+cHJvdlR
5cGUxPC9ibzpwcm92VHlwZT48Ym86cGxhdFR5cGU+cGxhdFR5cGUxPC9ibzpwbGF0VHlwZT48
L2JvOmRlc3RfQWRkcmVzcz48Ym86b3JpZ2luYWxfQWRkcmVzcyB4c2k6dHlwZT0iYm86QWRkc
mVzc0luZm8iPjxibzpwcm92VHlwZT5wcm92VHlwZTI8L2JvOnByb3ZUeXBlPjxibzpwbGF0VH
lwZT5wbGF0VHlwZTI8L2JvOnBsYXRUeXBlPjwvYm86b3JpZ2luYWxfQWRkcmVzcz48Ym86dGl
tZVN0YW1wPjIwMDkxMDEwMTAxMDEwPC9ibzp0aW1lU3RhbXA+PC9ibzpoZWFkZXI+PC9pbjpo
YW5kbGVSZXN1bHRSZXE+PC9pbjpoYW5kbGVSZXN1bHQ+PC9zb2FwZW52OkJvZHk+PC9zb2FwZ
W52OkVudmVsb3BlPg==
</data>
</attachments>
</p:ServiceMessageObject>
|
- HTTP message:
Code 6. HTTP message
--MIMEBoundaryurn_uuid_9FA6F5EF9F94B61B781242035161879
content-type: text/xml; charset=UTF-8
content-transfer-encoding: 8bit
content-id: <0.urn:uuid:9FA6F5EF9F94B61B781242035161880@apache.org>
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
</soapenv:Header>
<soapenv:Body>
<intf:operation1 xmlns:intf="http://AttachmentLib/AttachmentIntf">
<input1>
<field1>field1</field1>
<field2>field2</field2>
</input1>
</intf:operation1>
</soapenv:Body>
</soapenv:Envelope>
--MIMEBoundaryurn_uuid_9FA6F5EF9F94B61B781242035161879
content-type: application/octet-stream
content-transfer-encoding: binary
content-id: <contentid1>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http
://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema
-instance"><soapenv:Header/><soapenv:Body><in:handleResult xmlns:xsi="htt
p://www.w3.org/2001/XMLSchema-instance" xmlns:bo="http://bo.interfaces.we
sb.vgop.bmcc.com" xmlns:in="http://interfaces.wesb.vgop.bmcc.com"><in:han
dleResultReq xsi:type="bo:HandleOrderResultReq"><bo:header xsi:type="bo:H
eader"><bo:send_Address xsi:type="bo:AddressInfo"><bo:provType>provType3<
/bo:provType><bo:platType>platType3</bo:platType></bo:send_Address><bo:ms
gName>msgName</bo:msgName><bo:transactionId>123456789</bo:transactionId><
bo:version>1.0</bo:version><bo:dest_Address xsi:type="bo:AddressInfo"><bo
:provType>provType1</bo:provType><bo:platType>platType1</bo:platType></bo
:dest_Address><bo:original_Address xsi:type="bo:AddressInfo"><bo:provType
>provType2</bo:provType><bo:platType>platType2</bo:platType></bo:original
_Address><bo:timeStamp>20091010101010</bo:timeStamp></bo:header></in:hand
leResultReq></in:handleResult></soapenv:Body></soapenv:Envelope>
--MIMEBoundaryurn_uuid_9FA6F5EF9F94B61B781242035161879--
|
Note that the SOAP message string in the second part of HTTP message is the attachment content, not the actual SOAP message.
In the Downloads section below, the AttachmentPI.zip file is the demo for all readers as well as 3 mediation modules. Export the files into the EAR files and install the files. The a.xml file is the SOAP attachments file demonstrated in this article. This XML file needs to be inserted in <Profile_Root>/temp/attFiles and is recommended that you create another folder <Profile_Root>/temp/output.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample codes for this article | AttachmentPI.zip | 53KB | HTTP |
| XML file used in this article | a.xml | 2KB | HTTP |
Information about download methods
- Participate in the discussion forum.
-
"SOAP Messages with Attachments"
defines a binding for a SOAP 1.1 message to be carried within a MIME multipart/related message
-
"WS-I Attachments Profile 1.0" defines the WS-I Attachments Profile 1.0






