datai/datai-scenes/datai-scene-salesforce/docs/reference-code/com/docs/index.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

21 KiB
Raw Blame History

Salesforce SOAP API Java 客户端参考文档

唯一真源文档

本文档是 Salesforce SOAP API Java 客户端的唯一真源文档,包含四个核心模块的完整说明、使用指南和最佳实践。

📋 文档信息

  • 文档版本: v1.0.0
  • 创建日期: 2026-01-18
  • 最后更新: 2026-01-18
  • 维护者: Datai Team
  • 文档路径: docs/reference-code/com/docs/index.md

🎯 概述

本文档提供了 Salesforce 官方提供的四个 WSDL 对应的 Java 源代码的完整说明,包括:

  1. com.sforce.soap.apex - Apex SOAP API
  2. com.sforce.soap.metadata - Metadata API
  3. com.sforce.soap.tooling - Tooling API
  4. com.sforce.soap.partner - Partner API

这些模块位于 docs/reference-code/com/sforce/soap/ 目录下,提供了与 Salesforce 进行交互的完整 Java 客户端实现。

📚 模块导航

1. Apex SOAP API 模块

文档: apex-module.md

用途: 提供 Apex 代码编译、执行和测试功能

核心功能:

  • Apex 代码编译和执行
  • 测试执行和结果管理
  • 代码覆盖率分析
  • Flow 覆盖率检查
  • 日志记录和调试

主要类:

  • SoapConnection - SOAP 连接类
  • RunTestsRequest - 测试请求类
  • RunTestsResult - 测试结果类
  • ExecuteAnonymousResult - 匿名执行结果类

适用场景:

  • CI/CD 集成
  • 代码质量检查
  • 动态代码执行
  • Flow 测试

2. Metadata API 模块

文档: metadata-module.md

用途: 提供元数据管理功能,用于创建、读取、更新和删除 Salesforce 元数据

核心功能:

  • 元数据类型定义(数百种)
  • 部署操作
  • 异步操作管理
  • 删除操作

主要类:

  • CustomObject - 自定义对象定义
  • CustomField - 自定义字段定义
  • ApexClass - Apex 类定义
  • DeployOptions - 部署选项配置
  • DeployResult - 部署结果

适用场景:

  • 元数据部署
  • 元数据检索
  • CI/CD 集成
  • 元数据管理
  • 分析和报告

3. Tooling API 模块

文档: tooling-module.md

用途: 提供开发工具功能,用于访问和操作 Salesforce 的开发工具

核心功能:

  • 元数据操作
  • 开发工具功能
  • AI 和智能功能
  • 动作和自动化
  • 访问和安全

主要类:

  • ToolingConnection - Tooling API 连接类
  • ApexCodeCoverage - Apex 代码覆盖率
  • ApexTestQueueItem - Apex 测试队列项
  • FlowTestCoverage - Flow 测试覆盖率
  • AIApplication - AI 应用程序

适用场景:

  • 开发工具集成
  • 测试和质量保证
  • CI/CD 集成
  • AI 和智能功能
  • 元数据管理

4. Partner API 模块

文档: partner-module.md

用途: 提供数据交互功能,用于 CRUD 操作、查询和数据同步

核心功能:

  • CRUD 操作
  • 批量操作
  • 查询功能
  • 描述功能
  • 认证和会话
  • 高级功能

主要类:

  • Connector - Partner API 连接类
  • SObject - 动态对象类
  • QueryResult - 查询结果类
  • SaveResult - 保存结果类
  • DescribeSObjectResult - 对象描述结果类

适用场景:

  • 数据同步
  • 数据集成
  • 自定义应用开发
  • 报表和分析
  • 数据管理

🔧 快速开始

环境要求

  • Java 8 或更高版本
  • Salesforce WSC (Web Services Connector) 库
  • 有效的 Salesforce 账户和 API 访问权限

依赖配置

Maven 依赖

