datai/datai-scenes/datai-scene-salesforce/docs/reference-code/data-dump/Attachment文件上传.md
Kris 2e6f087732 docs: 完成REQ-010-17和REQ-010-2的文档创建
- 完成REQ-010-17(性能优化和限流处理)的所有6个阶段
  - 创建ADR文档:0026-performance-optimization.md
  - 创建Prompt文档:027-performance-optimization.md
  - 创建会话记录:20260119-performance-optimization.md
  - 创建变更记录:20260119-performance-optimization.md
  - 创建复盘报告:20260119-performance-optimization-retro.md
  - 更新index.md和CHANGELOG.md

- 完成REQ-010-2(基础实体类和Mapper创建)的前3个阶段
  - 更新ADR文档:0011-entity-mapper-create.md
  - 创建Prompt文档:002-entity-mapper-create.md
  - 更新index.md

所有文档均按照SSOT方法论创建,包括需求定义、架构决策、提示词资产化、执行会话、变更记录和闭环复盘。
2026-01-19 10:06:09 +08:00

4.1 KiB
Raw Blame History

1. 上传逻辑核心步骤

  1. 读取本地文件:将文件读入字节数组。

  2. Base64 编码Salesforce 的 Attachment 对象要求 Body 字段必须是 Base64 编码的文本。

  3. 构造 JSON 负载

    • ParentId: 关联的记录 ID如 Account, Contact, 或自定义对象的 ID

    • Name: 文件名。

    • Body: Base64 后的字符串。

  4. 发送 POST 请求:调用 sobjects/Attachment/ 接口。


2. Java 代码实现 (基于 HttpClient)

这里继续使用 Java 11+ 的 HttpClient。为了代码简洁,使用了 java.util.Base64

Java

import java.io.nio.file.Files;
import java.io.nio.file.Path;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Base64;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper; // 建议使用 Jackson 处理 JSON

public class SalesforceFileUploader {

    private static final String INSTANCE_URL = "https://your-instance.my.salesforce.com";
    private static final String ACCESS_TOKEN = "YOUR_ACCESS_TOKEN";

    public void uploadAttachment(String parentId, String filePath, String fileName) throws Exception {
        // 1. 将文件转换为 Base64 字符串
        byte[] fileContent = Files.readAllBytes(Path.of(filePath));
        String encodedString = Base64.getEncoder().encodeToString(fileContent);

        // 2. 准备请求体数据
        Map<String, String> payload = Map.of(
            "ParentId", parentId,
            "Name", fileName,
            "Body", encodedString
        );
        
        // 使用 Jackson 将 Map 转换为 JSON 字符串
        String jsonPayload = new ObjectMapper().writeValueAsString(payload);

        // 3. 构建 POST 请求
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(INSTANCE_URL + "/services/data/v58.0/sobjects/Attachment/"))
                .header("Authorization", "Bearer " + ACCESS_TOKEN)
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
                .build();

        // 4. 发送并处理响应
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() == 201) {
            System.out.println("上传成功Salesforce ID: " + response.body());
        } else {
            System.err.println("上传失败: " + response.body());
        }
    }
}

3. 关键字段说明

字段名 必填 说明
ParentId 附件所属记录的 ID。
Name 附件显示的名称(需带后缀,如 report.pdf)。
Body 文件的 Base64 编码内容。
Description 附件的简短描述。
IsPrivate 布尔值,是否设置为私有。

4. 注意事项与限制

  • 文件大小限制

    • 通过简单 REST API (JSON) 上传时,受限于请求体大小,通常建议单个文件不超过 50MBBase64 编码后体积会增加约 33%)。

    • 如果需要上传超大文件,建议使用 Multipart/form-data 格式,或者改用 Salesforce Files (ContentVersion) 对象。

  • 堆内存消耗

    • Files.readAllBytes 和 Base64 编码都会在 Java 内存中创建大对象。如果系统需要并发处理大量上传,建议优化为流式处理或增加 JVM 堆空间。
  • 弃用警告

    • Salesforce 官方已经不推荐在新项目中使用 Attachment,取而代之的是 ContentVersion(即 Salesforce FilesContentVersion 支持版本控制、更灵活的共享机制以及更大的单文件上限(最大 2GB

5. (进阶建议) 改用 ContentVersion (Files) 吗?

如果你的业务允许,强烈建议将 Attachment 替换为 ContentVersion。两者的主要区别是:

  • Attachment: 绑定在 ParentId 上,功能单一。

  • ContentVersion: 先上传文件生成 ID再通过 ContentDocumentLink 关联到多个记录,功能更强大。