跳转到正文

Constant 重点文件与方法

重点展开响应与异常、Hook 组织、集合处理、Base64 文件转换和图片压缩。其他工具按场景查阅通用工具脱敏与编码;各页中的源码链接可定位实际文件。

本页按重点文件查阅方法;表内方法名可打开源码。重载共享的约束写在表前,差异在各行说明。源码链接固定到核对版本,接入前提见快速开始

ResponseMessage

源码:ResponseMessage

不可变消息字段容器;不是 enum 或 record。Lombok 提供三参数构造器与 toString,没有按字段生成 equals/hashCode。

方法 / 重载用途、参数与返回值注意事项
ResponseMessage(String code, String message)设置业务码、消息,description 默认等于 message。没有非空或码唯一性校验。
code()返回 String 业务码。用于应用协议,不是 HTTP 状态。
message()返回消息模板字符串。可能包含 String.format 占位符,不自动插值。
description()返回消息说明字符串。三参数构造可与 message 区分;不参与异常格式化。

生成的 ResponseMessage(String code, String message, String description) 一次设置三个字段,适合错误码目录;构造后字段不可替换。

BusinessException

源码:BusinessException

携带 code、message 和可选 error 的 RuntimeException。Lombok 生成 getCode/getMessage/getError;错误消息覆盖发生在构造时,不影响已经创建的异常。

方法 / 重载用途、参数与返回值注意事项
BusinessException(String message)默认使用 E0001,再查询消息覆盖。适合单次业务错误;同码覆盖可能替换传入消息。
BusinessException(String code, String message)按 code 查覆盖文案,不格式化。业务码需由应用统一管理。
BusinessException(String code, String message, Object... args)取得最终模板后调用 String.format。参数数量/类型须匹配覆盖后的模板。
BusinessException(ResponseMessage responseCode)按消息对象的 code 查整对象覆盖。覆盖对象中的 code 也会成为异常码,保持 key/code 一致。
BusinessException(ResponseMessage responseCode, Object... args)对覆盖后的消息执行格式化。responseCode 不能 null;格式异常可能先于业务异常抛出。
withThrowable(Throwable error)保存自定义 error 字段,返回当前异常,可链式 throw。不调用 initCause;标准 getCause() 不会得到这里设置的异常。

ResponseMessageCacheUtil

源码:ResponseMessageCacheUtil

静态进程内 HashMap,没有 TTL 或并发保护。适合初始化时注册后只读,不用作多实例动态配置中心。

方法 / 重载用途、参数与返回值注意事项
get(String code, String message)命中时返回覆盖消息文本,否则返回传入 message。已存入 null 对象时可能 NPE。
get(ResponseMessage response)按 response.code 查覆盖对象,缺失返回原对象。返回引用,不复制;response 不能 null。
update(String code, ResponseMessage response)新增/替换该 code 对应的对象,返回 void。不会改变已经生成的异常;避免并发修改和 null。
delete(String code)删除覆盖,之后恢复使用调用者提供的默认消息。不删除 ResponseMessageResolveUtil 的目录记录。

ResponseMessageResolveUtil

源码:ResponseMessageResolveUtil

反射收集错误码目录,与文案覆盖是两套独立集合。仅扫描类自身字段,字段应为非 null、可访问的 public static ResponseMessage。

方法 / 重载用途、参数与返回值注意事项
resolve(String moduleName, Class<?> clazz)读取声明字段并写模块列表、全量列表和按码索引。不递归嵌套类/继承字段;重复调用追加全量列表,重复码最后写入者生效;访问失败会静默终止。
listByModule(String moduleName)返回模块最新一次解析的列表,未知模块空列表。命中时是内部可变引用,不要修改。
list()返回累计全量列表。未去重且为内部引用。
getByCode(String code)返回最后收集到的消息对象,未知 null。不会查询文案覆盖缓存。

调用例子及异常输出见响应与 Hook。构造业务异常后要 throw 才会中止流程,创建对象本身不产生 HTTP 响应。

AbstractBusinessListHook

源码:AbstractBusinessListHook

