I faced issues when tried to send binary data from Salesforce to external web services. To start with, I tried to send binary data from Salesforce to itself.
I am trying to read binary data from valid WordX ContentVersion file and upload it again to Salesforce as a Document.
When I use method Blob b = res0.getBodyAsBlob();
and then concatenate it with other form data through b.toString()
method, I receive an error
{
"column": "1",
"compileProblem": "",
"compiled": "true",
"exceptionMessage": "System.StringException: BLOB is not a valid UTF-8 string",
"exceptionStackTrace": "Class.BlobNotValidUTF8.<init>: line 43, column 1\nAnonymousBlock: line 2, column 1\nAnonymousBlock: line 2, column 1",
"line": "43",
"success": "false"
}
public with sharing class BlobNotValidUTF8 {
public BlobNotValidUTF8() {
ContentVersion cv = [SELECT Title, FileExtension, Description FROM ContentVersion WHERE Id = '0681x000001p65tAAA' ];
Http h = new Http();
HttpRequest r0 = new HttpRequest();
r0.setMethod('GET');
r0.setEndpoint('https://velocity-computing-3399-dev-ed.cs100.my.salesforce.com/services/data/v47.0/sobjects/ContentVersion/0681x000001p65tAAA/VersionData');
r0.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
HTTPResponse res0 = h.send(r0);
System.debug(LoggingLevel.ERROR, '@@@ : status' + res0.getStatus());
System.debug(LoggingLevel.ERROR, '@@@ : status' + res0.getStatusCode());
System.debug(LoggingLevel.ERROR, '@@@ : keys' + res0.getHeaderKeys());
for (String key: res0.getHeaderKeys()) {
System.debug(LoggingLevel.ERROR, '@@@ : key: ' + key + ' header = ' + res0.getHeader(key));
}
System.debug(LoggingLevel.ERROR, '@@@ : ' + res0.getBody());
Blob b = res0.getBodyAsBlob();
HttpRequest r = new HttpRequest();
r.setMethod('POST');
r.setEndpoint('https://velocity-computing-3399-dev-ed.cs100.my.salesforce.com/services/data/v50.0/sobjects/Document/');
r.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
r.setHeader('Content-Type', 'multipart/form-data; charset="UTF-8"; boundary=\"boundary_string\"');
r.setBody('--boundary_string\r\n'+
'Content-Disposition: form-data; name="entity_document";\r\n'+
'Content-Type: application/json\r\n'+
'\r\n'+
'{ \r\n'+
' "Description" : "' + cv.Description + '",\r\n'+
' "Keywords" : "",\r\n'+
' "FolderId" : "' + UserInfo.getUserId() + '",\r\n'+
' "Name" : "' + cv.Title + '",\r\n'+
' "Type" : "' + cv.FileExtension + '"\r\n'+
'}\r\n'+
'\r\n'+
'--boundary_string\r\n'+
'Content-Type: application/word\r\n'+
'Content-Transfer-Encoding: binary\r\n'+
'Content-Disposition: form-data; name="Body"; filename="' + cv.Title + '.' + cv.FileExtension + '"\r\n'+
'\r\n' +
//res0.getBody()+
b.toString()+
'\r\n'+
'--boundary_string--\r\n'
);
HTTPResponse res = h.send(r);
System.debug(LoggingLevel.ERROR, '@@@ : status' + res.getStatus());
System.debug(LoggingLevel.ERROR, '@@@ : status' + res.getStatusCode());
System.debug(LoggingLevel.ERROR, '@@@ : keys' + res.getHeaderKeys());
for (String key: res.getHeaderKeys()) {
System.debug(LoggingLevel.ERROR, '@@@ : key: ' + key + ' header = ' + res.getHeader(key));
}
System.debug(LoggingLevel.ERROR, '@@@ : ' + res.getBody());
insert new Log__c(Name = r.getEndpoint().left(51) + ' request ' + DateTime.now(), Line__c = r.getBody().left(131072));
insert new Log__c(Name = r.getEndpoint().left(51) + ' response ' + DateTime.now(), Line__c = res.getBody().left(131072));
insert new Log__c(Name = r.getEndpoint().left(51) + ' request ' + DateTime.now(), Line__c = r0.getBody().left(131072));
insert new Log__c(Name = r.getEndpoint().left(51) + ' response ' + DateTime.now(), Line__c = res0.getBody().left(131072));
}
}
When I use method res0.getBody(), it doesn't file, but the uploaded file is unreadable and Word application says that it is corrupted
public with sharing class BlobNotValidUTF8 {
public BlobNotValidUTF8() {
ContentVersion cv = [SELECT Title, FileExtension, Description FROM ContentVersion WHERE Id = '0681x000001p65tAAA' ];
Http h = new Http();
HttpRequest r0 = new HttpRequest();
r0.setMethod('GET');
r0.setEndpoint('https://velocity-computing-3399-dev-ed.cs100.my.salesforce.com/services/data/v47.0/sobjects/ContentVersion/0681x000001p65tAAA/VersionData');
r0.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
HTTPResponse res0 = h.send(r0);
System.debug(LoggingLevel.ERROR, '@@@ : status' + res0.getStatus());
System.debug(LoggingLevel.ERROR, '@@@ : status' + res0.getStatusCode());
System.debug(LoggingLevel.ERROR, '@@@ : keys' + res0.getHeaderKeys());
for (String key: res0.getHeaderKeys()) {
System.debug(LoggingLevel.ERROR, '@@@ : key: ' + key + ' header = ' + res0.getHeader(key));
}
System.debug(LoggingLevel.ERROR, '@@@ : ' + res0.getBody());
HttpRequest r = new HttpRequest();
r.setMethod('POST');
r.setEndpoint('https://velocity-computing-3399-dev-ed.cs100.my.salesforce.com/services/data/v50.0/sobjects/Document/');
r.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
r.setHeader('Content-Type', 'multipart/form-data; charset="UTF-8"; boundary=\"boundary_string\"');
r.setBody('--boundary_string\r\n'+
'Content-Disposition: form-data; name="entity_document";\r\n'+
'Content-Type: application/json\r\n'+
'\r\n'+
'{ \r\n'+
' "Description" : "' + cv.Description + '",\r\n'+
' "Keywords" : "",\r\n'+
' "FolderId" : "' + UserInfo.getUserId() + '",\r\n'+
' "Name" : "' + cv.Title + '",\r\n'+
' "Type" : "' + cv.FileExtension + '"\r\n'+
'}\r\n'+
'\r\n'+
'--boundary_string\r\n'+
'Content-Type: application/word\r\n'+
'Content-Transfer-Encoding: binary\r\n'+
'Content-Disposition: form-data; name="Body"; filename="' + cv.Title + '.' + cv.FileExtension + '"\r\n'+
'\r\n' +
res0.getBody()+
'\r\n'+
'--boundary_string--\r\n'
);
HTTPResponse res = h.send(r);
System.debug(LoggingLevel.ERROR, '@@@ : status' + res.getStatus());
System.debug(LoggingLevel.ERROR, '@@@ : status' + res.getStatusCode());
System.debug(LoggingLevel.ERROR, '@@@ : keys' + res.getHeaderKeys());
for (String key: res.getHeaderKeys()) {
System.debug(LoggingLevel.ERROR, '@@@ : key: ' + key + ' header = ' + res.getHeader(key));
}
System.debug(LoggingLevel.ERROR, '@@@ : ' + res.getBody());
insert new Log__c(Name = r.getEndpoint().left(51) + ' request ' + DateTime.now(), Line__c = r.getBody().left(131072));
insert new Log__c(Name = r.getEndpoint().left(51) + ' response ' + DateTime.now(), Line__c = res.getBody().left(131072));
insert new Log__c(Name = r.getEndpoint().left(51) + ' request ' + DateTime.now(), Line__c = r0.getBody().left(131072));
insert new Log__c(Name = r.getEndpoint().left(51) + ' response ' + DateTime.now(), Line__c = res0.getBody().left(131072));
}
}
How can send binary data in a way it will not become corrupted?