<dependencies>
    <!-- Salesforce WSC -->
    <dependency>
        <groupId>com.force.api</groupId>
        <artifactId>force-wsc</artifactId>
        <version>58.0.0</version>
    </dependency>
    
    <!-- Salesforce Partner API -->
    <dependency>
        <groupId>com.force.api</groupId>
        <artifactId>force-partner-api</artifactId>
        <version>58.0.0</version>
    </dependency>
    
    <!-- Salesforce Metadata API -->
    <dependency>
        <groupId>com.force.api</groupId>
        <artifactId>force-metadata-api</artifactId>
        <version>58.0.0</version>
    </dependency>
    
    <!-- Salesforce Tooling API -->
    <dependency>
        <groupId>com.force.api</groupId>
        <artifactId>force-tooling-api</artifactId>
        <version>58.0.0</version>
    </dependency>
    
    <!-- Salesforce Apex API -->
    <dependency>
        <groupId>com.force.api</groupId>
        <artifactId>force-apex-api</artifactId>
        <version>58.0.0</version>
    </dependency>
</dependencies>

Gradle 依赖

dependencies {
    implementation 'com.force.api:force-wsc:58.0.0'
    implementation 'com.force.api:force-partner-api:58.0.0'
    implementation 'com.force.api:force-metadata-api:58.0.0'
    implementation 'com.force.api:force-tooling-api:58.0.0'
    implementation 'com.force.api:force-apex-api:58.0.0'
}

📖 使用指南

1. Partner API 使用示例

建立连接

import com.sforce.soap.partner.*;
import com.sforce.ws.*;

// 创建连接配置
ConnectorConfig config = new ConnectorConfig();
config.setUsername("your-username");
config.setPassword("your-password");
config.setAuthEndpoint("https://login.salesforce.com/services/Soap/u/58.0");

// 创建连接
PartnerConnection connection = new PartnerConnection(config);

// 获取会话信息
System.out.println("Session ID: " + config.getSessionId());
System.out.println("Server URL: " + config.getServiceEndpoint());

创建记录

// 创建 Account 对象
SObject account = new SObject();
account.setType("Account");
account.setField("Name", "Acme Corporation");
account.setField("Industry", "Technology");
account.setField("Phone", "555-1234");

// 执行创建
SaveResult[] results = connection.create(new SObject[]{account});

// 处理结果
for (SaveResult result : results) {
    if (result.isSuccess()) {
        System.out.println("创建成功ID: " + result.getId());
    } else {
        for (Error error : result.getErrors()) {
            System.out.println("错误: " + error.getMessage());
        }
    }
}

查询记录

// 执行 SOQL 查询
QueryResult queryResult = connection.query(
    "SELECT Id, Name, Industry, Phone FROM Account WHERE Industry = 'Technology'"
);

// 处理结果
for (SObject record : queryResult.getRecords()) {
    String id = record.getId();
    String name = record.getField("Name").toString();
    String industry = record.getField("Industry").toString();
    String phone = record.getField("Phone").toString();
    
    System.out.println("ID: " + id);
    System.out.println("Name: " + name);
    System.out.println("Industry: " + industry);
    System.out.println("Phone: " + phone);
}

// 处理分页
while (!queryResult.isDone()) {
    queryResult = connection.queryMore(queryResult.getQueryLocator());
    // 处理更多记录
}

更新记录

// 创建要更新的对象
SObject account = new SObject();
account.setType("Account");
account.setId("001xx000003IAC");
account.setField("Phone", "555-5678");
account.setField("Industry", "Finance");

// 执行更新
SaveResult[] results = connection.update(new SObject[]{account});

// 处理结果
for (SaveResult result : results) {
    if (result.isSuccess()) {
        System.out.println("更新成功");
    } else {
        for (Error error : result.getErrors()) {
            System.out.println("错误: " + error.getMessage());
        }
    }
}

删除记录

// 执行删除
DeleteResult[] results = connection.delete(new String[]{"001xx000003IAC"});

// 处理结果
for (DeleteResult result : results) {
    if (result.isSuccess()) {
        System.out.println("删除成功");
    } else {
        for (Error error : result.getErrors()) {
            System.out.println("错误: " + error.getMessage());
        }
    }
}

2. Metadata API 使用示例

建立连接

import com.sforce.soap.metadata.*;
import com.sforce.ws.*;