构造时按 sequence 升序排列全部 Hook。 构造参数列表与元素均非 null;基类只组织 Hook,不自动调用业务方法。

方法 / 重载用途、参数与返回值注意事项
AbstractBusinessListHook(List<HOOK> hookList)构造时按 sequence 升序排列全部 Hook。保留同序号输入顺序;列表不可修改,Hook 本身仍可能可变。
getHookList()protected final 访问器,供子类调度已整理的 Hook。返回不可修改的容器;查未知类型仍可能 null。
name()由子类返回用于加载日志的名称。父类构造期间就可能调用,不依赖尚未初始化的子类字段。

AbstractBusinessGroupHook

源码:AbstractBusinessGroupHook

同时收集 Hook.type 和 Hook.types,按类型分组、去重、排序。 构造参数列表与元素均非 null;基类只组织 Hook,不自动调用业务方法。

方法 / 重载用途、参数与返回值注意事项
AbstractBusinessGroupHook(List<HOOK> hookList)同时收集 Hook.type 和 Hook.types,按类型分组、去重、排序。去重使用 equals/hashCode;相同 sequence 的组内顺序不稳定。
getHookGroupMap()protected final 访问器,供子类调度已整理的 Hook。返回不可修改的容器;查未知类型仍可能 null。

AbstractBusinessMapHook

源码:AbstractBusinessMapHook

从分组结果取每种类型排序后的首项。 构造参数列表与元素均非 null;基类只组织 Hook,不自动调用业务方法。

方法 / 重载用途、参数与返回值注意事项
AbstractBusinessMapHook(List<HOOK> hookList)从分组结果取每种类型排序后的首项。重复类型只记录错误,不拒绝启动;需要唯一性时调用方主动验证。
getHookMap()protected final 访问器,供子类调度已整理的 Hook。返回不可修改的容器;查未知类型仍可能 null。

AbstractBusinessGroupHookAbstractBusinessMapHook 继承 name() 及前一级访问器。扩展示例与 sequence/type/types 的完整契约见组织扩展 Hook

ListUtil

源码:ListUtil

通用集合工具及 Sort、Spilt、Random、Tree、Calc 嵌套工具均在同一文件。下面按嵌套类列出全部对外方法;回调参数代表字段 getter、setter 或转换函数,使用前确保集合元素符合其输入要求。

方法 / 重载用途、参数与返回值注意事项
distinct(List<T> list)按 equals/hashCode 去重,保留首项顺序,返回新 ArrayList。null/空列表返回空;保留一个 null 元素。
distinct(List<T> list, Function<? super T,Object> keyExtractor)按提取键去重,保留每个键的首项。提取器处理 null 元素的责任在调用方;不修改原列表。
retain(List<List<T>> list)求所有列表交集;无有效交集时 Optional.empty。任一子列表 null/空也返回 empty;结果按首列表顺序去重。
listNonValueIndex(List<T> list, Function<T,String> fun)返回提取字符串非空白的元素下标列表,下标从 0 开始。名称容易误读:实际选择“有值”的下标。
groupList(List<T> list, int length)按正 length 返回分组视图,空输入返回空列表。分组引用原列表,修改原列表影响结果。
groupList(List<T> list, int length, Function<List<T>,V> fun)返回惰性转换分组,每次 get(index) 时才调用 fun。仅调用此方法不会执行回调;重复遍历会重复执行,不能当 eager forEach 使用。

Sort:排序与序号

以下方法均为 ListUtil.Sort 的 static 方法;空列表不处理。

