function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
azrkhnazrkhn 

apex (https request) post method callout with multiple blobs in form data

Hello,

I am calling a remote webservice api from apex.

This is how the request should look like as per the api documentation.
URL: 'https://example.com/merge'
Method: 'POST'
Content-Type: 'multipart/form-data'
Parameters: {file_1: 'BINARY_PDF_DATA', file_2: 'BINARY_PDF_DATA', file_3: ..., user: 'auth_username', password: 'auth_password'}
Result: 'BINARY_PDF_DATA'

Below is the code that I have accomplished so far, but the problem is that this code returns a 500 - Internal Server Error when I run it.

Here is my code:
string username = 'auth_username';
string password = 'auth_password';
boolean isTest = true;
								

 Http h = new Http();
 HttpRequest req = new HttpRequest();
 req.setEndpoint('https://example.com/merge');
 req.setMethod('POST');
 req.setHeader('Content-Type','multipart/form-data; boundary=----RandomString');
                                                                
 string body = '------RandomString\r\n';
 body += 'Content-Disposition: form-data;';
body += 'name=\"user\"\r\n\r\n'+username+'\r\n';
                                
body += '------RandomString\r\n';
body += 'Content-Disposition: form-data;';
body += 'name=\"password\"\r\n\r\n'+password+'\r\n';
                                
body += '------RandomString\r\n';
body += 'Content-Disposition: form-data;';
body += 'name=\"test\"\r\n\r\n'+isTest+'\r\n';
                                
 // build the blob form data
                                
 integer k = 1;
for(blob blb : blobs){
                                    
body += '------RandomString\r\n';
body += 'Content-Disposition: form-data; name="file_'+k+'"; filename="file_'+k+'.pdf"\r\n\r\n';
body+= EncodingUtil.base64Encode(blb) +'\r\n';

k++;

}
                                
body += '------RandomString--';
req.setBody(body);
                                
 // Send the request, and return a response
HttpResponse res = h.send(req);

system.debug('Response is: ');
system.debug(res);

So I could not figure out what is wrong as apparently I have meet the webservice callout requirments as mentioned in the api documentation.

Any help in this regard will be appreciated.
azrkhnazrkhn
I could'nt do this with Apex but did this using Ajax call in a Visualforce page.

The related Apex controller builds the blobs, converts them to a list of base64 strings and then we use them directly in the Javascript code below.

Here is the Ajax code that I used in the Visualforce page to do the webservice call and get the binary data back.
 
const b64toBlob = (b64Data, contentType='', sliceSize=512) => {
            const byteCharacters = atob(b64Data);
            const byteArrays = [];
            
            for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
            const slice = byteCharacters.slice(offset, offset + sliceSize);
            
            const byteNumbers = new Array(slice.length);
            for (let i = 0; i < slice.length; i++) {
            byteNumbers[i] = slice.charCodeAt(i);
        }
        
        const byteArray = new Uint8Array(byteNumbers);
        byteArrays.push(byteArray);
        }
        
        const blob = new Blob(byteArrays, {type: contentType});
        return blob;
        }

       // we can use apex variables directly in javascript
        
        var uploadFormData = new FormData();
        uploadFormData.append("user","{!username}");
        uploadFormData.append("password","{!password}");
        uploadFormData.append("test","{!isTest}");
        
        var i = 1;
        <apex:repeat value="{!base64Strings}" var="b">
            var blob1 = b64toBlob("{!b}", "application/pdf");
        uploadFormData.append("file_"+i, blob1);
        i++;
        </apex:repeat>
        
        $.ajax({
            async: true,
            url : "{!url}",
            type : "POST",
            data : uploadFormData,
            cache : false,
            contentType : false,
            processData : false,
            xhr:function(){// telling that the response should be a blob
                var xhr = new XMLHttpRequest();
                xhr.responseType= 'blob'
                return xhr;
            },
            error: function(xhr, status, error) {
                console.log(xhr.responseText);
            },
            success : function(response, status, xhr) {
                //alert("Success!");
                //console.log(response); // response is a blob
                
               // cannot send blob directly to Apex controller so convert it to base64 string and send
                var reader = new FileReader();
                reader.readAsDataURL(response); 
                reader.onloadend = function() {
                    
                    base64data = reader.result;
                    
                    // send back the base64 string to controller using Visualforce Remoting
                    // and decode it back to blob

                

                }
            }
        });