// 创建连接配置
ConnectorConfig config = new ConnectorConfig();
config.setUsername("your-username");
config.setPassword("your-password");
config.setAuthEndpoint("https://login.salesforce.com/services/Soap/m/58.0");

// 创建连接
MetadataConnection connection = new MetadataConnection(config);

创建自定义对象

// 创建自定义对象
CustomObject customObject = new CustomObject();
customObject.setFullName("MyCustomObject__c");
customObject.setLabel("My Custom Object");
customObject.setPluralLabel("My Custom Objects");
customObject.setDeploymentStatus("Deployed");
customObject.setSharingModel("ReadWrite");

// 添加字段
CustomField nameField = new CustomField();
nameField.setFullName("MyCustomObject__c.Name__c");
nameField.setType("Text");
nameField.setLabel("Name");

CustomField emailField = new CustomField();
emailField.setFullName("MyCustomObject__c.Email__c");
emailField.setType("Email");
emailField.setLabel("Email Address");
emailField.setRequired(true);

customObject.setFields(new CustomField[]{nameField, emailField});

// 部署元数据
AsyncResult result = connection.create(new Metadata[]{customObject});

// 等待部署完成
while (!result.isDone()) {
    Thread.sleep(1000);
    result = connection.checkStatus(result.getId());
}

if (result.getState() == AsyncRequestState.Completed) {
    System.out.println("部署成功");
} else {
    System.out.println("部署失败: " + result.getMessage());
}

部署元数据

// 创建部署选项
DeployOptions options = new DeployOptions();
options.setCheckOnly(false);
options.setTestLevel("RunLocalTests");
options.setRollbackOnError(true);

// 读取 zip 文件
File zipFile = new File("metadata.zip");
byte[] zipBytes = Files.readAllBytes(zipFile.toPath());

// 执行部署
AsyncResult result = connection.deploy(zipBytes, options);

// 等待部署完成
while (!result.isDone()) {
    Thread.sleep(1000);
    result = connection.checkStatus(result.getId());
}

// 获取部署结果
DeployResult deployResult = connection.checkDeployStatus(result.getId());

if (deployResult.isSuccess()) {
    System.out.println("部署成功");
    System.out.println("部署的组件数: " + deployResult.getNumberComponentsDeployed());
} else {
    System.out.println("部署失败");
    for (DeployMessage message : deployResult.getMessages()) {
        System.out.println("错误: " + message.getProblem());
    }
}

3. Tooling API 使用示例

建立连接

import com.sforce.soap.tooling.*;
import com.sforce.ws.*;

// 创建连接配置
ConnectorConfig config = new ConnectorConfig();
config.setUsername("your-username");
config.setPassword("your-password");
config.setAuthEndpoint("https://login.salesforce.com/services/Soap/T/58.0");

// 创建连接
ToolingConnection connection = new ToolingConnection(config);

查询代码覆盖率

// 执行 SOQL 查询
QueryResult queryResult = connection.query(
    "SELECT ApexClassOrTriggerName, Coverage, NumLinesCovered, NumLinesUncovered " +
    "FROM ApexCodeCoverage " +
    "ORDER BY Coverage DESC"
);

// 处理结果
for (SObject record : queryResult.getRecords()) {
    ApexCodeCoverage coverage = (ApexCodeCoverage) record;
    String name = coverage.getApexClassOrTriggerName();
    double coveragePercent = coverage.getCoverage();
    int linesCovered = coverage.getNumLinesCovered();
    int linesUncovered = coverage.getNumLinesUncovered();
    
    System.out.println("类名: " + name);
    System.out.println("覆盖率: " + coveragePercent + "%");
    System.out.println("覆盖行数: " + linesCovered);
    System.out.println("未覆盖行数: " + linesUncovered);
}

查询 Flow 测试覆盖率

// 执行 SOQL 查询
QueryResult queryResult = connection.query(
    "SELECT FlowName, Coverage, NumElementsCovered, NumElementsNotCovered " +
    "FROM FlowTestCoverage " +
    "ORDER BY Coverage DESC"
);

