一、Hutool简介
Hutool是一个功能丰富的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率。它涵盖了Java开发中的方方面面,从字符串处理、日期操作到网络请求、加密解密,几乎覆盖了日常开发中的所有工具需求。
核心优势:
- 全面性:覆盖字符串、日期、集合、加密、网络等全方位工具
- 简洁性:一行代码完成复杂操作,减少样板代码
- 可靠性:经过数千项目验证,稳定可靠
- 轻量级:无侵入性,按需引入模块
二、Maven依赖
在pom.xml中添加以下依赖即可使用Hutool:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
三、核心工具类详解
1. 字符串处理 – StrUtil
StrUtil是Hutool中最强大的工具类之一,提供了数百个静态方法来处理字符串。
常用方法:
// 判断字符串是否为空(支持null、空字符串、全空格)
boolean isBlank = StrUtil.isBlank(" "); // true
boolean isNotBlank = StrUtil.isNotBlank("Hello"); // true
// 字符串格式化(比String.format更优雅)
String result = StrUtil.format("你好,{},欢迎来到{}!", "张三", "上海");
// 去除字符串前后缀
String fileName = StrUtil.removeSuffix("girl.jpg", ".jpg"); // "girl"
String suffix = StrUtil.removePrefix("girl.jpg", "girl."); // "jpg"
// 字符串分割与拼接
List<String> list = StrUtil.split("a,b,c", ','); // ["a", "b", "c"]
String joined = StrUtil.join("-", "a", "b", "c"); // "a-b-c"
生产场景应用:
// 用户输入校验
public void validateUser(UserDTO dto) {
if (StrUtil.isBlank(dto.getUsername())) {
throw new ValidationException("用户名不能为空");
}
// 清理输入并设置默认值
String username = StrUtil.trim(dto.getUsername());
String nickname = StrUtil.blankToDefault(dto.getNickname(), username);
dto.setUsername(username);
dto.setNickname(nickname);
}
2. 日期时间处理 – DateUtil
DateUtil提供了高度便捷的日期访问、处理和转换方式,极大简化了Java原生日期API的复杂操作。
常用方法:
// 获取当前时间
String now = DateUtil.now(); // "2024-01-15 10:30:45"
String today = DateUtil.today(); // "2024-01-15"
// 字符串转日期(自动识别格式)
Date date1 = DateUtil.parse("2024-01-15");
Date date2 = DateUtil.parse("2024/01/15 10:30:45");
// 日期格式化
String formatted = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
// 日期计算与偏移
Date tomorrow = DateUtil.tomorrow(); // 明天
Date yesterday = DateUtil.yesterday(); // 昨天
Date nextWeek = DateUtil.offsetWeek(new Date(), 1); // 下周
Date oneHourLater = DateUtil.offsetHour(new Date(), 1); // 1小时后
// 计算时间差
long daysBetween = DateUtil.between(startDate, endDate, DateUnit.DAY); // 相差天数
long hoursBetween = DateUtil.between(startDate, endDate, DateUnit.HOUR); // 相差小时
// 时间判断
boolean isToday = DateUtil.isToday(date); // 是否为今天
boolean isWeekend = DateUtil.isWeekend(new Date()); // 是否为周末
生产场景应用:
// 订单时间处理
public Order createOrder(OrderDTO dto) {
Order order = new Order();
order.setOrderNo(generateOrderNo());
order.setCreateTime(DateUtil.now()); // 当前时间字符串
order.setPayDeadline(DateUtil.offsetHour(new Date(), 2)); // 2小时后
return orderRepository.save(order);
}
// 会员到期提醒
public boolean isExpiringSoon(Member member) {
Date expireDate = member.getExpireDate();
Date now = new Date();
long remainDays = DateUtil.between(now, expireDate, DateUnit.DAY);
return remainDays > 0 && remainDays <= 7; // 7天内到期
}
3. 集合操作 – CollUtil
CollUtil提供了对List、Set、Map等集合的操作方法,支持创建、添加、移除、转换等操作。
常用方法:
// 创建并初始化集合
List<String> list = CollUtil.newArrayList("Hutool", "Java", "Tools");
Set<String> set = CollUtil.newHashSet("Apple", "Banana", "Orange");
Map<String, String> map = CollUtil.newHashMap();
// 判断集合是否为空
boolean isEmpty = CollUtil.isEmpty(list);
// 集合转换(去重)
Set<String> uniqueSet = CollUtil.newHashSet(list);
// 集合拼接
String joined = CollUtil.join(list, ","); // "Hutool,Java,Tools"
// 集合查找
boolean contains = list.contains("Hutool");
4. 类型转换 – Convert
Convert类提供了一个统一的类型转换入口,能优雅地处理各种复杂的数据类型转换。
常用方法:
// 基础类型转换
int num = Convert.toInt("123");
boolean bool = Convert.toBool("true");
Integer value = Convert.toInt(null, 0); // null -> 0(带默认值)
// 集合类型转换
String[] strArr = {"1", "2", "3"};
List<Integer> intList = Convert.toList(Integer.class, strArr); // [1, 2, 3]
// 金额转大写
String chineseAmount = Convert.digitToChinese(12345.67);
// 输出:壹万贰仟叁佰肆拾伍元陆角柒分
// 半角/全角转换
String fullWidth = Convert.toSBC("Hello 123"); // "Hello 123"
String halfWidth = Convert.toDBC(fullWidth); // "Hello 123"
5. 加密解密 – SecureUtil
SecureUtil将Java原生的加密解密API封装成了极其简单的一行调用,支持MD5、SHA、AES、RSA等算法。
常用方法:
// MD5加密
String md5 = SecureUtil.md5("hello world");
// SHA256加密
String sha256 = SecureUtil.sha256("hello world");
// AES加密
AES aes = SecureUtil.aes("1234567812345678".getBytes());
String encrypted = aes.encryptHex("这是一个秘密");
String decrypted = aes.decryptStr(encrypted);
// RSA非对称加密
RSA rsa = SecureUtil.rsa();
byte[] encryptData = rsa.encrypt("数据", KeyType.PublicKey);
6. 文件操作 – FileUtil
FileUtil简化了文件读写、复制、删除等操作,自动处理流关闭,避免资源泄漏。
常用方法:
// 读取文件内容
String content = FileUtil.readUtf8String("example.txt");
// 写入文件内容
FileUtil.writeUtf8String("example.txt", "Hello, Hutool!");
// 复制文件
FileUtil.copy("src.txt", "dest.txt", true);
// 删除文件
boolean isDeleted = FileUtil.del("file.txt");
// 网络文件下载(支持断点续传)
long size = HttpUtil.downloadFile("https://example.com/file.mp4",
FileUtil.file("download/"));
// 文件压缩成ZIP
ZipUtil.zip("c:/docs", "c:/docs.zip");
7. HTTP请求 – HttpUtil
HttpUtil简化了HTTP请求的发起,支持GET、POST、PUT、DELETE等请求方式,支持文件上传和异步处理。
常用方法:
// GET请求
String response = HttpUtil.get("https://api.example.com/data");
// POST请求(表单数据)
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("username", "张三");
paramMap.put("password", "123456");
String postResponse = HttpUtil.post("https://api.example.com/login", paramMap);
// POST请求(JSON数据)
User user = new User("张三", "123456");
String json = JSONUtil.toJsonStr(user);
String response = HttpUtil.createPost("https://api.example.com/register")
.header("Content-Type", "application/json")
.body(json)
.timeout(3000)
.execute()
.body();
// 文件上传
HashMap<String, Object> uploadMap = new HashMap<>();
uploadMap.put("username", "张三");
uploadMap.put("file", FileUtil.file("logo.png"));
String uploadResponse = HttpUtil.post("https://api.example.com/upload", uploadMap);
// 带进度监控的下载
HttpRequest.get("https://example.com/bigfile.zip")
.setChunkedStreamSize(1024 * 1024) // 1MB分块
.executeAsync()
.writeBody("download/bigfile.zip", new StreamProgress() {
@Override
public void start() {
Console.log("开始下载...");
}
@Override
public void progress(long progressSize) {
Console.log("已下载:{}", FileUtil.readableFileSize(progressSize));
}
@Override
public void finish() {
Console.log("下载完成!");
}
});
8. JSON处理 – JSONUtil
JSONUtil提供了JSON的解析和生成功能,支持POJO与JSON的转换。
常用方法:
// 对象转JSON字符串
User user = new User("张三", 25);
String jsonString = JSONUtil.toJsonStr(user);
// JSON字符串转对象
User parsedUser = JSONUtil.toBean(jsonString, User.class);
// 创建JSON对象
JSONObject json = new JSONObject();
json.put("name", "Hutool");
json.put("age", 3);
String jsonStr = json.toString();
// 解析JSON字符串
JSONObject jsonObject = JSON.parseObject(jsonStr);
String name = jsonObject.getStr("name");
int age = jsonObject.getInt("age");
9. 断言工具 – Assert
Assert工具类用于接口参数校验,替代繁琐的if-else判断,不符合条件直接抛出异常。
常用方法:
// 字符串非空校验
Assert.notBlank(cardNo, "礼品卡编号不能为空");
// 条件判断
Assert.isTrue(amount.compareTo(BigDecimal.ZERO) > 0, "金额必须大于0");
// 对象非空校验
Assert.notNull(user, "用户信息不能为空");
// 集合非空校验
Assert.notEmpty(list, "列表不能为空");
10. 数字处理 – NumberUtil
NumberUtil提供了数字的加减乘除、四舍五入、随机数生成等功能。
常用方法:
// 四舍五入
BigDecimal result = NumberUtil.round(123.456, 2); // 123.46
// 精确计算
BigDecimal sum = NumberUtil.add(new BigDecimal("10.5"), new BigDecimal("20.3"));
BigDecimal difference = NumberUtil.sub(new BigDecimal("30.0"), new BigDecimal("15.5"));
BigDecimal product = NumberUtil.mul(new BigDecimal("10.0"), new BigDecimal("2.5"));
BigDecimal quotient = NumberUtil.div(new BigDecimal("10.0"), new BigDecimal("3.0"), 2);
// 随机数生成
int randomInt = RandomUtil.randomInt(1, 100); // 1-100之间的随机整数
String randomStr = RandomUtil.randomString(10); // 10位随机字符串
// 唯一ID生成
String uuid = IdUtil.randomUUID(); // 带-的UUID
String simpleUUID = IdUtil.simpleUUID(); // 不带-的UUID
long snowflakeId = IdUtil.getSnowflake(1, 1).nextId(); // 雪花算法ID
11. 正则表达式 – ReUtil
ReUtil简化了正则表达式的使用,提供了匹配、查找、替换等功能。
常用方法:
// 正则匹配
boolean isMatch = ReUtil.isMatch("^\\d+$", "123456"); // true
// 查找所有匹配项
List<String> words = ReUtil.findAll("[a-zA-Z]+", "Java、Python、C++", 0);
// 替换匹配项
String replaced = ReUtil.replaceAll("Hello Java", "Java", "World"); // "Hello World"
// 提取匹配内容
String content = "订单号:123456,金额:100.00";
String orderNo = ReUtil.get("订单号:(\\d+)", content, 1); // "123456"
String amount = ReUtil.get("金额:(\\d+\\.\\d+)", content, 1); // "100.00"
12. 配置文件处理 – Setting
Setting模块提供了强大的配置文件管理功能,支持.properties文件读写,支持中文、变量引用、分组等特性。
常用方法:
// 加载配置文件
Setting setting = new Setting("config.properties");
// 读取配置项
String username = setting.getStr("database.username");
String password = setting.getStr("database.password");
// 修改配置
setting.set("database.password", "new_password");
setting.store("config.properties");
// 分组读取
String value = setting.getByPath("some.group.key");
配置文件示例:
# config.properties
database.url=jdbc:mysql://localhost:3306/test
database.username=root
database.password=123456
# 分组配置
[redis]
host=127.0.0.1 port=6379 password=redis_pass
[email]
smtp.host=smtp.example.com smtp.port=587 smtp.username=user@example.com smtp.password=email_pass
13. 数据库操作 – Db模块
Db模块基于JDBC封装,借鉴ActiveRecord思想,通过链式API支持数据库连接、CRUD操作、事务管理。
常用方法:
// 查询所有数据
List<Entity> entities = Db.use().findAll("user_table");
for (Entity entity : entities) {
System.out.println(entity.getStr("name"));
System.out.println(entity.getInt("age"));
}
// 条件查询
List<Entity> users = Db.use().findAll(Entity.create("user_table")
.set("age", ">", 18));
// 插入数据
Db.use().insert(Entity.create("user_table")
.set("name", "张三")
.set("age", 25));
// 更新数据
Db.use().update(Entity.create("user_table")
.set("age", 26),
Entity.create("user_table")
.set("name", "张三"));
// 删除数据
Db.use().delete(Entity.create("user_table")
.set("name", "张三"));
// 事务管理
Db.use().tx(new TxFunc() {
@Override
public void call() throws SQLException {
// 插入用户
Db.use().insert(Entity.create("user_table")
.set("name", "张三")
.set("age", 25));
// 插入订单
Db.use().insert(Entity.create("order_table")
.set("user_id", 1)
.set("amount", 100.00));
}
});
14. Excel操作 – ExcelUtil
ExcelUtil针对POI中的Excel和Word进行封装,简化了Excel文件的读写操作。
常用方法:
// 读取Excel文件
ExcelReader reader = ExcelUtil.getReader("test.xlsx");
List<List<Object>> rows = reader.read();
// 写入Excel文件
List<Map<String, Object>> rows = new ArrayList<>();
Map<String, Object> row = new HashMap<>();
row.put("姓名", "张三");
row.put("年龄", 25);
rows.add(row);
ExcelWriter writer = ExcelUtil.getWriter("test.xlsx");
writer.write(rows, true);
writer.close();
// 读取指定Sheet
ExcelReader reader = ExcelUtil.getReader("test.xlsx", "Sheet1");
List<Map<String, Object>> list = reader.readAll();
// 写入大数据量(分块读取)
ExcelWriter writer = ExcelUtil.getBigWriter("bigdata.xlsx");
for (int i = 0; i < 100000; i++) {
writer.writeRow(new Object[]{"数据" + i, i});
}
writer.close();
15. 验证码生成 – CaptchaUtil
CaptchaUtil提供了简单易用的验证码生成功能,包括图片验证码和动态验证码。
常用方法:
// 生成线段干扰验证码
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(200, 100);
System.out.println("验证码内容:" + captcha.getCode());
captcha.write("captcha.png");
// 生成圆圈干扰验证码
CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(200, 100);
System.out.println("验证码内容:" + circleCaptcha.getCode());
circleCaptcha.write("circle_captcha.png");
// 生成动态验证码(GIF)
GifCaptcha gifCaptcha = CaptchaUtil.createGifCaptcha(200, 100);
System.out.println("验证码内容:" + gifCaptcha.getCode());
gifCaptcha.write("gif_captcha.gif");
16. 二维码生成 – QrCodeUtil
QrCodeUtil提供了二维码的生成和解析功能。
常用方法:
// 生成二维码
QrCodeUtil.generate("https://hutool.cn", 300, 300, FileUtil.file("qrcode.png"));
// 解析二维码
String decodedText = QrCodeUtil.decode(FileUtil.file("qrcode.png"));
// 生成带Logo的二维码
QrCodeUtil.generate("https://hutool.cn", 300, 300,
FileUtil.file("logo.png"), FileUtil.file("qrcode_with_logo.png"));
// 生成带颜色的二维码
QrConfig config = new QrConfig();
config.setForeColor(Color.BLUE);
config.setBackColor(Color.WHITE);
QrCodeUtil.generate("https://hutool.cn", config, FileUtil.file("qrcode_color.png"));
17. 系统信息 – SystemUtil
SystemUtil提供了获取系统信息、JVM信息、环境变量等功能。
常用方法:
// 获取操作系统信息
String osName = SystemUtil.get("os.name");
String osVersion = SystemUtil.get("os.version");
// 获取JVM信息
String jvmVersion = SystemUtil.getJavaVersion();
String jvmVendor = SystemUtil.get("java.vendor");
// 获取内存信息
RuntimeInfo runtimeInfo = SystemUtil.getRuntimeInfo();
long totalMemory = runtimeInfo.getTotalMemory();
long freeMemory = runtimeInfo.getFreeMemory();
long usedMemory = runtimeInfo.getUsedMemory();
// 获取环境变量
String path = SystemUtil.get("PATH");
String home = SystemUtil.get("HOME");
18. 日志工具 – Log
Log是Hutool的日志门面工具,自动识别底层日志实现(Log4j2、Logback、Slf4j等),提供统一的日志记录接口。
常用方法:
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
private static final Log log = LogFactory.get();
// 记录日志
log.debug("调试信息");
log.info("普通信息");
log.warn("警告信息");
log.error("错误信息");
// 带参数的日志
log.info("用户{}登录成功", username);
log.error("文件{}读取失败,原因:{}", fileName, e.getMessage());
// 异常日志
try {
// 业务代码
} catch (Exception e) {
log.error("业务处理异常", e);
}
19. 定时任务 – CronUtil
CronUtil提供了类Crontab表达式的定时任务调度功能,支持秒级别的定时任务定义。
常用方法:
// 添加定时任务
CronUtil.schedule("0 0/5 * * * ?", new Task() {
@Override
public void execute() {
System.out.println("每5分钟执行一次");
}
});
// 启动定时任务
CronUtil.start();
// 停止定时任务
CronUtil.stop();
// 设置是否守护线程
CronUtil.setMatchSecond(true); // 支持秒级别
// 立即执行一次
CronUtil.schedule("0 0 * * * ?", new Task() {
@Override
public void execute() {
System.out.println("每小时执行一次");
}
}, true); // true表示立即执行一次
20. 其他实用工具类
BeanUtil – Bean属性拷贝工具类
// 属性拷贝
BeanUtil.copyProperties(sourceBean, targetBean);
// Bean转Map
Map<String, Object> map = BeanUtil.beanToMap(bean);
// Map转Bean
User user = BeanUtil.mapToBean(map, User.class, false);
IdcardUtil – 身份证工具类
// 身份证校验
boolean valid = IdcardUtil.isValidCard("321083197812162119"); // true
// 获取年龄
int age = IdcardUtil.getAgeByIdCard("321083197812162119", new Date());
// 获取生日
String birth = IdcardUtil.getBirthByIdCard("321083197812162119");
// 获取省份
String province = IdcardUtil.getProvinceByIdCard("321083197812162119");
ValidatorUtil – 校验工具类
// 邮箱格式校验
boolean isValidEmail = ValidatorUtil.isEmail("user@example.com");
// 手机号格式校验
boolean isValidMobile = ValidatorUtil.isMobile("13800138000");
// 身份证号校验
boolean isValidIdCard = ValidatorUtil.isIdCard("321083197812162119");
ZipUtil – 压缩解压工具类
// 压缩文件夹
ZipUtil.zip("path/to/source/folder", "path/to/destination/archive.zip");
// 解压缩文件
ZipUtil.unzip("path/to/archive.zip", "path/to/destination/folder");
// 压缩单个文件
ZipUtil.zip("file.txt", "file.zip");
// 解压到指定目录
ZipUtil.unzip("archive.zip", "target/dir");
四、模块化引入
Hutool支持按需引入模块,避免引入不必要的依赖:
<!-- 核心模块 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.8.16</version>
</dependency>
<!-- HTTP模块 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
<version>5.8.16</version>
</dependency>
<!-- 加密模块 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-crypto</artifactId>
<version>5.8.16</version>
</dependency>
<!-- JSON模块 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-json</artifactId>
<version>5.8.16</version>
</dependency>
<!-- Excel模块 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-poi</artifactId>
<version>5.8.16</version>
</dependency>
<!-- 数据库模块 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-db</artifactId>
<version>5.8.16</version>
</dependency>
五、最佳实践
1. 避免引入整个hutool-all
在生产环境中,建议按需引入子模块,而不是整个hutool-all,这样可以减少项目依赖和打包体积。
2. 统一异常处理
结合Assert工具类进行参数校验,统一异常处理:
public void createUser(UserDTO dto) {
// 参数校验
Assert.notBlank(dto.getUsername(), "用户名不能为空");
Assert.notBlank(dto.getPassword(), "密码不能为空");
Assert.isTrue(dto.getPassword().length() >= 6, "密码长度不能少于6位");
// 业务逻辑
User user = new User();
BeanUtil.copyProperties(dto, user);
user.setCreateTime(DateUtil.now());
userRepository.save(user);
}
3. 配置文件管理
使用Setting模块管理配置文件,支持中文和分组:
// 加载配置文件
Setting setting = new Setting("config.properties");
// 读取配置
String dbUrl = setting.getStr("database.url");
String dbUsername = setting.getStr("database.username");
String dbPassword = setting.getStr("database.password");
// 分组读取
String redisHost = setting.getByPath("redis.host");
String redisPort = setting.getByPath("redis.port");
4. 日志记录规范
使用Log工具类统一日志记录:
private static final Log log = LogFactory.get();
public void processOrder(Order order) {
try {
log.info("开始处理订单:{}", order.getOrderNo());
// 业务逻辑
orderService.process(order);
log.info("订单处理完成:{}", order.getOrderNo());
} catch (Exception e) {
log.error("订单处理失败:{},原因:{}", order.getOrderNo(), e.getMessage(), e);
throw new BusinessException("订单处理失败");
}
}
六、总结
Hutool作为Java开发中的”瑞士军刀”,通过静态方法封装,将复杂的操作简化成一行代码,极大地提升了开发效率。无论是字符串处理、日期操作、文件读写、网络请求还是加密解密,Hutool都提供了简洁易用的API。
核心价值:
- 减少代码量:原来需要30行的代码,使用Hutool可能只需要3行
- 降低BUG率:工具类经过千万项目验证,比自己写的代码更稳定
- 提高效率:避免重复造轮子,专注于业务逻辑
- 中文友好:文档和注释全中文,学习成本低
在实际项目中,建议根据需求按需引入模块,结合Assert进行参数校验,使用Log统一日志记录,充分发挥Hutool的优势,让Java开发变得更加”甜甜的”。