方法 / 重载用途、参数与返回值注意事项
Sort.sort(List<T> list, List<R> keyList, Function<T,R> extractor)按 keyList 顺序重排原 list,未匹配元素排末尾。原 list 必须可修改;keyList 重复键只处理一次。
Sort.setSortOrder(List<T> list, BiConsumer<T,Integer> set)按当前列表顺序从 0 写序号。修改元素,不改变 list 顺序。
Sort.setSortOrder(List<T> list, BiConsumer<T,Integer> set, int start)从 start 开始逐项写序号。不替调用方检查序号溢出。
Sort.collate(List<T> list, Comparator<T> comparator, BiConsumer<T,Integer> set)按 comparator 排序的临时视图从 0 写序号。不会重排原 list,仅写元素的序号字段。
Sort.collate(List<T> list, Comparator<T> comparator, BiConsumer<T,Integer> set, int start)同上,从 start 写序号。需要实际展示排序时另行排序原列表。
Sort.removeRepeatCollate(List<T> list, Function<T,Number> get, Function<T,Integer> getOrder, BiConsumer<T,Integer> set)按旧序号排序后,让相邻且 Number.equals 相同的元素共用序号。不是删除重复元素,也不将不同 Number 类型按数值归并。

Spilt:拆分与转换

类名在源码中拼作 Spilt。separate 是 Java 正则,默认逗号;to 系列过滤空白片段,但不统一 trim 非空白片段。

方法 / 重载用途、参数与返回值注意事项
Spilt.str(String str, int splitLen)按 UTF-16 字符数每 splitLen 个切一段,返回字符串列表。splitLen 必须 >0,先校验再处理空输入;可能切开代理对。
Spilt.to(String content)按逗号拆分并返回字符串列表。空白输入返回空列表。
Spilt.to(String content, String separate)按指定正则拆分。字面点号等需转义,不能把 separate 当普通字符串。
Spilt.to(String content, Function<String,T> function)按逗号拆分后转换每段。转换异常传播。
Spilt.to(String content, String separate, Function<String,T> function)指定分隔正则和转换回调。非空结果由 Stream.toList 产生,不支持结构修改。
Spilt.toInteger(String content)逗号分割后转 Integer。非法数字会转换失败。
Spilt.toInteger(String content, String separate)指定正则,逐段转 Integer。不要传超出 Integer 范围的数字。
Spilt.toLong(String content)逗号分割后转 Long。非法格式失败,不忽略坏元素。
Spilt.toLong(String content, String separate)指定正则,逐段转 Long。空输入返回空列表。

Random:抽样与拆数

方法 / 重载用途、参数与返回值注意事项
Random.random(List<T> list, int number)随机取 number 项,返回新列表;输入不足时直接复制全部。不会按值去重;非正 number 返回空,不用于安全随机。
Random.random(List<T> list, Function<T,R> extractor, int number)默认按字段降序,约 60% 优先项加 40% 随机项后打乱。不是完全均匀抽样。
Random.random(List<T> list, Function<T,R> extractor, int number, boolean desc)显式决定排序方向的优先抽样。字段应可比较且非 null;number 达到总量时直接复制,不重排。
Random.generateList(int total, int count)将正 total 随机拆成 count 份,默认补足总数。total<count 或参数非正返回空。
Random.generateList(int total, int count, boolean isReplenish)决定最后一份是否取全部余额。false 时总和可小于 total;count=1 仍返回 total。

Tree:组树、遍历标记

childKey 返回的子列表必须已初始化且可修改。组树会修改原节点;重复调用前清空旧 children。全部递归方法都不检测环,自引用/环形父子关系可能造成无限递归。