// 处理结果
for (SObject record : queryResult.getRecords()) {
    FlowTestCoverage coverage = (FlowTestCoverage) record;
    String flowName = coverage.getFlowName();
    double coveragePercent = coverage.getCoverage();
    int elementsCovered = coverage.getNumElementsCovered();
    int elementsNotCovered = coverage.getNumElementsNotCovered();
    
    System.out.println("Flow 名称: " + flowName);
    System.out.println("覆盖率: " + coveragePercent + "%");
    System.out.println("覆盖元素数: " + elementsCovered);
    System.out.println("未覆盖元素数: " + elementsNotCovered);
}

4. Apex API 使用示例

建立连接

import com.sforce.soap.apex.*;
import com.sforce.ws.*;

// 创建连接配置
ConnectorConfig config = new ConnectorConfig();
config.setUsername("your-username");
config.setPassword("your-password");
config.setAuthEndpoint("https://login.salesforce.com/services/Soap/s/58.0");

// 创建连接
SoapConnection connection = new SoapConnection(config);

执行匿名代码

// 执行匿名 Apex 代码
String code = "Account acc = new Account(Name='Test Account'); insert acc;";

ExecuteAnonymousResult result = connection.executeAnonymous(code);

// 处理结果
if (result.isSuccess()) {
    System.out.println("执行成功");
} else {
    System.out.println("执行失败");
    System.out.println("编译问题: " + result.getCompileProblem());
    System.out.println("异常消息: " + result.getExceptionMessage());
    System.out.println("异常堆栈: " + result.getExceptionStackTrace());
}

运行测试

// 创建测试请求
RunTestsRequest request = new RunTestsRequest();
request.setAllTests(true);

// 执行测试
RunTestsResult result = connection.runTests(request);

// 处理结果
System.out.println("测试总数: " + result.getNumTestsRun());
System.out.println("失败数: " + result.getNumFailures());
System.out.println("代码覆盖率: " + result.getCodeCoverage());

// 处理失败的测试
for (RunTestFailure failure : result.getFailures()) {
    System.out.println("失败的测试: " + failure.getName());
    System.out.println("错误消息: " + failure.getMessage());
    System.out.println("堆栈跟踪: " + failure.getStackTrace());
}

// 处理成功的测试
for (RunTestSuccess success : result.getSuccesses()) {
    System.out.println("成功的测试: " + success.getName());
    System.out.println("执行时间: " + success.getTime() + "ms");
}

⚠️ 注意事项

API 限制

  1. Partner API

    • 每日 API 调用限制:根据许可证类型而定
    • 单次查询记录数限制50,000 条
    • 批量操作限制200 条记录
  2. Metadata API

    • 部署文件大小限制39 MB
    • 单次部署组件数限制10,000 个
    • 异步操作超时10 分钟
  3. Tooling API

    • 每日 API 调用限制:根据许可证类型而定
    • SOQL 查询限制50,000 条记录
    • 并发请求限制:根据许可证类型而定
  4. Apex API

    • 每日 API 调用限制:根据许可证类型而定
    • 执行时间限制60 秒
    • 堆栈深度限制1,000 层

权限要求

  • 需要适当的 API 权限
  • 需要对象和字段的 CRUD 权限
  • 某些操作需要系统管理员权限

错误处理

  • 实现完善的错误处理机制
  • 记录详细的错误日志
  • 实现重试逻辑
  • 处理网络超时和连接问题

性能优化

  • 使用批量操作减少 API 调用
  • 只查询需要的字段
  • 使用适当的过滤条件
  • 实现缓存机制
  • 监控 API 调用性能

🎓 最佳实践

1. 连接管理

// 使用连接池
public class SalesforceConnectionPool {
    private static final Map<String, PartnerConnection> connectionPool = new ConcurrentHashMap<>();
    
    public static PartnerConnection getConnection(String username, String password) {
        return connectionPool.computeIfAbsent(username, key -> {
            try {
                ConnectorConfig config = new ConnectorConfig();
                config.setUsername(username);
                config.setPassword(password);
                config.setAuthEndpoint("https://login.salesforce.com/services/Soap/u/58.0");
                return new PartnerConnection(config);
            } catch (ConnectionException e) {
                throw new RuntimeException("创建连接失败", e);
            }
        });
    }
    
