外观
Hutool 工具库
2026-04-01
版本: 5.8.34 官网: hutool.cn
Hutool 是国内使用最广泛的 Java 工具库之一,包含字符串、集合、日期、IO、加密、HTTP 等众多工具类。
Nebula 框架中不做二次封装,业务代码可直接引入使用。
引入依赖
nebula-support-dependencies BOM 已统一管理版本,子项目只需声明模块名即可:
// build.gradle —— 按需引入所需模块(推荐细粒度引入)
dependencies {
implementation 'cn.hutool:hutool-core' // 核心工具:字符串、集合、日期、Bean ...
implementation 'cn.hutool:hutool-crypto' // 加密工具:RSA、AES、MD5 ...
implementation 'cn.hutool:hutool-extra' // 扩展工具:邮件、Emoji、Spring 工具 ...
// 或者一次性引入全部模块(包体较大,谨慎使用)
// implementation 'cn.hutool:hutool-all'
}StrUtil — 字符串工具
StrUtil 是日常使用频率最高的工具类,覆盖判空、格式化、截取、分割等高频场景。
空值判断
// 判断字符串是否为空(null、""、仅空白字符均视为空)
StrUtil.isBlank(str)
StrUtil.isNotBlank(str)
// 仅判断 null 和 "",不处理空格
StrUtil.isEmpty(str)
StrUtil.isNotEmpty(str)在 Nebula 项目中的典型用法(动态查询条件):
// nebula-system:字典项分页查询,字段有值才加 WHERE 条件
if (StrUtil.isNotBlank(request.getItemLabel())) {
wrapper.like(SysDictItemDO::getItemLabel, request.getItemLabel());
}
if (StrUtil.isNotBlank(request.getItemValue())) {
wrapper.like(SysDictItemDO::getItemValue, request.getItemValue());
}字符串分割
// 按逗号分割,并自动去除每个元素的首尾空白
List<String> codes = StrUtil.splitTrim(typeCode, ',');
// 按固定长度分割
List<String> parts = StrUtil.split("a-b-c", '-');
// 判断是否包含某个子串(忽略大小写)
StrUtil.containsIgnoreCase("Hello", "hello"); // true字符串格式化
// 使用 {} 占位符(类 Slf4j 风格)
String msg = StrUtil.format("用户 {} 登录失败,剩余重试次数:{}", username, remaining);
// 转为驼峰 / 下划线
StrUtil.toCamelCase("sys_user_name"); // sysUserName
StrUtil.toUnderlineCase("sysUserName"); // sys_user_name常用转换
// 安全转换为 int,转换失败返回默认值
int page = Convert.toInt(request.getParam("page"), 1);
// null 安全的默认值
String name = StrUtil.nullToDefault(rawName, "未命名");
// 截取字符串
StrUtil.sub("Hello World", 0, 5); // HelloCollUtil — 集合工具
// 空集合判断(null 和空集合都返回 true)
CollUtil.isEmpty(list)
CollUtil.isNotEmpty(list)
// 创建 ArrayList(可读性更好)
List<Long> ids = CollUtil.newArrayList(1L, 2L, 3L);
// 集合分批处理(防止 IN 查询超长)
CollUtil.split(ids, 500).forEach(batch -> {
// 每批最多 500 条处理
doSomething(batch);
});
// 交集 / 并集 / 差集
CollUtil.intersection(listA, listB);
CollUtil.union(listA, listB);
CollUtil.subtract(listA, listB);
// 转换集合(类似 stream map)
List<String> names = CollUtil.map(userList, SysUserDO::getName, true);项目中的典型用法:
// nebula-system:批量操作前先判断集合非空
if (CollUtil.isNotEmpty(saveParam.getRoleIds())) {
sysUserRoleService.saveUserRoles(userId, saveParam.getRoleIds());
}DateUtil — 日期工具
// 获取当前时间
Date now = DateUtil.date();
LocalDateTime ldt = LocalDateTimeUtil.now();
// 日期格式化
String formatted = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
// 字符串解析(支持常见格式自动识别)
Date date = DateUtil.parse("2026-04-01");
Date date2 = DateUtil.parse("2026/04/01 10:30:00");
// 日期计算
Date nextWeek = DateUtil.offsetDay(now, 7);
Date lastMonth = DateUtil.offsetMonth(now, -1);
// 时间差
long diffDays = DateUtil.between(startDate, endDate, DateUnit.DAY);
// 获取当月起止时间(适合统计查询)
Date beginOfMonth = DateUtil.beginOfMonth(now);
Date endOfMonth = DateUtil.endOfMonth(now);IdUtil — ID 生成
// 生成雪花 ID(long 型,分布式唯一)
long id = IdUtil.getSnowflakeNextId();
// 生成 UUID(带横线)
String uuid = IdUtil.randomUUID();
// 生成 UUID(不带横线,常用于文件名、Token 等)
String simpleUuid = IdUtil.simpleUUID();注意: Nebula 框架使用 MyBatis-Plus 的
@TableId(type = IdType.ASSIGN_ID)自动生成雪花 ID, 通常不需要手动调用IdUtil。业务中需要生成唯一标识时可使用IdUtil.simpleUUID()。
CryptoUtil — 加密工具
// MD5 摘要(适合文件校验、非敏感信息签名)
String md5 = SecureUtil.md5("content");
// AES 对称加密(适合配置项加密存储)
AES aes = SecureUtil.aes(key.getBytes());
String cipherText = aes.encryptHex("明文");
String plainText = aes.decryptStr(cipherText);
// RSA 非对称加密(Nebula 认证域使用场景:后端加密私钥加密,前端公钥解密)
// 实际登录场景中前端用 JSEncrypt 用公钥加密密码,后端用私钥解密
RSA rsa = SecureUtil.rsa(privateKey, publicKey);
String decrypted = rsa.decryptStr(encryptedPassword, KeyType.PrivateKey);BeanUtil — 对象拷贝
注意
Nebula 规范推荐使用 MapStruct 进行对象转换,BeanUtil.copyProperties 适用于快速脚本或测试场景, 正式业务代码请优先使用 MapStruct。
// 浅拷贝(字段名相同才会赋值)
TargetVO vo = BeanUtil.copyProperties(sourceDO, TargetVO.class);
// 批量拷贝
List<TargetVO> voList = BeanUtil.copyToList(doList, TargetVO.class);
// 转为 Map
Map<String, Object> map = BeanUtil.beanToMap(obj);常见错误
| 问题 | 原因 | 解决方案 |
|---|---|---|
StrUtil.isBlank 与 isEmpty 混淆 | isBlank 包含空白字符判断,isEmpty 不包含 | 业务判断推荐统一用 isBlank |
BeanUtil.copyProperties 类型不匹配静默跳过 | Hutool 遇类型不兼容不抛错,字段丢失 | 用 MapStruct 替代,编译期校验 |
DateUtil.parse 格式识别失败 | 非标准日期字符串 | 显式传入 DatePattern 格式 |
