首页 > 解决方案 > 如何在使用 salesforce apex 时将较大的文件(大于 12 MB)上传到 aws s3 存储桶

问题描述

我需要一些帮助才能从 Salesforce 顶点服务器端将大文件上传到 s3 存储桶。

我需要能够拆分 blob 并使用 Http PUT 操作将其上传到 aws s3 存储桶。我可以一次上传最多 12 MB 的文件,因为这是 Apex 中的 PUT 请求正文大小限制。所以我需要能够使用多部分操作上传。我注意到s3允许部分上传并返回一个uploadId。想知道是否有人以前在 salesforce apex 代码中这样做过。这将不胜感激。

在此先感谢 Parbati Bose。

这是代码

public with sharing class AWSS3Service {

    private static Http http;

    @auraEnabled
    public static  void uploadToAWSS3( String fileToUpload , String filenm , String doctype){


        fileToUpload = EncodingUtil.urlDecode(fileToUpload, 'UTF-8');

        filenm = EncodingUtil.urlEncode(filenm , 'UTF-8'); // encode the filename in case there are special characters in the name 
        String filename = 'Storage' + '/' + filenm ;
        String attachmentBody = fileToUpload;

        String formattedDateString = DateTime.now().formatGMT('EEE, dd MMM yyyy HH:mm:ss z');




        // s3 bucket!
        String key = '**********' ;
        String secret = '********' ;
        String bucketname = 'testbucket' ;
        String region = 's3-us-west-2' ;



        String host = region + '.' + 'amazonaws.com' ; //aws server base url




    try{
        HttpRequest req = new HttpRequest();
        http = new Http() ;
        req.setMethod('PUT');
        req.setEndpoint('https://' + bucketname + '.' + host +  '/' +  filename );
        req.setHeader('Host', bucketname + '.' + host);

        req.setHeader('Content-Encoding', 'UTF-8');
        req.setHeader('Content-Type' , doctype);
        req.setHeader('Connection', 'keep-alive');
        req.setHeader('Date', formattedDateString);
        req.setHeader('ACL', 'public-read-write');


        String stringToSign = 'PUT\n\n' +
                doctype + '\n' +
                formattedDateString + '\n' +
                '/' + bucketname +  '/' + filename;


        Blob mac = Crypto.generateMac('HMACSHA1', blob.valueof(stringToSign),blob.valueof(secret));
        String signed = EncodingUtil.base64Encode(mac);
        String authHeader = 'AWS' + ' ' + key + ':' + signed;
        req.setHeader('Authorization',authHeader);

        req.setBodyAsBlob(EncodingUtil.base64Decode(fileToUpload)) ;



        HttpResponse response = http.send(req);

        Log.debug('response from aws s3 is ' + response.getStatusCode() + ' and ' + response.getBody());


    }catch(Exception e){
            Log.debug('error in connecting to s3 ' + e.getMessage());
            throw e ;
        }
    }

标签: amazon-web-servicesamazon-s3file-uploadsalesforce

解决方案


在过去的几天里,我一直在研究同样的问题,不幸的是,由于 APEX 堆大小限制为 12MB,您将从 Salesforce 外部更好地执行此传输。 https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm

虽然可以使用 multipart 写入文件,但您似乎无法将它们从数据库中取出以将它们拆分成可以发送的块。在 stackexchange 上提出了类似的问题 - https://salesforce.stackexchange.com/questions/264015/how-to-retrieve-file-content-from-content-document-in-chunks-using-soql


推荐阅读