Salesforce Apex类调用AWS API时遭遇文件格式无效错误求助
问题分析与解决思路
核心问题原因
你遇到的错误本质是请求体格式不符合AWS API的预期,具体问题出在这几点:
- 你将
VersionData(Blob类型)转成Base64字符串后直接放入multipart请求体,AWS会把这当成普通文本内容,而非原始文件的二进制数据,自然无法识别为PDF格式。 - 硬编码
Content-Type: application/octet-stream没有匹配实际文件的MIME类型,AWS可能依赖这个头部辅助识别文件格式。 - 手动拼接字符串形式的multipart请求容易出现换行符、边界符的格式错误,导致AWS解析文件内容失败。
解决步骤
1. 直接传输二进制数据,避免Base64编码
不要将Blob转成Base64字符串,而是直接将二进制内容嵌入multipart请求体。Apex的HttpRequest支持setBodyAsBlob方法,可以正确处理二进制数据。
2. 设置正确的文件MIME类型
根据ContentVersion的FileType字段动态设置Content-Type,比如PDF对应application/pdf,JPG对应image/jpeg等。
3. 正确构造multipart/form-data请求体
使用Blob拼接的方式构造请求体,确保边界符、换行符和内容格式完全符合HTTP规范。
修改后的代码示例
public class InvoiceUpload { // ... (原有代码省略) public static void uploadFileToAWS(Id contentVersionId) { try { // 查询ContentVersion,确保获取到VersionData和FileType ContentVersion cv = [SELECT Id, Title, VersionData, FileType FROM ContentVersion WHERE Id = :contentVersionId LIMIT 1]; // 定义multipart边界 String boundary = 'Boundary-' + String.valueOf(System.currentTimeMillis()); String contentTypeHeader = 'multipart/form-data; boundary=' + boundary; // 构造请求体的各个部分:边界、头部、文件内容、结束边界 Blob bodyBlob = Blob.valueOf('--' + boundary + '\r\n'); bodyBlob = bodyBlob + Blob.valueOf('Content-Disposition: form-data; name="document"; filename="' + cv.Title + '"\r\n'); // 根据FileType设置正确的Content-Type String fileContentType = getContentTypeByFileType(cv.FileType); bodyBlob = bodyBlob + Blob.valueOf('Content-Type: ' + fileContentType + '\r\n\r\n'); // 添加原始文件二进制数据 bodyBlob = bodyBlob + cv.VersionData; bodyBlob = bodyBlob + Blob.valueOf('\r\n--' + boundary + '--'); // 创建HTTP请求 HttpRequest req = new HttpRequest(); req.setEndpoint('你的AWS API端点'); req.setMethod('POST'); req.setHeader('Content-Type', contentTypeHeader); // 添加授权令牌等其他头部 // req.setHeader('Authorization', 'Bearer ' + 你的令牌); req.setBodyAsBlob(bodyBlob); // 发送请求并处理响应 Http http = new Http(); HTTPResponse res = http.send(req); System.debug('AWS响应状态码: ' + res.getStatusCode()); System.debug('AWS响应内容: ' + res.getBody()); } catch (Exception ex) { System.debug('异常信息: ' + ex.getMessage()); } } // 辅助方法:根据Salesforce的FileType返回对应的MIME类型 private static String getContentTypeByFileType(String fileType) { Map<String, String> typeMap = new Map<String, String>{ 'PDF' => 'application/pdf', 'JPG' => 'image/jpeg', 'JPEG' => 'image/jpeg', 'PNG' => 'image/png', 'JFIF' => 'image/jfif', 'BMP' => 'image/bmp', 'TIFF' => 'image/tiff' }; return typeMap.getOrDefault(fileType.toUpperCase(), 'application/octet-stream'); } }
额外验证点
- 确认
ContentVersion的FileType字段值正确(比如PDF文件对应的FileType是'PDF')。 - 检查AWS API的multipart/form-data参数名是否确实是
document(代码中name="document"要和API要求一致)。 - 发送请求前可以打印请求体的Blob大小,确认和原始文件大小一致,避免数据丢失。
内容的提问来源于stack exchange,提问作者barucco
相关产品推荐
相关产品推荐