方法 / 重载用途、参数与返回值注意事项
Tree.build(List<TREE_VO> list, Function<TREE_VO,KEY_TYPE> idKey, Function<TREE_VO,KEY_TYPE> fkIdKey, Function<TREE_VO,List<TREE_VO>> childKey)按父 ID 组树;父 ID 为 null 或父不在输入中的节点作为根。重复 ID 的父节点映射保留首项,不是数据完整性检查。
Tree.build(List<TREE_VO> list, Function<TREE_VO,KEY_TYPE> idKey, Function<TREE_VO,KEY_TYPE> fkIdKey, Function<TREE_VO,List<TREE_VO>> childKey, KEY_TYPE rootKey)组树后返回自身 ID 等于 rootKey 的节点。rootKey 不是“父 ID 等于该值”的筛选。
Tree.build(List<TREE_VO> list, Function<TREE_VO,KEY_TYPE> idKey, Function<TREE_VO,KEY_TYPE> fkIdKey, Function<TREE_VO,List<TREE_VO>> childKey, Function<TREE_VO,Integer> levelKey)以输入最小层级为根组树。levelKey 返回 null 可能比较失败。
Tree.build(List<TREE_VO> list, Function<TREE_VO,KEY_TYPE> idKey, Function<TREE_VO,KEY_TYPE> fkIdKey, Function<TREE_VO,List<TREE_VO>> childKey, Function<TREE_VO,Integer> levelKey, Integer rootLevel)使用显式 rootLevel,非根层才向父节点追加。只返回指定层级节点;孤儿未必出现在结果中。
Tree.level(List<T> list, Function<T,List<T>> childKey, BiConsumer<T,Integer> levelKey)从根 1 开始递归写层级。不改变节点父 ID。
Tree.level(List<T> list, Function<T,List<T>> childKey, BiConsumer<T,Integer> levelKey, int level)以指定层级为起点递归写入。修改元素,不返回新树。
Tree.leaf(List<T> list, Function<T,List<T>> childKey, BiConsumer<T,Boolean> setLeafKey)将所有后代标 true,但不设置传入的顶层节点。名字不代表“只标叶子”;内部节点也会 true。
Tree.leafLast(List<T> list, Function<T,List<T>> childKey, BiConsumer<T,Boolean> setLeafKey)仅无子节点者标 true。不会把已有 true 的非叶子重置为 false。
Tree.chain(List<T> list, Function<T,List<T>> childKey, BiConsumer<T,List<String>> setChainKey, Function<T,String> chainContentKey)为后代写祖先内容链,不含自身。根节点不设置;空白链内容影响后续祖先链。
Tree.getByParentId(List<TREE_VO> list, KEY_TYPE parentId, Function<TREE_VO,KEY_TYPE> idKey, Function<TREE_VO,List<TREE_VO>> childKey)深度优先寻找自身 ID 等于 parentId 的首节点,未找到 null。名称虽含 ParentId,比较的是节点自己的 ID。

Calc:累计与逐项计算

方法 / 重载用途、参数与返回值注意事项
Calc.accumulateForInteger(List<Integer> list)返回整数前缀和列表。null/空返回空;整数溢出不检查。
Calc.accumulateForLong(List<Long> list)返回 long 前缀和列表。元素 null 会失败,long 溢出不检查。
Calc.accumulate(List<T> list, Supplier<T> initValue, BiFunction<T,T,T> accumulateFunction)从初始值依次累计并记录每一步结果。单元素输入直接返回该元素,不执行初始值或累计函数。
Calc.addForInteger(List<Integer> list, Integer addValue)每个 Integer 加上 addValue,返回新列表。原元素不变,不是求总和。
Calc.add(List<T> list, BiFunction<T,T,T> function, T addValue)对每个元素执行 function(element, addValue)。回调可能修改可变元素;集合新建不保证深拷贝。

分组回调的执行时机可用下面的完整片段观察,放入 main 方法,import 为 java.util.Listcom.own.constant.util.list.ListUtil

java
var batches = ListUtil.groupList(List.of(1, 2, 3), 2, group -> {
    System.out.println(group);
    return group.size();
}); // 此处还没有输出
for (Integer size : batches) {
    System.out.println("size=" + size);
} // 输出 [1, 2] / size=2 / [3] / size=1

私有 CustomPartition.get(index) 才执行分组函数,size() 仅向上取整计算组数;因此不要忽略分组返回值来执行数据库写入。相关影响见 MapperUtil

FileBase64Util

源码:FileBase64Util

将文件或网络内容转换成 Base64,解码支持 MIME Base64 及 data: 前缀。输出整串驻留内存;结果不携带原文件名或媒体类型。

