核心概念
本文档介绍 Lovrabet Java OpenSDK 的核心类和概念,帮助您深入理解 SDK 的工作原理。
1. SDK 客户端(LovrabetSDKClient)
LovrabetSDKClient 是 SDK 的核心类,封装了所有 OpenAPI 接口调用。
1.1 创建客户端
public LovrabetSDKClient(String accessKey, String baseUrl);
参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| accessKey | String | 是 | 访问密钥,在应用后台生成 |
| baseUrl | String | 是 | API 服务器地址:https://runtime.lovrabet.com/openapi |
示例:
String accessKey = "ak-OD8xWhMOsL5ChQ3Akhv4uYYiu1fPOFQGVF9BULIeov8";
String baseUrl = "https://runtime.lovrabet.com/openapi";
LovrabetSDKClient sdkClient = new LovrabetSDKClient(accessKey, baseUrl);
1.2 客户端特性
线程安全
LovrabetSDKClient 是线程安全的,可以在多线程环境中共享使用:
// 推荐:创建单例复用
public class SdkClientManager {
private static volatile LovrabetSDKClient instance;
public static LovrabetSDKClient getInstance() {
if (instance == null) {
synchronized (SdkClientManager.class) {
if (instance == null) {
instance = new LovrabetSDKClient(
ConfigManager.getAccessKey(),
ConfigManager.getBaseUrl()
);
}
}
}
return instance;
}
}
// 在应用中使用
LovrabetSDKClient client = SdkClientManager.getInstance();
自动认证
SDK 会自动处理所有请求的签名认证,您无需关心签名算法的实现细节:
// SDK 会自动完成:
// 1. 生成时间戳
// 2. 构建签名字符串
// 3. 计算 HMAC-SHA256 签名
// 4. 添加认证头到 HTTP 请求
LovrabetResult<?> result = sdkClient.getList(request); // 自动签名
2. 请求对象(LovrabetRequest)
LovrabetRequest 封装了 API 调用所需的参数。
2.1 类定义
public class LovrabetRequest {
private Long id; // 主键ID
private String appCode; // 应用编码(必填)
private String modelCode; // 数据集编码
private Map<String, Object> paramMap; // 业务参数
// Getters and Setters
}
2.2 字段说明
| 字段 | 类型 | 必填 | 使用场景 | 说明 |
|---|---|---|---|---|
| appCode | String | 是 | 所有接口 | 应用编码,在应用后台获取 |
| modelCode | String | 部分接口 | 数据操作接口 | 数据集编码,标识要操作的数据集 |
| id | Long | 部分接口 | getOne、update | 数据记录的主键 ID |
| paramMap | Map | 否 | 多种场景 | 分页参数、查询条件、数据字段等 |
2.3 使用示例
基础请求(仅 appCode)
用于获取数据集列表等应用级接口:
LovrabetRequest request = new LovrabetRequest();
request.setAppCode("app-c2dd52a2");
数据集操作请求
用于查询数据列表等数据集级接口:
LovrabetRequest request = new LovrabetRequest();
request.setAppCode("app-c2dd52a2");
request.setModelCode("b460abdbb0fb49e1865110d9dfbbc9b4");
// 添加分页参数
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("pageSize", 10);
paramMap.put("currentPage", 1);
request.setParamMap(paramMap);
单条数据操作请求
用于查询、更新特定记录:
LovrabetRequest request = new LovrabetRequest();
request.setAppCode("app-c2dd52a2");
request.setModelCode("32c036010c504757b80d438e3c0ec8b7");
request.setId(513L);
// 更新操作还需要设置要修改的字段
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("TEXT_1", "新的文本内容");
request.setParamMap(paramMap);
2.4 paramMap 使用指南
paramMap 是一个灵活的参数容器,支持多种用途:
用途 1:分页参数
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("currentPage", 1); // 当前页码,从 1 开始
paramMap.put("pageSize", 20); // 每页显示的记录数
用途 2:数据字段(创建/更新)
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("TEXT_1", "订单编号-001"); // 文本字段
paramMap.put("NUMBER_3", 100); // 数字字段
paramMap.put("DATETIME_1", System.currentTimeMillis()); // 时间戳
paramMap.put("SELECT_4", "china-north"); // 选择字段
用途 3:查询条件(如果 API 支持)
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("status", "active"); // 根据状态筛选
paramMap.put("category", "product"); // 根据分类筛选
3. 响应对象(LovrabetResult)
LovrabetResult<T> 是所有 API 接口的统一响应对象。
3.1 类定义
public class LovrabetResult<T> {
private boolean success; // 执行是否成功
private String resultCode; // 结果代码
private String resultMsg; // 结果消息
private T data; // 返回数据
private LovrabetPage page; // 分页信息(部分接口)
private List<LovrabetField> fieldList; // 字段列表(部分接口)
// Getters and Setters
}
3.2 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| success | boolean | 请求是否成功,true 表示成功,false 表示失败 |
| resultCode | String | 结果代码,成功时为 "0000",失败时为具体错误码 |
| resultMsg | String | 结果消息,失败时包含错误详情 |
| data | T | 返回的业务数据,类型根据接口不同而不同 |
| page | LovrabetPage | 分页信息(仅分页查询接口返回) |
| fieldList | List | 字段列表(某些接口返回) |
3.3 处理响应的标准模式
模式 1:基础判断
LovrabetResult<?> result = sdkClient.someMethod(request);
if (result.isSuccess()) {
// 成功:处理业务数据
Object data = result.getData();
System.out.println("操作成功: " + data);
} else {
// 失败:处理错误信息
System.err.println("操作失败 [" + result.getResultCode() + "]: " + result.getResultMsg());
}
模式 2:类型安全处理
// 获取单条数据
LovrabetResult<?> result = sdkClient.getOne(request);
if (result.isSuccess()) {
Map<String, Object> data = (Map<String, Object>) result.getData();
// 访问具体字段
String text = (String) data.get("TEXT_1");
Integer number = (Integer) data.get("NUMBER_3");
System.out.println("文本字段: " + text);
System.out.println("数字字段: " + number);
}
模式 3:列表数据处理
// 获取列表数据
LovrabetResult<?> result = sdkClient.getList(request);
if (result.isSuccess()) {
List<Map<String, Object>> dataList = (List<Map<String, Object>>) result.getData();
System.out.println("数据量: " + dataList.size());
// 遍历处理
for (Map<String, Object> record : dataList) {
System.out.println("记录: " + record);
}
}
模式 4:带重试的错误处理
int maxRetries = 3;
int retryCount = 0;
LovrabetResult<?> result = null;
while (retryCount < maxRetries) {
result = sdkClient.getOne(request);
if (result.isSuccess()) {
// 成功,跳出循环
break;
} else {
retryCount++;
System.err.println("尝试 " + retryCount + " 失败: " + result.getResultMsg());
if (retryCount < maxRetries) {
try {
Thread.sleep(1000); // 等待 1 秒后重试
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
// 最终处理
if (result != null && result.isSuccess()) {
System.out.println("数据: " + result.getData());
} else {
System.err.println("多次重试后仍然失败");
}
4. 认证机制
SDK 使用 HMAC-SHA256 签名算法进行认证,确保请求的安全性和完整性。
4.1 签名流程(SDK 自动完成)
虽然 SDK 会自动处理签名,但了解签名流程有助于您排查问题:
步骤 1:收集签名参数
SDK 会收集以下参数(按字典序排序):
accessKey: 访问密钥timeStamp: 时间戳(毫秒)appCode: 应用编码datasetCode: 数据集编码
步骤 2:构建签名字符串
accessKey=ak-xxx&appCode=app-xxx&datasetCode=xxx&timeStamp=1234567890
步骤 3:计算 HMAC-SHA256 签名
使用固定的密钥对签名字符串进行 HMAC-SHA256 加密,然后 Base64 编码。
步骤 4:添加到请求头
SDK 会自动将以下信息添加到 HTTP 请求头:
X-Time-Stamp: 时间戳X-App-Code: 应用编码X-Dataset-Code: 数据集编码X-Token: 生成的签名
4.2 安全最佳实践
✅ 正确做法
// 1. 使用环境变量
String accessKey = System.getenv("LOVRABET_ACCESS_KEY");
// 2. 使用配置文件
@Value("${lovrabet.accessKey}")
private String accessKey;
// 3. 使用密钥管理服务
String accessKey = secretManager.getSecret("lovrabet-access-key");
❌ 错误做法
// ❌ 不要硬编码在代码中
String accessKey = "ak-OD8xWhMOsL5ChQ3Akhv4uYYiu1fPOFQGVF9BULIeov8";
// ❌ 不要提交到代码仓库
// git add config.properties (包含 accessKey)
// ❌ 不要在日志中打印
logger.info("AccessKey: " + accessKey); // 危险!
4.3 常见认证问题
问题 1: "Token 无效"
原因:
- AccessKey 不正确
- 系统时间与服务器时间相差超过 10 分钟
解决方案:
// 检查系统时间
System.out.println("当前时间戳: " + System.currentTimeMillis());
// 确认 AccessKey
System.out.println("AccessKey 前 10 位: " + accessKey.substring(0, 10));
问题 2: "AccessKey 不存在或已失效"
解决方案:
- 登录 Lovrabet 云兔平台
- 检查 AccessKey 是否已生成且未过期
- 确认 OpenAPI 功能已开通
- 如需要,重新生成 AccessKey
5. 完整的请求-响应流程
下图展示了一次完整的 API 调用流程:
┌─────────────────┐
│ 创建 Request │
│ 设置参数 │
└────────┬────────┘
│
▼
┌─────────────────┐
│ SDK 自动签名 │ ← 自动添加时间戳、计算签名
└────────┬────────┘
│
▼
┌─────────────────┐
│ 发送 HTTP 请求 │ ← 携带签名头
└────────┬────────┘
│
▼
┌─────────────────┐
│ 服务器验证签名 │
└────────┬────────┘
│
▼
┌─────────────────┐
│ 处理业务逻辑 │
└────────┬────────┘
│
▼
┌─────────────────┐
│ 返回 Result │ ← 包含 success、data 等
└────────┬────────┘
│
▼
┌─────────────────┐
│ 应用处理结果 │ ← if (result.isSuccess()) { ... }
└─────────────────┘
示例代码
// 1. 创建 Request
LovrabetRequest request = new LovrabetRequest();
request.setAppCode("app-c2dd52a2");
request.setModelCode("32c036010c504757b80d438e3c0ec8b7");
request.setId(513L);
// 2-4. SDK 自动完成签名、发送、验证
// 5. 服务器处理并返回 Result
LovrabetResult<?> result = sdkClient.getOne(request);
// 6. 应用处理结果
if (result.isSuccess()) {
Map<String, Object> data = (Map<String, Object>) result.getData();
System.out.println("查询成功: " + data);
} else {
System.err.println("查询失败: " + result.getResultMsg());
}
下一步
现在您已经理解了 SDK 的核心概念,建议按以下顺序继续学习:
-
📖 快速开始 5 分钟完成第一个 CRUD 程序
-
📚 核心概念 ← 当前位置 深入理解 SDK 工作原理
-
📋 API 参考 ← 推荐下一步 查阅完整的接口文档
-
💡 业务示例 学习 5 个真实场景的实现
-
🚀 最佳实践 掌握生产环境优化技巧
-
❓ 常见问题 解决使用中的疑问
需要帮助? 访问 常见问题 或联系 service@lovrabet.com