通过 Apex 在 REST API 中发送文件
Sending Files in REST API via Apex
我正在与接受在其系统中上传文件的供应商之一进行整合。这样做时,他们要求文件以 multipart/form-data 格式发送,格式如下 !!
我尝试使用 Base64 字符串将其配置为多部分表单数据,但仍然无法正常工作!
-H "accept: application/json"
-H "x-api-key: API_KEY"
-H "x-api-token: API_TOKEN"
-H "Content-Type: multipart/form-data"
-F "file=@b4b35527-522d-4228-a266-bdaa80e28a8b.jpg;type=image/jpeg"
salesforce apex 标注不支持您正在查找的内容。
它仍在 salesforce Idea Exchange 中,这里是 link 相同的。
https://trailblazer.salesforce.com/ideaView?id=08730000000Kr80AAC
您可以为其投票,但目前 multipart/form-data header 不受支持。
如果您有任何问题,请告诉我。
Salesforce 确实支持 multipart/form-data,但它不支持将图像作为 Blob 发送。
根据我的要求,我需要将图像/PDF/附件作为表单数据发送。我使用了稍微修改过的 http://www.fishofprey.com/2017/04/steps-required-to-support-posting.html
我得到了另一种 blob 方法,可以将图像和附件作为 blob 包含在内。目前我还没有为视频和其他文档添加编解码器,但很快我会添加这些,因为 API 确实支持那个。
在此处查找修改后的 HttpFormBuilder 版本,将图像和其他附件作为 blob 包含在内。我们只需要添加适当的编解码器。
public class HttpFormBuilder_Custom {
private final static string Boundary = '1ff13444ed8140c7a32fc4e6451aa76d';
public static string GetContentType() {
return 'multipart/form-data; charset="UTF-8"; boundary="' + Boundary + '"';
}
private static string SafelyPad(
string value,
string valueCrLf64,
string lineBreaks) {
string valueCrLf = '';
blob valueCrLfBlob = null;
while (valueCrLf64.endsWith('=')) {
value += ' ';
valueCrLf = value + lineBreaks;
valueCrLfBlob = blob.valueOf(valueCrLf);
valueCrLf64 = EncodingUtil.base64Encode(valueCrLfBlob);
}
return valueCrLf64;
}
public static string WriteBoundary() {
string value = '--' + Boundary + '\r\n';
blob valueBlob = blob.valueOf(value);
return EncodingUtil.base64Encode(valueBlob);
}
public static string WriteBoundary(
EndingType ending) {
string value = '';
if (ending == EndingType.Cr) {
value += '\n';
} else if (ending == EndingType.None) {
value += '\r\n';
}
value += '--' + Boundary + '--';
blob valueBlob = blob.valueOf(value);
return EncodingUtil.base64Encode(valueBlob);
}
/**
* Write a key-value pair to the form's body.
*/
public static string WriteBodyParameter(string key, string value) {
string contentDisposition = 'Content-Disposition: form-data; name="' + key + '"';
string contentDispositionCrLf = contentDisposition + '\r\n\r\n';
blob contentDispositionCrLfBlob = blob.valueOf(contentDispositionCrLf);
string contentDispositionCrLf64 = EncodingUtil.base64Encode(contentDispositionCrLfBlob);
string content = SafelyPad(contentDisposition, contentDispositionCrLf64, '\r\n\r\n');
string valueCrLf = value + '\r\n';
blob valueCrLfBlob = blob.valueOf(valueCrLf);
string valueCrLf64 = EncodingUtil.base64Encode(valueCrLfBlob);
content += SafelyPad(value, valueCrLf64, '\r\n');
return content;
}
/**
* Helper enum indicating how a file's base64 padding was replaced.
*/
public enum EndingType {
Cr,
CrLf,
None
}
public static string WriteBlobBodyParameter(string key, string file64, string fileName) {
String mimeType = resolveMimeType(fileName);
string contentDisposition = 'Content-Disposition: form-data; name="' + key + '"; filename="'+fileName+'"';
string contentDispositionCrLf = contentDisposition + '\r\n';
blob contentDispositionCrLfBlob = blob.valueOf(contentDispositionCrLf);
string contentDispositionCrLf64 = EncodingUtil.base64Encode(contentDispositionCrLfBlob);
string content = SafelyPad(contentDisposition, contentDispositionCrLf64, '\r\n');
string contentTypeHeader = 'Content-Type: ' + mimeType;
string contentTypeCrLf = contentTypeHeader + '\r\n\r\n';
blob contentTypeCrLfBlob = blob.valueOf(contentTypeCrLf);
string contentTypeCrLf64 = EncodingUtil.base64Encode(contentTypeCrLfBlob);
content += SafelyPad(contentTypeHeader, contentTypeCrLf64, '\r\n\r\n');
integer file64Length = file64.length();
String last4Bytes = file64.substring(file64.length()-4,file64.length());
// Avoid padding the file data with spaces, which SafelyPad does
// http://salesforce.stackexchange.com/a/33326/102
EndingType ending = EndingType.None;
if (last4Bytes.endsWith('==')) {
last4Bytes = last4Bytes.substring(0,2) + '0K';
file64 = file64.substring(0,file64.length()-4) + last4Bytes;
ending = EndingType.CrLf;
} else if (last4Bytes.endsWith('=')) {
last4Bytes = last4Bytes.substring(0,3) + 'N';
file64 = file64.substring(0,file64.length()-4) + last4Bytes;
ending = EndingType.Cr;
}
content += file64;
content += WriteBoundary(ending);
return content;
}
private static String resolveMimeType(String fileName) {
String fileType = fileName.substringAfterLast('.');
String mimeType = 'image/png'; // fallback value
if (fileType.equalsIgnoreCase('png')) {
mimeType = 'image/png';
} else if (fileType.equalsIgnoreCase('jpeg') || fileType.equalsIgnoreCase('jpg')) {
mimeType = 'image/jpg';
} else if (fileType.equalsIgnoreCase('pgm')) {
mimeType = 'image/x-portable-graymap';
} else if (fileType.equalsIgnoreCase('ppm')) {
mimeType = 'image/x-portable-pixmap';
}
return mimeType;
}
}
我正在与接受在其系统中上传文件的供应商之一进行整合。这样做时,他们要求文件以 multipart/form-data 格式发送,格式如下 !!
我尝试使用 Base64 字符串将其配置为多部分表单数据,但仍然无法正常工作!
-H "accept: application/json"
-H "x-api-key: API_KEY"
-H "x-api-token: API_TOKEN"
-H "Content-Type: multipart/form-data"
-F "file=@b4b35527-522d-4228-a266-bdaa80e28a8b.jpg;type=image/jpeg"
salesforce apex 标注不支持您正在查找的内容。 它仍在 salesforce Idea Exchange 中,这里是 link 相同的。
https://trailblazer.salesforce.com/ideaView?id=08730000000Kr80AAC
您可以为其投票,但目前 multipart/form-data header 不受支持。
如果您有任何问题,请告诉我。
Salesforce 确实支持 multipart/form-data,但它不支持将图像作为 Blob 发送。
根据我的要求,我需要将图像/PDF/附件作为表单数据发送。我使用了稍微修改过的 http://www.fishofprey.com/2017/04/steps-required-to-support-posting.html
我得到了另一种 blob 方法,可以将图像和附件作为 blob 包含在内。目前我还没有为视频和其他文档添加编解码器,但很快我会添加这些,因为 API 确实支持那个。
在此处查找修改后的 HttpFormBuilder 版本,将图像和其他附件作为 blob 包含在内。我们只需要添加适当的编解码器。
public class HttpFormBuilder_Custom {
private final static string Boundary = '1ff13444ed8140c7a32fc4e6451aa76d';
public static string GetContentType() {
return 'multipart/form-data; charset="UTF-8"; boundary="' + Boundary + '"';
}
private static string SafelyPad(
string value,
string valueCrLf64,
string lineBreaks) {
string valueCrLf = '';
blob valueCrLfBlob = null;
while (valueCrLf64.endsWith('=')) {
value += ' ';
valueCrLf = value + lineBreaks;
valueCrLfBlob = blob.valueOf(valueCrLf);
valueCrLf64 = EncodingUtil.base64Encode(valueCrLfBlob);
}
return valueCrLf64;
}
public static string WriteBoundary() {
string value = '--' + Boundary + '\r\n';
blob valueBlob = blob.valueOf(value);
return EncodingUtil.base64Encode(valueBlob);
}
public static string WriteBoundary(
EndingType ending) {
string value = '';
if (ending == EndingType.Cr) {
value += '\n';
} else if (ending == EndingType.None) {
value += '\r\n';
}
value += '--' + Boundary + '--';
blob valueBlob = blob.valueOf(value);
return EncodingUtil.base64Encode(valueBlob);
}
/**
* Write a key-value pair to the form's body.
*/
public static string WriteBodyParameter(string key, string value) {
string contentDisposition = 'Content-Disposition: form-data; name="' + key + '"';
string contentDispositionCrLf = contentDisposition + '\r\n\r\n';
blob contentDispositionCrLfBlob = blob.valueOf(contentDispositionCrLf);
string contentDispositionCrLf64 = EncodingUtil.base64Encode(contentDispositionCrLfBlob);
string content = SafelyPad(contentDisposition, contentDispositionCrLf64, '\r\n\r\n');
string valueCrLf = value + '\r\n';
blob valueCrLfBlob = blob.valueOf(valueCrLf);
string valueCrLf64 = EncodingUtil.base64Encode(valueCrLfBlob);
content += SafelyPad(value, valueCrLf64, '\r\n');
return content;
}
/**
* Helper enum indicating how a file's base64 padding was replaced.
*/
public enum EndingType {
Cr,
CrLf,
None
}
public static string WriteBlobBodyParameter(string key, string file64, string fileName) {
String mimeType = resolveMimeType(fileName);
string contentDisposition = 'Content-Disposition: form-data; name="' + key + '"; filename="'+fileName+'"';
string contentDispositionCrLf = contentDisposition + '\r\n';
blob contentDispositionCrLfBlob = blob.valueOf(contentDispositionCrLf);
string contentDispositionCrLf64 = EncodingUtil.base64Encode(contentDispositionCrLfBlob);
string content = SafelyPad(contentDisposition, contentDispositionCrLf64, '\r\n');
string contentTypeHeader = 'Content-Type: ' + mimeType;
string contentTypeCrLf = contentTypeHeader + '\r\n\r\n';
blob contentTypeCrLfBlob = blob.valueOf(contentTypeCrLf);
string contentTypeCrLf64 = EncodingUtil.base64Encode(contentTypeCrLfBlob);
content += SafelyPad(contentTypeHeader, contentTypeCrLf64, '\r\n\r\n');
integer file64Length = file64.length();
String last4Bytes = file64.substring(file64.length()-4,file64.length());
// Avoid padding the file data with spaces, which SafelyPad does
// http://salesforce.stackexchange.com/a/33326/102
EndingType ending = EndingType.None;
if (last4Bytes.endsWith('==')) {
last4Bytes = last4Bytes.substring(0,2) + '0K';
file64 = file64.substring(0,file64.length()-4) + last4Bytes;
ending = EndingType.CrLf;
} else if (last4Bytes.endsWith('=')) {
last4Bytes = last4Bytes.substring(0,3) + 'N';
file64 = file64.substring(0,file64.length()-4) + last4Bytes;
ending = EndingType.Cr;
}
content += file64;
content += WriteBoundary(ending);
return content;
}
private static String resolveMimeType(String fileName) {
String fileType = fileName.substringAfterLast('.');
String mimeType = 'image/png'; // fallback value
if (fileType.equalsIgnoreCase('png')) {
mimeType = 'image/png';
} else if (fileType.equalsIgnoreCase('jpeg') || fileType.equalsIgnoreCase('jpg')) {
mimeType = 'image/jpg';
} else if (fileType.equalsIgnoreCase('pgm')) {
mimeType = 'image/x-portable-graymap';
} else if (fileType.equalsIgnoreCase('ppm')) {
mimeType = 'image/x-portable-pixmap';
}
return mimeType;
}
}