I am trying to POST a PDF attachment to a Restful web service (not under my control). My issue is that I need to get put the raw bytes of the PDF into the Body of the request and whenever I call Blob.toString(), I get stopped by a UTF-8 String error:
BLOB is not a valid UTF-8 String
I’ve tried to put the base64 encoded bytes into the body instead, but the web service doesn’t seem to support it.
public Dom.Document uploadFile(Attachment attachment){ // Body String boundary = '------------' + String.valueOf(DateTime.now().getTime()); string body = ''; body+= boundary; body+= '\r\n'; body+= 'Content-Disposition: form-data; name=\"file\";'; body+= 'filename=\"' + attachment.name + '\"'; body+= '\r\n'; //body+= 'Content-Transfer-Encoding: base64\r\n'; body+= 'Content-Type: application/octet-stream'; body+= '\r\n\r\n'; body+= attachment.body.toString(); body+= '\r\n' + boundary + '\r\n'; HttpRequest req = new HttpRequest(); req.setEndpoint('http://connect.sandbox.mimeo.com/2012/02/storageservice/test'); // Set headers req.setHeader('Authorization', authorizationData); req.setHeader('Content-Type', 'multipart/form-data; boundary=' + boundary); req.setHeader('Content-Length',String.valueof(body.length())); req.setMethod('POST'); req.setTimeOut(120000); req.setBody(body); Http http = new Http(); HttpResponse res = http.send(req); Dom.Document retDocument = res.getBodyDocument(); return retDocument; }
Is there anyway to get the blob as a non utf8 string? I thinking about trying to write my own base64 decode that returns a string but I don’t even know if this is even possible in apex.
Update
Just to give some more info here is the request I’m trying to replicate in Apex. This was made using Mimeo’s C# library and was successful. Mimeo provides no documentation for this service that I can find:
POST http://connect.sandbox.mimeo.com/2012/02/storageservice/test HTTP/1.1 Authorization: Basic [removed] Content-Type: multipart/form-data; boundary=----------8d0de7b15063540 Host: connect.sandbox.mimeo.com Content-Length: 493827 Expect: 100-continue Connection: Keep-Alive ------------8d0de7b15063540 Content-Disposition: form-data; name="file"; filename="printme.pdf" Content-Type: application/octet-stream [BINARY PDF] ------------8d0de7b15063540
Answer
This is how I send attachments. All credits(& explanation) http://enreeco.blogspot.in/2013/01/salesforce-apex-post-mutipartform-data.html
@Future(callout=true)
public static void uploadFile(Blob file_body, String file_name, String reqEndPoint){
String boundary = '----------------------------741e90d31eff';
String header = '--'+boundary+'\r\nContent-Disposition: form-data; name="file"; filename="'+file_name+'"\r\nContent-Type: application/octet-stream'; // added '\r's removed ';' see Tim Smith's comment
String footer = '\r\n--'+boundary+'--';
String headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\r\n\r\n'));
while(headerEncoded.endsWith('='))
{
header+=' ';
headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\r\n\r\n'));
}
String bodyEncoded = EncodingUtil.base64Encode(file_body);
String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer));
Blob bodyBlob = null;
String last4Bytes = bodyEncoded.substring(bodyEncoded.length()-4,bodyEncoded.length());
if(last4Bytes.endsWith('='))
{
Blob decoded4Bytes = EncodingUtil.base64Decode(last4Bytes);
HttpRequest tmp = new HttpRequest();
tmp.setBodyAsBlob(decoded4Bytes);
String last4BytesFooter = tmp.getBody()+footer;
bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded.substring(0,bodyEncoded.length()-4)+EncodingUtil.base64Encode(Blob.valueOf(last4BytesFooter)));
}
else
{
bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded);
}
HttpRequest req = new HttpRequest();
req.setHeader('Content-Type','multipart/form-data; boundary='+boundary);
req.setMethod('POST');
req.setEndpoint(reqEndPoint);
req.setBodyAsBlob(bodyBlob);
req.setTimeout(120000);
Http http = new Http();
HTTPResponse res = http.send(req);
}
Attribution
Source : Link , Question Author : NSjonas , Answer Author : shmuel friedman