You need to sign in to do that
Don't have an account?
henryCH
Problem loading image file via HTTP Request
Hi,
I'd like to use HTTP classes to load an image from the web then save it as an Attachment and finally send it attached to an email. At first glance everything seems to work fine. But the picture I receive is obviously a corrupt file. Any ideas what's wrong with my code:
public class EmailTestCtr { public Integer totalFileSize {get; set;} public Email__c mail {get; set;} public String contentType {get; set;} public String response {get; set;} public EmailTestCtr(){ totalFileSize = 0; } public void loadFile(){ String url = ''; Http h = new Http(); HTTPRequest req = new HttpRequest(); req.setEndpoint('http://www.clienthouse.com/images/f106e78f34/CH_location_web1.jpg'); req.setMethod('GET'); req.setCompressed(false); HTTPResponse resp = h.send(req); this.contentType = resp.getHeader('Content-Type'); this.response = resp.getHeader('Content-Length'); System.debug(resp.getBody()); String body = resp.getBody(); Attachment a = new Attachment(); try { if(this.mail == null){ mail = new Email__c( Name = 'test' ); insert mail; } a.Body = Blob.valueOf(body); a.Name = 'Name'; a.ParentId = mail.Id; a.ContentType = this.contentType; insert a; } catch(DMLException e){ ApexPages.addMessages(e); } this.totalFileSize += [select BodyLength from Attachment where Id = :a.Id].BodyLength; } public void sendEmail(){ Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); String[] toAddresses = new String[] {'h.hess@clienthouse.com'}; email.setToAddresses(toAddresses); email.setSubject(this.mail.Name); email.setPlainTextBody('Text goes here.'); List<Messaging.EmailFileAttachment> files = new List<Messaging.EmailFileAttachment>(); for(Attachment file : [select Name, Body, ContentType from Attachment where ParentId = :this.mail.Id]){ System.debug('------------>FILE' + file); Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment(); efa.setBody(file.Body); efa.setContentType(file.ContentType); efa.setFileName(file.Name + '.jpg'); files.add(efa); } email.setFileAttachments(files); Messaging.sendEmail(new Messaging.SingleEmailMessage[] { email }); } }
Thanks and best regards,
Henry
I found a link that knows how to do this...
http://stackoverflow.com/questions/9632570/upload-image-from-android-client-to-salesforce-custom-object
In the recent Spring release (v24) ... you can now work with binary data (blobs in apex) directly in the http request or response. Here's an example of making a HTTP GET request for an image PNG file, and saving it to the document object in salesforce.
Here is the code in that link:
HttpRequest r = new HttpRequest();
r.setMethod('GET');
r.setEndpoint('http://www.pocketsoap.com/osx/soqlx/soqlxicon.png');
Http http = new Http();
HttpResponse res = http.send(r);
blob image = res.getBodyAsBlob();
Document d = new Document();
d.name = 'logo.png';
d.body = image;
d.folderId = UserInfo.getUserId();
insert d;
system.debug(d.id);
All Answers
I don't think it's your code. I think because HTTPResponse stores body as a string, you'll need to be able to access the image originally as Base64Encoded, so it won't get corrupted in the process. Then you can decode into a blob.
Hi Josh,
Thanks for your reponse. Does that really mean that Apex cannot handle binary data via HTTP because everything is converted into unencoded strings?? Sounds unbelievable to me. Is there nobody out there who tried this before??
Thanks and best regards,
Henry
Some final remarks.
This is a critical limitation for us so I tried to find a workaround for this problem. Browsing the docs I stumbled over the PageReference object's getContent() method. Compared to HTTPResponse.getBody() this method returns a Blob, so I tested something like:
And received a well handled java.net.ConnectException! At this point I got a little frustrated.
What' s really annoying me is actually not the fact that this is not working. I could understand if Apex had the following two limitations:
:: HTTP classes only support text based content like XML or HTML : alright!
:: PageReference.getContent() only supports content from the salesforce.com domain : acceptable!
But all of this is not documented (!!) and this makes it a real pain.
Best regards,
Henry
Here's an older post with the same outcome:
http://boards.developerforce.com/t5/Apex-Code-Development/How-to-return-binary-data-from-an-External-web-service-callout/td-p/154724
What's the specific use case, Henry? Anything on the other end which could convert it to base64? How much control do you have over the server hosting the image?
I found a link that knows how to do this...
http://stackoverflow.com/questions/9632570/upload-image-from-android-client-to-salesforce-custom-object
In the recent Spring release (v24) ... you can now work with binary data (blobs in apex) directly in the http request or response. Here's an example of making a HTTP GET request for an image PNG file, and saving it to the document object in salesforce.
Here is the code in that link:
HttpRequest r = new HttpRequest();
r.setMethod('GET');
r.setEndpoint('http://www.pocketsoap.com/osx/soqlx/soqlxicon.png');
Http http = new Http();
HttpResponse res = http.send(r);
blob image = res.getBodyAsBlob();
Document d = new Document();
d.name = 'logo.png';
d.body = image;
d.folderId = UserInfo.getUserId();
insert d;
system.debug(d.id);