方法 / 重载用途、参数与返回值注意事项
toBase64(String path)识别 HTTP URL,否则按本地路径读取;空白返回空串。会访问真实网络/磁盘,路径应来自受控来源。
urlToBase64(String url)HTTP GET,默认请求超时 5 秒。只接受 HTTP URL;非 2xx、读取失败返回空串。
urlToBase64(String url, Duration timeout)指定单次请求超时,非法时回退 5 秒。连接超时仍为客户端固定 5 秒;中断恢复标记后返回空串。
pathToBase64(String path)去除路径前后空白后读取本地文件。路径非法或读失败返回空串。
fileToBase64(File file)以 File 读取并编码。null 返回空串;读取流由工具关闭。
fileToBase64(Path path)以 Path 读取并编码。失败返回空串,不能区分空文件和失败。
inputStreamToBase64(InputStream inputStream)读取输入流剩余内容并编码。不负责关闭传入流;调用方管理资源。
base64ToInputStream(String base64)解码为内存输入流。空/非法/零字节内容返回空输入流,不抛格式异常。
base64ToFile(String base64)解码到新临时 .tmp 文件,返回 File。失败或零字节返回 null;调用方负责删除成功创建的临时文件。

ImageCompressorUtil

源码:ImageCompressorUtil

读整张图片后调整尺寸与编码,返回输出 File。质量/大小搜索次数有界;无法达到大小上限会失败,不返回超限文件假装成功。IO/参数错误包装为 BusinessSimpleException,自定义 error 保存原异常。

方法 / 重载用途、参数与返回值注意事项
compress(File sourceFile)默认 Options 输出新临时文件。调用方负责清理临时输出;不是原地压缩。
compress(File sourceFile, Options options)用指定选项输出新临时文件;options=null 采用默认。源文件必须可读且 ImageIO 支持。
compress(File sourceFile, File targetFile)默认 Options 写指定路径,返回 targetFile。会覆盖目标并创建父目录;同路径会覆盖源文件。
compress(File sourceFile, File targetFile, Options options)按选项限制尺寸、质量、字节数并写目标。动画/元数据不保证保留;JPEG/BMP 透明像素转白底。
Options.defaults()尺寸/大小不限制、quality=0.85、不放大、BALANCED。默认不保证文件变小。
Options.maxDimension(int maxWidth, int maxHeight)从默认选项设置最大宽高。保持宽高比,0 表示该方向不限制,负数非法。
Options.maxSize(long maxSizeBytes)从默认选项设置输出字节上限。0 表示不限制;为达上限可能进一步缩小尺寸。
Options.withMaxDimension(int maxWidth, int maxHeight)返回替换最大宽高的新 Options。原 Options 不变,需使用返回值。
Options.withMaxSizeBytes(long maxSizeBytes)返回替换字节上限的新 Options。负数构造失败。
Options.withMaxSizeKB(long maxSizeKB)以 1024 倍换算字节后返回新 Options。超大 long 乘法未做精确溢出校验。
Options.withQuality(float quality)返回新质量选项,常规有效值为 (0,1]。仅影响支持压缩质量的编码器,不直接等于文件缩小百分比。
Options.withOutputFormat(String outputFormat)指定格式并规范化名称,如 jpg→jpeg。需本机 ImageIO Writer 支持;会优先于目标和源扩展名。
Options.withAllowUpscale(boolean allowUpscale)是否允许按尺寸约束放大。放大不增加真实细节。
Options.withScalingMode(ScalingMode scalingMode)选择 FAST/BALANCED/QUALITY 插值方式。null 回退 BALANCED;与 JPEG quality 是不同参数。

Options 是 record,完整构造参数为 maxWidth, maxHeight, maxSizeBytes, quality, outputFormat, allowUpscale, scalingMode;同名访问器读取各值。ScalingMode 为插值枚举,私有 Size 是内部尺寸载体。图片操作示例和编码格式选择见文件与图片

TraceIdUtil

源码:TraceIdUtil

使用当前线程 MDC 的 traceId;仅操作本地日志上下文,不创建远端追踪 Span。

方法 / 重载用途、参数与返回值注意事项
get()读取 traceId;空白时生成 UUID 写回并返回。具有写入副作用,不是纯读取。
set(Object traceId)非 null 转为字符串写入;null 则生成 UUID。不校验长度或格式;任务结束需由调用方清理或恢复 MDC。