Retrieving a MIME-encoded binary attachment through MTOM with ColdFusion 10

Setup:
A Oracle Weblogic (BEA) Web Service returning mime-encoded binary documents (word or pdf) in attachment through MTOM, matching the metadata specified in the request.
A client running on ColdFusion 10, using the automatically generated stub from the WSDL of the Web Service using axis2.

To start, we have ColdFusion generate the stub by invoking the WSDL:

variables.ws=createObject("webservice","http://testserver/CarsDocContentServiceWS/CarsDocContentServiceWSPort?WSDL",{wsversion="2",refreshwsdl="false",timeout=500});

Iomportant: we need to specify wsversion = 2 to force ColdFusion to use axis2. Refreshwdl can be false, we only want the stub to be generated once. Regenerating it each time is time-consuming.
To see what we get back from the Web Service it is always a good idea to dump it:

writeDump(variables.ws);

dump of the webservice and its methods

The method we are looking for is getmanifestationcontent. The first 8 variables are the metadata we need to provide, the last 5 are returned by the Web Service. I create a placeholder for them.


variables.result=StructNew();
variables.result.filenameOut='';
variables.result.errorMessage='';
variables.result.errorCode='';

All set up to invoke the method on the webservice:


variables.response=variables.ws.getmanifestationcontent('MYACC','ST',JavaCast("bigdecimal",5007),JavaCast("bigdecimal",2012),'INIT','EN','INTRA','PDF',JavaCast("bigdecimal",1),variables.result.filenameOut,dhl,variables.result.errorMessage,variables.result.errorCode);

Some of the metadata we passed in had to be casted to the expected datatype. The one oddity in this particular webservice was the ‘dhl’ variable that matches the expected javax.activation.DataHandler data type. Since this is a returned argument, I expected it would be enough to pass just the name of an empty variable and the stub would automatically return a DataHandler object. But the webservice refused to accept any null valued arguments, so I had to build a empty DataHandler object in which even the DataSource had to be specified, even if it would never be used on the Web Service. So I added these 2 lines of code prior to the invocation of the Web Service.


fds=CreateObject("Java", "javax.activation.FileDataSource").init('c:\temp.pdf');
dhl=CreateObject("Java", "javax.activation.DataHandler").init(fds);

Time to look at the response of our request. I would have expected the response to be in the DataHandler variable dhl. But this was not the case. The attachent was in the response of the invocation of the getmanifestation method itself.
So, again, I dumped it to see what I was dealing with.

writeDump(variables.response);

manifestationcontent response

Clearly, the filename was in the get_FileName_out() method:

saveToFileName="c:\"&variables.response.getFileName_out();

Now the only thing left is to get the binary attachment and I saved it locally to the disk. The getFileContent_out() contained the getInputStream() i was looking for. So I could loop through that until the end-of-file and stream it to the local disk:


inputStream=variables.response.getFileContent_out().getInputStream();
outStream=createObject("Java","java.io.ByteArrayOutputStream").init();

byteClass=createObject("Java","java.lang.Byte").TYPE;
byteArray=createObject("Java","java.lang.reflect.Array").newInstance(byteClass, javacast("int", 1024));
length=inputStream.read(byteArray);
offset=0;
while (length GT 0) {
outStream.write(byteArray,offset,length);
length=inputStream.read(byteArray);
}
outStream.close();
inputStream.close();
FileWrite(saveToFileName,outStream.toByteArray());

While dumping the objects returned from the Web Sevice, I noticed that the Oracle WebLogic WebService used the Apache James Mime4J library. Since it was not by default in my list of libs that ColdFusion is using, I had to download it and put it in the cfusion/lib directory. I didn’t need to reference it anywhere in my code, but it would not run without it, specifically throwing an error telling me that ColdFusion could not find a specific class within this library.

Advertisements

3 Responses to “Retrieving a MIME-encoded binary attachment through MTOM with ColdFusion 10”

  1. Brian Kresge (@parkerfly) Says:

    Thank you for posting this. I’ve been dealing for years with an MTOM attached zip file by treating the binary encoding in ColdFusion, and ending up with extra characters at the end. I wonder if this would similarly work in CF8 or CF9? I don’t see anything in here particularly CF10 specific.

  2. Brian Kresge (@parkerfly) Says:

    …other than the wsdl piece, that is.

  3. Streaming a pdf from a streamReader to a browser | Marbie's Weblog Says:

    […] up on my article on ‘retrieving a MIME-encoded binary attachment through MTOM with ColdFusion 10′, it was only logical that I had to send the content i retrieved to the browser. Remember, we […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: