Has anyone worked on multi-part SOAP responses with attachments within apex?
Scenario:
We're trying to retrieve a pdf document from an external site using webservice requests then show the pdf file within Salesforce. Problem is, it's returning a multi-part response with attachment on it in which salesforce doesn't support at the moment(https://help.salesforce.com/apex/HTViewSolution?urlname=System-CalloutException-Web-service-callout-failed-Failed-to-get-next-element&language=en_US).
VF Page
<apex:page controller="GetDocumentvRetrieve" sidebar="false" showHeader="false" contentType="application/pdf">
<script>
window.location.href = "data:application/pdf;charset=utf-8;base64,{!data}";
</script>
</apex:page>
Class
public class GetDocumentvRetrieve {
public string data {get; set;}
public GetDocumentvRetrieve () {
data = retrieveDocument('########');
}
public String retrieveDocument(String docID) {
String strBody ='<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">';
strBody +=' <soap:Header>';
strBody +=' <wsse:Security xmlns:wsse=" " xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1">';
strBody +=' <wsse:UsernameToken wsu:Id="UsernameToken-277573">';
strBody +=' <wsse:Username>#######</wsse:Username>';
strBody +=' <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">############</wsse:Password>';
strBody +=' </wsse:UsernameToken>';
strBody +=' </wsse:Security>';
strBody +=' </soap:Header>';
strBody +=' <soap:Body>';
strBody += ' <getDocument xmlns="http://www.datamail.co.nz/vretrieve/webservices/">';
strBody += ' <id>###########</id>';
strBody += ' </getDocument>';
strBody +=' </soap:Body>';
strBody +='</soap:Envelope>';
HttpRequest request = new HttpRequest();
request.setEndpoint('https://vr2.datamail.co.nz/vretrieve/webservices/viewdocumentservice');
request.setMethod('POST');
request.setHeader('Content-Type', 'application/pdf');
request.setHeader('SOAPAction', '"" ');
request.setTimeout(100000);
request.setBody(strBody);
Http http = new Http();
system.debug('request===>' + request.getBody());
HttpResponse response = http.send(request);
system.debug('res =======>'+response );
integer statusCode = response.getStatusCode();
String statusMessage = response.getStatus();
String message = response.getBody();
system.debug('statusCode =======>'+statusCode);
system.debug('statusMessage =======>'+statusMessage);
system.debug('message =======>'+message);
Blob contentData = response.getBodyAsBlob();
return EncodingUtil.base64Encode(contentData);
}
}
Here's the raw response http://pastebin.com/9mEVV0dg
Already checked the following posts, but it doesn't involve parsing through multi-part SOAP responses:
Display PDF with Visualforce
Any workaround on how can I extract the attachment from the SOAP response?
Best Answer
I know it's way too late but i thought I would post our solution incase anyone else has the same issue.
Coincidentally we were having the exact same problem with datamail.co.nz/vretrieve haha.
Basically the problem is that you can't use response.getBody() as it will convert the whole response to a string and corrupt the binary attachment, and you can't just use response.getBodyAsBlob() because the text component of the response will also corrupt the file.
There should be a header in the response called 'Content-Type', which also should have a parameter called 'boundary', this is used to separate the different parts of the response.
What we did was pull out the boundary value and convert it to hex, then convert the whole response to hex and use the boundary to split out the attachment, then convert the separated file back to a blob.
For us, there was still some header information in the section containing the file however that didn't seem to affect the file when it was converted back to a pdf so we left it there, others may need to split that out too.
here's our code,