API 文档 - 检索操作
元数据
- 需求编号:003-06
- 创建时间:2026-02-06
- 创建人:AI Assistant
- 状态:已完成
- 版本:v1.0.0
API 概述
本文档描述了 Salesforce Metadata API 检索操作相关的 REST API 接口,包括元数据检索请求提交、状态轮询、状态检查和历史查询功能。
核心功能
- 提交检索请求:向 Salesforce 提交元数据检索请求,返回异步操作 ID
- 轮询检索状态:循环检查检索状态直到完成或超时
- 单次状态检查:单次检查检索状态,返回当前状态
- 检索历史查询:查询检索操作的历史记录
- 检索记录查询:根据 asyncId 查询具体的检索记录
技术栈
- Spring Boot 2.7.x
- Spring Security(权限控制)
- MyBatis Plus(数据持久化)
- Salesforce Metadata API
基础路径
/salesforce/metadata/retrieve
接口列表
接口 1:提交检索请求
功能描述
向 Salesforce 提交元数据检索请求。检索操作是异步的,提交后会立即返回一个异步操作 ID(asyncId),客户端需要使用这个 ID 轮询检索状态或查询结果。
请求方式
POST
请求路径
/salesforce/metadata/retrieve
权限要求
- 权限标识:
salesforce:metadata:retrieve
- 使用
@PreAuthorize("@ss.hasPermi('salesforce:metadata:retrieve')") 控制
请求参数
请求体参数(JSON)
| 参数名 |
类型 |
必填 |
说明 |
示例 |
| apiVersion |
Double |
是 |
API 版本 |
59.0 |
| singlePackage |
Boolean |
否 |
是否为单个包,默认 false |
false |
| unpackaged |
Object |
条件 |
未打包的元数据类型列表(与 packageNames 二选一) |
见下方示例 |
| packageNames |
String[] |
条件 |
包名称列表(与 unpackaged 二选一) |
["MyPackage"] |
| specificFiles |
String[] |
否 |
特定文件列表 |
["package.xml"] |
Unpackaged 对象结构
| 参数名 |
类型 |
必填 |
说明 |
示例 |
| types |
Array |
是 |
元数据类型列表 |
见下方示例 |
PackageTypeMember 对象结构
| 参数名 |
类型 |
必填 |
说明 |
示例 |
| name |
String |
是 |
元数据类型名称 |
"CustomObject" |
| members |
String[] |
是 |
成员列表,* 表示所有 |
["*"] |
请求示例
示例 1:检索所有 CustomObject
POST /salesforce/metadata/retrieve
Content-Type: application/json
{
"apiVersion": 59.0,
"singlePackage": false,
"unpackaged": {
"types": [
{
"name": "CustomObject",
"members": ["*"]
}
]
}
}
示例 2:检索特定包
POST /salesforce/metadata/retrieve
Content-Type: application/json
{
"apiVersion": 59.0,
"singlePackage": true,
"packageNames": ["MyManagedPackage"]
}
示例 3:检索多种元数据类型
POST /salesforce/metadata/retrieve
Content-Type: application/json
{
"apiVersion": 59.0,
"unpackaged": {
"types": [
{
"name": "CustomObject",
"members": ["Account", "Contact"]
},
{
"name": "ApexClass",
"members": ["MyClass", "MyTestClass"]
},
{
"name": "ApexTrigger",
"members": ["*"]
}
]
}
}
响应参数
成功响应(HTTP 200)
| 参数名 |
类型 |
说明 |
示例 |
| code |
Integer |
状态码,200 表示成功 |
200 |
| msg |
String |
提示信息 |
"操作成功" |
| data |
Object |
异步结果对象 |
见下方说明 |
AsyncResult 对象
| 参数名 |
类型 |
说明 |
示例 |
| id |
String |
异步操作 ID |
"09Sxx0000000001EAA" |
| done |
Boolean |
是否完成 |
false |
| state |
String |
状态(Queued、InProgress、Completed、Error) |
"Queued" |
成功响应示例
{
"code": 200,
"msg": "操作成功",
"data": {
"id": "09Sxx0000000001EAA",
"done": false,
"state": "Queued"
}
}
错误响应示例
{
"code": 500,
"msg": "检索元数据失败: 连接超时",
"data": null
}
接口 2:轮询检索状态
功能描述
轮询检索状态直到完成或超时。此接口会循环检查检索状态,直到检索完成(成功或失败)或达到超时时间。适用于需要等待检索完成的场景。
请求方式
GET
请求路径
/salesforce/metadata/retrieve/status/{asyncId}
权限要求
- 权限标识:
salesforce:metadata:retrieve
请求参数
路径参数
| 参数名 |
类型 |
必填 |
说明 |
示例 |
| asyncId |
String |
是 |
异步操作 ID |
"09Sxx0000000001EAA" |
查询参数
| 参数名 |
类型 |
必填 |
说明 |
示例 |
| interval |
Long |
否 |
轮询间隔(毫秒),默认 5000 |
5000 |
| timeout |
Long |
否 |
超时时间(毫秒),默认 300000(5分钟) |
300000 |
请求示例
GET /salesforce/metadata/retrieve/status/09Sxx0000000001EAA?interval=5000&timeout=300000
响应参数
成功响应(HTTP 200)
| 参数名 |
类型 |
说明 |
示例 |
| code |
Integer |
状态码,200 表示成功 |
200 |
| msg |
String |
提示信息 |
"操作成功" |
| data |
Object |
检索结果对象 |
见下方说明 |
RetrieveResultVo 对象
| 参数名 |
类型 |
说明 |
示例 |
| asyncId |
String |
异步操作 ID |
"09Sxx0000000001EAA" |
| status |
String |
检索状态 |
"Succeeded" |
| success |
Boolean |
是否成功 |
true |
| zipFile |
String |
ZIP 文件数据(Base64 编码) |
"UEsDBBQ..." |
| errorMessage |
String |
错误消息(失败时) |
null |
| messages |
Array |
检索消息列表 |
见下方说明 |
| completedTime |
Date |
完成时间 |
"2026-02-06T10:30:00" |
| done |
Boolean |
是否完成 |
true |
RetrieveMessageVo 对象
| 参数名 |
类型 |
说明 |
示例 |
| fileName |
String |
文件名 |
"objects/Account.object" |
| problem |
String |
问题描述 |
"Entity is not found" |
| problemType |
String |
问题类型 |
"Warning" |
成功响应示例
{
"code": 200,
"msg": "操作成功",
"data": {
"asyncId": "09Sxx0000000001EAA",
"status": "Succeeded",
"success": true,
"zipFile": "UEsDBBQACAAI...",
"errorMessage": null,
"messages": [],
"completedTime": "2026-02-06T10:30:00",
"done": true
}
}
超时响应示例
{
"code": 500,
"msg": "检索操作超时",
"data": null
}
接口 3:单次检查状态
功能描述
单次检查检索状态,立即返回当前状态。适用于前端主动轮询的场景,由前端控制轮询间隔。
请求方式
GET
请求路径
/salesforce/metadata/retrieve/check/{asyncId}
权限要求
- 权限标识:
salesforce:metadata:retrieve
请求参数
路径参数
| 参数名 |
类型 |
必填 |
说明 |
示例 |
| asyncId |
String |
是 |
异步操作 ID |
"09Sxx0000000001EAA" |
请求示例
GET /salesforce/metadata/retrieve/check/09Sxx0000000001EAA
响应参数
成功响应(HTTP 200)
与"轮询检索状态"接口的响应参数相同,但只返回当前状态,不会等待完成。
进行中响应示例
{
"code": 200,
"msg": "操作成功",
"data": {
"asyncId": "09Sxx0000000001EAA",
"status": "InProgress",
"success": null,
"zipFile": null,
"errorMessage": null,
"messages": [],
"completedTime": null,
"done": false
}
}
已完成响应示例
{
"code": 200,
"msg": "操作成功",
"data": {
"asyncId": "09Sxx0000000001EAA",
"status": "Succeeded",
"success": true,
"zipFile": "UEsDBBQACAAI...",
"errorMessage": null,
"messages": [],
"completedTime": "2026-02-06T10:30:00",
"done": true
}
}
接口 4:获取检索历史
功能描述
获取检索操作的历史记录列表。返回最近的检索记录,支持限制返回数量。
请求方式
GET
请求路径
/salesforce/metadata/retrieve/history
权限要求
- 权限标识:
salesforce:metadata:retrieve
请求参数
查询参数
| 参数名 |
类型 |
必填 |
说明 |
示例 |
| limit |
Integer |
否 |
返回数量限制,默认 50,最大 100 |
50 |
请求示例
GET /salesforce/metadata/retrieve/history?limit=20
响应参数
成功响应(HTTP 200)
| 参数名 |
类型 |
说明 |
示例 |
| code |
Integer |
状态码,200 表示成功 |
200 |
| msg |
String |
提示信息 |
"操作成功" |
| data |
Array |
检索历史列表 |
见下方说明 |
DataiMetadataRetrieve 对象
| 参数名 |
类型 |
说明 |
示例 |
| id |
Long |
记录 ID |
1 |
| asyncId |
String |
异步操作 ID |
"09Sxx0000000001EAA" |
| status |
String |
检索状态 |
"Succeeded" |
| done |
Boolean |
是否完成 |
true |
| message |
String |
消息 |
"Retrieve completed successfully" |
| errorMessage |
String |
错误消息 |
null |
| retrieveTime |
Date |
检索时间 |
"2026-02-06T10:30:00" |
| updateTime |
Date |
更新时间 |
"2026-02-06T10:30:00" |
| userId |
Long |
用户 ID |
1 |
| createBy |
String |
创建者 |
"admin" |
| createTime |
Date |
创建时间 |
"2026-02-06T10:25:00" |
成功响应示例
{
"code": 200,
"msg": "操作成功",
"data": [
{
"id": 1,
"asyncId": "09Sxx0000000001EAA",
"status": "Succeeded",
"done": true,
"message": "Retrieve completed successfully",
"errorMessage": null,
"retrieveTime": "2026-02-06T10:30:00",
"updateTime": "2026-02-06T10:30:00",
"userId": 1,
"createBy": "admin",
"createTime": "2026-02-06T10:25:00"
},
{
"id": 2,
"asyncId": "09Sxx0000000002EAA",
"status": "Failed",
"done": true,
"message": null,
"errorMessage": "Invalid API version",
"retrieveTime": "2026-02-06T10:20:00",
"updateTime": "2026-02-06T10:20:00",
"userId": 1,
"createBy": "admin",
"createTime": "2026-02-06T10:15:00"
}
]
}
接口 5:查询检索记录
功能描述
根据 asyncId 查询具体的检索记录。用于获取某个特定检索操作的详细信息。
请求方式
GET
请求路径
/salesforce/metadata/retrieve/record/{asyncId}
权限要求
- 权限标识:
salesforce:metadata:retrieve
请求参数
路径参数
| 参数名 |
类型 |
必填 |
说明 |
示例 |
| asyncId |
String |
是 |
异步操作 ID |
"09Sxx0000000001EAA" |
请求示例
GET /salesforce/metadata/retrieve/record/09Sxx0000000001EAA
响应参数
成功响应(HTTP 200)
与"获取检索历史"接口中的单个对象结构相同。
成功响应示例
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 1,
"asyncId": "09Sxx0000000001EAA",
"status": "Succeeded",
"done": true,
"message": "Retrieve completed successfully",
"errorMessage": null,
"retrieveTime": "2026-02-06T10:30:00",
"updateTime": "2026-02-06T10:30:00",
"userId": 1,
"createBy": "admin",
"createTime": "2026-02-06T10:25:00"
}
}
记录不存在响应示例
{
"code": 200,
"msg": "操作成功",
"data": null
}
错误码
业务错误码
| 错误码 |
说明 |
处理建议 |
| RETRIEVE_001 |
获取 MetadataConnection 失败 |
检查 Salesforce 连接配置 |
| RETRIEVE_002 |
检索元数据操作失败 |
检查请求参数和 API 版本 |
| RETRIEVE_003 |
检索操作超时 |
增加超时时间或稍后重试 |
| RETRIEVE_004 |
检查检索状态失败 |
检查 asyncId 是否正确 |
| RETRIEVE_005 |
获取检索历史失败 |
检查数据库连接 |
| RETRIEVE_006 |
根据 asyncId 查询检索记录失败 |
检查 asyncId 是否正确 |
| RETRIEVE_007 |
请求参数不能为空 |
检查请求体是否为空 |
| RETRIEVE_008 |
API 版本不能为空 |
检查 apiVersion 字段 |
| RETRIEVE_009 |
未打包的元数据类型列表不能为空 |
检查 unpackaged.types 字段 |
| RETRIEVE_010 |
检索元数据失败 |
查看详细错误信息 |
HTTP 状态码
| 状态码 |
说明 |
| 200 |
请求成功 |
| 400 |
请求参数错误 |
| 401 |
未授权,需要登录 |
| 403 |
禁止访问,权限不足 |
| 500 |
服务器内部错误 |
使用流程
典型使用场景 1:简单检索并等待结果
1. 调用 POST /salesforce/metadata/retrieve 提交检索请求
2. 获取返回的 asyncId
3. 调用 GET /salesforce/metadata/retrieve/status/{asyncId} 轮询状态
4. 等待返回结果(包含 ZIP 文件 Base64 数据)
5. 前端解码 Base64 并下载 ZIP 文件
典型使用场景 2:前端主动轮询
1. 调用 POST /salesforce/metadata/retrieve 提交检索请求
2. 获取返回的 asyncId
3. 前端使用定时器,每隔 5 秒调用 GET /salesforce/metadata/retrieve/check/{asyncId}
4. 检查返回的 done 字段,为 true 时表示完成
5. 如果成功,获取 ZIP 文件数据;如果失败,显示错误信息
典型使用场景 3:查询历史记录
1. 调用 GET /salesforce/metadata/retrieve/history 获取检索历史列表
2. 用户选择某条历史记录
3. 调用 GET /salesforce/metadata/retrieve/record/{asyncId} 获取详细信息
4. 显示检索状态和结果
注意事项
1. 异步操作特性
- 检索操作是异步的,提交请求后立即返回 asyncId
- 需要使用 asyncId 轮询或查询状态
- 检索时间取决于元数据数量和复杂度,可能需要几秒到几分钟
2. ZIP 文件处理
- ZIP 文件内容以 Base64 编码返回
- 不在数据库中存储 ZIP 文件内容
- 对于大文件,建议设置合理的超时时间
3. 超时控制
- 轮询接口默认超时时间为 5 分钟
- 可以通过 timeout 参数调整超时时间
- 超时后会抛出异常,需要客户端处理
4. 权限控制
- 所有接口都需要
salesforce:metadata:retrieve 权限
- 使用 Spring Security 的
@PreAuthorize 注解控制
- 确保用户有权限访问目标 Salesforce 组织的元数据
相关文档