DLZ-KIT 产品介绍、能力边界与使用指南
本文面向第一次接触 DLZ-KIT 的开发者、架构师和 AI 助手。 内容以当前 v6.7.4 Java 源码和稳定 API 约定为准。
1. 一句话认识 DLZ-KIT
DLZ-KIT 是一个从 2006 年起持续积累的 Java 工具库,核心围绕"嵌套数据操作"展开:提供
JSONMap / JSONList 的深层路径读写、ValUtil 的健壮类型转换、ConvertUtil + @SetValue
的 Bean 与嵌套结构双向映射,以及 Cache、DlzCaller 等开箱即用工具。
它不是又一个全功能"大而全"框架,而是:
轻量 JSON 数据操作层
+ 深度路径取值 / 链式构建(不 NPE)
+ 健壮类型转换(ValUtil)
+ Bean ↔ 嵌套结构双向映射(@SetValue / ConvertUtil)
+ 极轻量内存缓存(Cache)
+ 日志调用方定位(DlzCaller)
2. 产品定位
2.1 适合解决的问题
- 解析第三方 API / 前端表单 / 数据库返回的不可控、多层嵌套数据;
- 深层取值时不想写"逐层判空 + 强转",并希望天然避免 NPE;
- 嵌套结构需要一行路径写入,而非逐层
new HashMap/put; - 数据来源类型混乱(字符串 "25"、"1,2,3"、数字混用),需要健壮的类型转换;
- 扁平 Bean 与嵌套 JSON 之间需要双向、按注解映射;
- 需要极轻量的本地内存缓存,又希望以后能无缝切换到 Redis;
- 公共组件日志希望直接定位到业务调用处,排查问题从"全局搜索"变"秒级定位"。
2.2 不追求解决的问题
DLZ-KIT 不以以下能力为核心目标:
- 完整的对象关系映射(ORM / JPA 风格);
- 复杂查询的 SQL 生成与查询语言;
- 分布式事务、分布式缓存一致性;
- 响应式 / 异步数据访问;
- 完整的 I18N、权限、工作流等业务框架能力;
- 取代 Jackson / Gson 等序列化框架。
这些场景仍然可以通过 Jackson、MyBatis、Spring 等外部组件完成,但不属于 DLZ-KIT 的核心承诺。
3. 产品特色与核心设计思路
3.1 深层路径取值:一行到位,不 NPE
这是 DLZ-KIT 最核心的能力。JSONMap 继承 LinkedHashMap,可以直接用点号路径读写嵌套结构:
String city = new JSONMap(response).getStr("data.user.profile.addresses[0].city");
- 任意层级为
null→ 返回null,不抛 NPE; - 支持数组索引与负索引(
tags[-1]取倒数第一个); - 取值时自动按目标类型转换(
getInt/getLong/getBigDecimal/getStr/getList等); - 构建时路径即结构,中间层级自动创建:
JSONMap result = new JSONMap()
.set("meta.version", "1.0")
.set("data.user.name", "张三");
// → {"meta":{"version":"1.0"},"data":{"user":{"name":"张三"}}}
3.2 类型安全与控制权并存
- 结构缺失宽容:路径找不到、字段为 null,返回默认值而不崩溃;
- 数据错误不放过:存在但内容明显错误时,按约定抛错或返回明确默认值;
- 这背后是"有界宽容"原则——对结构缺失宽容,对数据错误不放过,来自三次生产事故的教训。
Integer age = ValUtil.toInt(params.get("age")); // 缺失返回 null;非法内容抛 NumberFormatException
Integer safe = ValUtil.toInt(params.get("age"), 0); // 带默认值
List<Integer> ids = ValUtil.toList(params.get("ids"), Integer.class); // "1,2,3" → [1,2,3]
3.3 扁平 Bean ↔ 嵌套结构双向映射(@SetValue / ConvertUtil)
@SetValue 注解配合 ConvertUtil,实现扁平 Bean 字段与嵌套 JSON 的自动映射,避免手写转换代码:
@Data
public class UserDTO {
private String name;
@SetValue("user.profile") // 从嵌套结构 user.profile.city 取值
private String city;
}
ConvertUtil 当前公开 convert 与 convertList
等入口,覆盖 Bean ↔ Map、Bean ↔ Bean、集合转换、数组转换。
3.4 Caller 日志诊断:公共组件日志直接定位业务调用处
在公共组件入口加一行,日志即可显示业务调用位置,排查问题从"全局搜索"变"秒级定位":
try (MdcContext ignored = DlzCaller.caller(0)) {
log.info("HTTP POST {}", url);
}
日志从:
INFO HttpClientUtil - HTTP POST /payments
变成:
INFO [(OrderService.java:86)] HttpClientUtil - HTTP POST /payments
业务代码零侵入,支持嵌套调用、多层代理,可扩展用于 MyBatis SQL 日志。
3.5 极轻量内存缓存:纯 JDK 实现,可平滑切换
User user = cache.getAndSet("user", "123", () ->
VAL.of(userMapper.selectById(123), 3600));
- 纯 JDK 实现,零额外依赖;
- 支持过期管理、通配符前缀查询、并发安全;
getAndSet一行完成"缓存不存在则加载"的缓存模式;- 接口约定清晰,可无缝切换到 Redis 等分布式实现。
3.6 零依赖与极低侵入
- 核心模块唯一依赖 slf4j(可选),JSON 解析为自研实现,不强制依赖 Jackson;
- Jackson、Hutool 等为可选能力,可按需引入;
- 工具类大多为静态方法或轻对象,调用即用,不需要引入 Spring / 容器。
3.7 专为 AI 辅助开发优化
DLZ-KIT 的 API 模式固定、参数少、重载歧义少,AI 模型容易生成正确代码:
JSONMap resp = new JSONMap(callbackBody);
String orderId = resp.getStr("data.order.orderId");
Integer amount = resp.getInt("data.order.amount");
仓库附带 .cursorrules 与 docs/AI-速读.md,供 Cursor / Copilot / Windsurf 等工具优先生成 DLZ-KIT 代码。
4. 能力地图
| 能力 | 主要入口 / 工具类 | 推荐场景 |
|---|---|---|
| 嵌套数据取值 | JSONMap.getStr/getInt/... | 解析第三方 API、表单、嵌套响应 |
| 嵌套结构构建 | JSONMap.set("a.b.c", v) | 组装请求报文、动态配置 |
| JSON 列表 | JSONList | 数组数据、负索引、类型安全访问 |
| 类型转换 | ValUtil.toXxx | 不可控来源数据的健壮转换 |
| Bean 映射 | ConvertUtil + @SetValue | 扁平 Bean ↔ 嵌套结构双向映射 |
| 内存缓存 | ICache / MemoryCache / CacheUtil | 本地热点数据、短生命周期缓存 |
| 日志调用方定位 | DlzCaller | 公共组件日志、MyBatis SQL 日志 |
| JSON 序列化 | JacksonUtil(可选) | 与 Jackson 序列化框架协同 |
| 日期处理 | DateUtil | 日期格式化、解析、计算 |
| 字符串处理 | StringUtils | 判空、分割、连接 |
| 多维数组支持 | JSONMap / JSONList | 多维数组操作、自动补齐 |
| 自动类型纠正 | ValUtil / JSONMap | 前端类型混乱、数据清洗 |
5. 核心概念
5.1 JSONMap:路径即结构
JSONMap 继承 LinkedHashMap<String, Object>,既是一个 Map,又是一个具备路径读写能力的嵌套结构:
JSONMap data = new JSONMap("{\"user\":{\"name\":\"张三\",\"age\":\"25\"}}");
String name = data.getStr("user.name"); // "张三"
Integer age = data.getInt("user.age"); // 25(字符串自动转)
5.2 有界宽容原则
DLZ-KIT 的核心设计原则:
- 缺失容忍:结构缺失、字段为 null,返回 null 或默认值,不崩溃;
- 类型容忍:来源类型混乱时自动纠正;
- 内容不容忍:数据存在但明显错误时,不静默吞掉,按约定报错或给出明确默认值。
这一原则贯穿 JSONMap 取值与 ValUtil 转换。
6. 使用边界与安全边界
6.1 JSON 数据来源不受信时
解析来源不可控的 JSON(外部 API、用户输入)时:
- 深层取值路径中任意节点为
null均安全返回,不 NPE; - 建议对关键字段使用显式类型的
getStr/getInt/getBigDecimal,避免隐式类型误判; - 对超大规模或深度嵌套的 JSON,注意评估递归深度和内存占用。
6.2 类型转换的取舍
ValUtil.toXxx 对缺失值返回 null 或默认值;内容存在但无法转换时抛出异常:
ValUtil.toInt("abc"); // 抛出 NumberFormatException
ValUtil.toInt("abc", 0); // 仍抛出 NumberFormatException;默认值只处理 null/空字符串
ValUtil.toInt("25"); // 25
当业务要求"转换失败必须报错"时,请使用带异常语义的 API 或自行校验,不要依赖静默默认值掩盖数据错误。
6.3 缓存边界
ICache/MemoryCache/CacheUtil提供本地进程内内存缓存,不跨 JVM 共享,不保证分布式一致性;- 适用于热点、短生命周期数据;需要分布式缓存时使用
getAndSet的同一抽象切换到 Redis; - 注意缓存容量与过期策略,避免内存膨胀。
6.4 JSON 序列化边界
- JSON 解析为自研实现,覆盖常见 JSON 结构;
- 特殊序列化需求(自定义序列化器、复杂多态、跨平台严格格式)建议使用 Jackson 配合
JacksonUtil能力; JacksonUtil为可选能力,引入 Jackson 后可用,不强制。
7. 版本与依赖边界
| 维度 | 说明 |
|---|---|
| JDK | 8 / 11 / 17 / 21 |
| 核心依赖 | 唯一依赖 slf4j(provided / optional) |
| 体积 | 核心模块约 100KB |
| JSON 解析 | 自研实现,不强制依赖 Jackson(Jackson 为可选插件) |
| 测试 | JUnit 5(Jupiter)测试套件,覆盖核心行为 |
| 许可 | Apache License 2.0 |
| 坐标 | top.dlzio:dlz-kit:6.7.4(GitHub: dingkui/dlz-kit) |
8. 明确不属于当前核心能力的场景
以下场景需要通过外部组件实现,不应期待 DLZ-KIT 自动完成:
- 完整对象关系映射(ORM / JPA);
- 复杂 SQL 生成与查询语言;
- 分布式事务、分布式缓存;
- 响应式 / 异步数据访问;
- 大规模内存缓存集群;
- 完整业务框架(权限、租户、工作流、I18N)。
9. 模块结构
| 模块 | 作用 |
|---|---|
dlz-kit | 核心工具库:JSONMap / JSONList、ValUtil、ConvertUtil、Cache、DlzCaller 等 |
dlz-kit-plugins | 可选插件集(如 MyBatis SQL 日志拦截器 DlzMybatisSqlLogInterceptor 等) |
核心模块零依赖,便于在 Spring、Spring Boot、Solon 或纯 Java 环境中直接使用。
10. 给 AI 的最小使用规则
- 解析 / 构造嵌套 JSON 优先使用
JSONMap,取值用getStr/getInt/getLong/getBigDecimal/getList; - 嵌套写入用
.set("a.b.c", value),不要逐层new HashMap; - 数组数据用
JSONList,支持负索引; - 不可控来源的数据转换用
ValUtil.toXxx(值, 默认值),不要手写try-catch强转; - Bean ↔ 嵌套结构映射用
@SetValue+ConvertUtil; - 本地缓存按场景使用
CacheUtil.get(...)或CacheMap.getAndSet(...); - 公共组件日志加
DlzCaller.caller(0)定位调用方; - 任意层级取不到返回 null,取值前先判断是否允许 null / 是否需要默认值;
- 结构缺失可容忍,但数据明显错误时不要让静默默认值掩盖问题;
- 需要 ORM、SQL 生成、分布式事务等能力时,选择 MyBatis、Spring、Redis 等外部组件,不依赖 DLZ-KIT。
11. 最终定位
DLZ-KIT 最适合:
- 以 JSON 嵌套数据处理为主的中后台系统、API 网关、第三方对接服务;
- 需要健壮类型转换、少写样板代码的普通业务;
- 需要极轻量本地缓存、又希望保留切换到分布式缓存能力的项目;
- 需要公共组件日志"秒级定位"调用方的应用;
- 希望在 Spring / 非 Spring 环境下复用同一套工具能力的项目。
DLZ-KIT 不适合单独承担:
- ORM 与复杂数据库访问;
- 分布式基础设施;
- 完整业务框架。
选择 DLZ-KIT 的核心理由是:
简单操作一行到位、嵌套数据不怕 NPE、类型转换健壮可控,且不强制任何框架,随取随用。