    public static void closeConnection(String username) {
        PartnerConnection connection = connectionPool.remove(username);
        if (connection != null) {
            try {
                connection.logout();
            } catch (ConnectionException e) {
                // 忽略登出错误
            }
        }
    }
}

2. 批量操作

// 批量创建记录
public void createAccounts(List<Account> accounts) throws ConnectionException {
    final int BATCH_SIZE = 200;
    
    for (int i = 0; i < accounts.size(); i += BATCH_SIZE) {
        int end = Math.min(i + BATCH_SIZE, accounts.size());
        List<Account> batch = accounts.subList(i, end);
        
        SObject[] sObjects = batch.stream()
            .map(this::convertToSObject)
            .toArray(SObject[]::new);
        
        SaveResult[] results = connection.create(sObjects);
        
        for (SaveResult result : results) {
            if (!result.isSuccess()) {
                // 处理错误
            }
        }
    }
}

3. 错误处理

// 统一错误处理
public class SalesforceErrorHandler {
    public static void handleSaveResult(SaveResult result) {
        if (!result.isSuccess()) {
            for (Error error : result.getErrors()) {
                log.error("保存失败 - ID: {}, 错误代码: {}, 消息: {}, 字段: {}",
                    result.getId(),
                    error.getStatusCode(),
                    error.getMessage(),
                    String.join(", ", error.getFields())
                );
            }
        }
    }
    
    public static void handleConnectionException(ConnectionException e) {
        if (e instanceof ApiFault) {
            ApiFault fault = (ApiFault) e;
            log.error("API 错误 - 异常代码: {}, 消息: {}",
                fault.getExceptionCode(),
                fault.getExceptionMessage()
            );
        } else {
            log.error("连接错误", e);
        }
    }
}

4. 重试机制

// 带重试的 API 调用
public class SalesforceRetryHandler {
    private static final int MAX_RETRIES = 3;
    private static final long RETRY_DELAY_MS = 1000;
    
    public static <T> T executeWithRetry(Callable<T> callable) throws Exception {
        int retryCount = 0;
        Exception lastException = null;
        
        while (retryCount < MAX_RETRIES) {
            try {
                return callable.call();
            } catch (ConnectionException e) {
                lastException = e;
                retryCount++;
                
                if (retryCount < MAX_RETRIES) {
                    log.warn("API 调用失败,{} 秒后重试 (第 {} 次)", 
                        RETRY_DELAY_MS / 1000, retryCount);
                    Thread.sleep(RETRY_DELAY_MS);
                }
            }
        }
        
        throw new Exception("API 调用失败,已达到最大重试次数", lastException);
    }
}

5. 日志记录

// API 调用日志记录
public class SalesforceLogger {
    public static void logApiCall(String apiName, String operation, Object params) {
        log.info("API 调用 - 名称: {}, 操作: {}, 参数: {}", 
            apiName, operation, params);
    }
    
    public static void logApiResult(String apiName, String operation, 
                                     boolean success, Object result) {
        if (success) {
            log.info("API 调用成功 - 名称: {}, 操作: {}, 结果: {}", 
                apiName, operation, result);
        } else {
            log.error("API 调用失败 - 名称: {}, 操作: {}, 结果: {}", 
                apiName, operation, result);
        }
    }
}

🔗 相关资源

官方文档

开发工具

社区资源

📝 更新日志

v1.0.0 (2026-01-18)

  • 初始版本发布
  • 包含四个核心模块的完整说明
  • 提供使用示例和最佳实践
  • 添加注意事项和错误处理指南

📧 联系方式

如有问题或建议,请联系:

  • 维护者: Datai Team
  • 邮箱: support@datai.com
  • 文档路径: docs/reference-code/com/docs/index.md

注意: 本文档是唯一真源文档,所有关于 Salesforce SOAP API Java 客户端的使用说明和最佳实践都应以此文档为准。如有任何疑问,请参考本文档或联系维护者。