前言:
作为软件工程师,在平时开发中,我们会使用很多工具类来提升项目开发的速度,而国内用的比较多的 Hutool 框架,就是其中之一。
Hutool介绍
下面就说说Hutool工具,官方的解释是:(Hutool 官方文档:doc.hutool.cn/)
Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。
Hutool中的工具方法来自每个用户的精雕细琢,它涵盖了Java开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当;
Hutool是项目中“util”包友好的替代,它节省了开发人员对项目中公用类和公用工具方法的封装时间,使开发专注于业务,同时可以最大限度的避免封装不完善带来的bug。
1.Hutool包含组件
一个Java基础工具类,对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装,组成各种Util工具类,同时提供以下组件:
模块 | 介绍 |
hutool-aop | JDK动态代理封装,提供非IOC下的切面支持 |
hutool-bloomFilter | 布隆过滤,提供一些Hash算法的布隆过滤 |
hutool-cache | 简单缓存实现 |
hutool-core | 核心,包括Bean操作、日期、各种Util等 |
hutool-cron | 定时任务模块,提供类Crontab表达式的定时任务 |
hutool-crypto | 加密解密模块,提供对称、非对称和摘要算法封装 |
hutool-db | JDBC封装后的数据操作,基于ActiveRecord思想 |
hutool-dfa | 基于DFA模型的多关键字查找 |
hutool-extra | 扩展模块,对第三方封装(模板引擎、邮件、Servlet、二维码、Emoji、FTP、分词等) |
hutool-http | 基于HttpUrlConnection的Http客户端封装 |
hutool-log | 自动识别日志实现的日志门面 |
hutool-script | 脚本执行封装,例如Javascript |
hutool-setting | 功能更强大的Setting配置文件和Properties封装 |
hutool-system | 系统参数调用封装(JVM信息等) |
hutool-json | JSON实现 |
hutool-captcha | 图片验证码实现 |
hutool-poi | 针对POI中Excel和Word的封装 |
hutool-socket | 基于Java的NIO和AIO的Socket封装 |
hutool-jwt | JSON Web Token (JWT)封装实现 |
2.引入框架
首先,在项目的 pom.xml 引入依赖:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
3.常见使用场景
下面就说说在开发过程中,我们经常用到的场景
3.1HTTP 请求类
Apache 的 HttpClient 用的比较多,但是由于此包较为庞大,API 又比较难用,因此并不适用很多场景,而 Hutool 的 Hutool-http 针对 JDK 的 HttpUrlConnection 做一层封装,简化了 HTTPS 请求、文件上传、Cookie 记忆等操作,使 Http 请求变得无比简单。
发送一个get请求:
// GET请求
String content = HttpUtil.get(url);
System.out.println(content);
发送一个 post请求:
// POST 请求
HashMap<String, Object> param = new HashMap<>();
//数据封装
paramMap.put("city", "南京");
paramMap.put("desc", "南京真漂亮");
String result = HttpUtil.post("www.java.com", param);
3.2类型转换
Hutool包专门提供了Convert类,我们使用它做类型转换,使用起来非常方便。
数字转换为字符串:
int a = 666;
//str为"666"
String str = Convert.toStr(a);
转换为指定类型数组:
long[] b = {1,2,3,4,5};
//bStr为:"[1, 2, 3, 4, 5]"
String bStr = Convert.toStr(b);
System.out.println(bStr);
String[] b = { "1", "2", "3", "4" };
//结果为Integer数组
Integer[] intArray = Convert.toIntArray(b);
long[] c = {1,2,3,4,5};
//结果为Integer数组
Integer[] intArray2 = Convert.toIntArray(c);
转换为日期对象:
String a = "2024-04-05";
Date value = Convert.toDate(a);
System.out.println(value);//Fri Apr 05 00:00:00 CST 2024
转换为集合:
Object[] a = {"a", "你", "好", "", 1};
List<?> list = Convert.convert(List.class, a);
System.out.println(list.toString());//[a, 你, 好, , 1]
//从4.1.11开始可以这么用
List<?> list = Convert.toList(a);
3.3生成 N 位随机验证码
如果想生成手机验证码(4 位或 6 位),使用 Hutool 的这个功能就再也合适不过了,具体实现代码如下:
// 生成 4 位随机验证码
String verificationCode = RandomUtil.randomStringUpper(4);
3.4时间日期转换
通常情况下,我们需要使用SimpleDateFormat类,做时间和字符串类型的转换。其实Hutool包专门提供了DateUtil类,给我们做时间和日期类型转换的。
Date和Calendar相互转换:
//当前时间
Date date = DateUtil.date();//2024-04-05 16:13:48
//当前时间
Date date2 = DateUtil.date(Calendar.getInstance());
字符串转日期:
//将字符串转换成Date类型
String dateStr = "2024-04-05";
Date date = DateUtil.parse(dateStr);
//自定义时间格式做类型转换
String dateStr = "2024.04.05";
Date date = DateUtil.parse(dateStr, "yyyy-MM-dd");
//格式化日期输出
String dateStr = "2024-04-05";
Date date = DateUtil.parse(dateStr);
//结果 2017/04/05
String format = DateUtil.format(date, "yyyy/MM/dd");
//结果:2024-04-05 00:00:00
String formatDateTime = DateUtil.formatDateTime(date);
//结果:00:00:00
String formatTime = DateUtil.formatTime(date);
开始和结束时间:
String dateStr = "2024-04-05 22:33:23";
Date date = DateUtil.parse(dateStr);
//一天的开始,结果:2024-04-05 00:00:00
Date beginOfDay = DateUtil.beginOfDay(date);
//一天的结束,结果:2024-04-05 23:59:59
Date endOfDay = DateUtil.endOfDay(date);
DateTime beginOfMonth = DateUtil.beginOfMonth(date);
DateTime endOfMonth = DateUtil.endOfMonth(date);
3.5计时器
Hutool 通过封装 TimeInterval 实现计时器功能,即可以计算方法或过程执行的时间。
TimeInterval timer = DateUtil.timer();
// todo:执行具体业务
timer.interval(); // 花费毫秒数
timer.intervalRestart();// 返回花费时间,并重置开始时间
timer.intervalMinute(); // 花费分钟数
3.6数字工具
NumberUtil 数字工具针对数学运算做工具性封装。我最喜欢使用它的保留小时和数字格式化。
保留小数
double te1=123456.123456;
double te2=123456.127456;
Console.log(round(te1,4)); // 结果:123456.1235
Console.log(round(te2,4)); // 结果:123456.1275
3.7StringUtil
这个工具的用处类似于Apache Commons Lang中的StringUtil,常用的方法例如isBlank、isNotBlank、isEmpty、isNotEmpty。
hasBlank方法:就是给定一些字符串,如果一旦有空的就返回true,常用于判断好多字段是否有空的。
这两个方法的区别是hasEmpty只判断是否为null或者空字符串(""),hasBlank则会把不可见字符也算做空,isEmpty和isBlank同理。
removePrefix方法:去掉字符串的前缀后缀的,例如去个文件名的扩展名。
String fileName = StrUtil.removeSuffix("nanjing.jpg", ".jpg") //nanjing
忽略大小写的时候用removePrefixIgnoreCase和removeSuffixIgnoreCase方法。
sub方法:
String str = "abcdefgh";
String strSub1 = StrUtil.sub(str, 2, 3); //strSub1 -> c
String strSub2 = StrUtil.sub(str, 2, -3); //strSub2 -> cde
String strSub3 = StrUtil.sub(str, 3, 2); //strSub2 -> c
3.8随机数
- NumberUtil.generateRandomNumber 生成不重复随机数 根据给定的最小数字和最大数字,以及随机数的个数,产生指定的不重复的数组。
- NumberUtil.generateBySet 生成不重复随机数 根据给定的最小数字和最大数字,以及随机数的个数,产生指定的不重复的数组。
3.9布隆过滤器
布隆过滤器(Bloom Filter)是一种数据结构,用于快速检查一个元素是否属于一个集合中。它可以高效地判断一个元素不在集合中(即不存在),但不能确定一个元素是否一定存在于集合中。布隆过滤器通过使用多个哈希函数和位数组来实现这一功能。
布隆过滤器的基本原理如下:
- 初始化:首先需要定义一个位数组,将所有位都初始化为 0。
- 添加元素:对于要加入集合的元素,使用多个哈希函数将元素映射到位数组上的多个位置,并将这些位置的值设置为 1。
- 查询元素:对于要查询的元素,同样使用多个哈希函数计算对应的位数组位置,如果这些位置的值都为 1,则表示元素可能存在于集合中;如果存在任何一个位置的值为 0,则表示元素一定不存在于集合中。
布隆过滤器的优点是:
- 节省空间:相比于传统的数据结构,布隆过滤器可以用较少的空间来存储大量元素。
- 快速查询:布隆过滤器可以在常数时间内进行元素的查询,非常高效。
- 可以扩展:通过增加哈希函数和位数组大小,可以灵活地调整布隆过滤器的容量和误判率。
然而,布隆过滤器也存在一些缺点,主要是存在一定的误判率(即可能判断某个元素存在于集合中,但实际上并不存在),并且无法删除已加入的元素。
布隆过滤器常用于需要快速判断元素是否可能存在于大型数据集合中的场景,如缓存系统、网络爬虫去重、拦截垃圾邮件等。在实际应用中,布隆过滤器可以起到很好的辅助作用,但需要根据具体场景和需求来调整参数,以平衡误判率和存储空间之间的关系。(来着ChatGpt解释)
Hutool布隆过滤器的具体使用如下:
// 初始化
BitMapBloomFilter filter = new BitMapBloomFilter(10);
filter.add("126");
filter.add("abg");
filter.add("ggg");
// 查找
System.out.println(filter.contains("126"));//true
3.10邮件发送工具
在 Java 中发送邮件主要依靠 javax.mail 包,但是由于使用比较繁琐,因此 Hutool 针对其做了封装 MailUtil,它的使用主要需要两步:
- 添加 Java Mail 依赖(因为 MailUtil 是对它的封装)。
- 编写邮件发送代码。
//导入依赖
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
// 发送普通文本邮件,最后一个参数可选是否添加多个附件
MailUtil.send("hutool@hello.com", "测试", "测试用的", false);
// 发送 HTML 格式的邮件并附带附件,最后一个参数可选是否添加多个附件:
MailUtil.send("hutool@hello.com", "测试", "<h1>邮件测试用户</h1>", true, FileUtil.file("d:/ccc.xml"));
// 群发邮件,可选 HTML 或普通文本,可选多个附件:
ArrayList<String> tos = CollUtil.newArrayList(
"girl1@hello.com",
"girl2@hello.com",
"girl3@hello.com",
"girl4@hello.com");
MailUtil.send(tos, "测试", "邮件来自群发测试", false);
3.11IdUtil
在分布式环境中,唯一ID生成应用十分广泛,生成方法也多种多样,Hutool针对一些常用生成策略做了简单封装。
唯一ID生成器的工具类,涵盖了:
- UUID
- ObjectId
- Snowflake雪花算法
UUID全称通用唯一识别码(universally unique identifier),JDK通过java.util.UUID提供了 Leach-Salz 变体的封装。在Hutool中,生成一个UUID字符串方法如下:
//生成的UUID是带-的字符串,类似于:d1a1d4a7-db0a-4a90-bd4b-b3e708212471
String uuid = IdUtil.randomUUID();
//生成的是不带-的字符串,类似于:1d8178f8bd644dffba5408e89d88940a
String simpleUUID = IdUtil.simpleUUID();
Hutool重写java.util.UUID的逻辑,对应类为cn.hutool.core.lang.UUID,使生成不带-的UUID字符串不再需要做字符替换,性能提升近一倍。
ObjectId是MongoDB数据库的一种唯一ID生成策略,是UUID version1的变种。Hutool针对此封装了cn.hutool.core.lang.ObjectId,快捷创建方法为:
String id = ObjectId.next();
System.out.println(id);//660fbb333af4d7ae6faf3b19
String id2 = IdUtil.objectId();
System.out.println(id2);//660fbb333af4d7ae6faf3b1a
雪花算法分布式系统中,有一些需要使用全局唯一ID的场景,有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。雪花算法就是这种生成器。
//参数1为终端ID
//参数2为数据中心ID
Snowflake snowflake = IdUtil.getSnowflake(1, 1);
long id = snowflake.nextId();
3.12BeanUtil
判断是否为Bean对象:BeanUtil.isBean方法根据是否存在只有一个参数的setXXX方法或者public类型的字段来判定是否是一个Bean对象。这样的判定方法主要目的是保证至少有一个setXXX方法用于属性注入。
boolean isBean = BeanUtil.isBean(HashMap.class);//false
Bean转为Map:BeanUtil.beanToMap方法则是将一个Bean对象转为Map对象。
//person对象
SubPerson person = new SubPerson();
person.setAge(14);
person.setOpenid("11213232");
person.setName("测试B");
person.setSubName("sub名字");
//转成map
Map<String, Object> map = BeanUtil.beanToMap(person);
Bean转Bean:Bean之间的转换主要是相同属性的复制,因此方法名为copyProperties,此方法支持Bean和Map之间的字段复制。BeanUtil.copyProperties方法同样提供一个CopyOptions参数用于自定义属性复制。
SubPerson p1 = new SubPerson();
p1.setSlow(true);
p1.setName("测试");
p1.setSubName("sub测试");
Map<String, Object> map = MapUtil.newHashMap();
BeanUtil.copyProperties(p1, map);
3.13JSONUtil
JSONUtil是针对JSONObject和JSONArray的静态快捷方法集合。
JSONUtil.toJsonStr可以将任意对象(Bean、Map、集合等)直接转换为JSON字符串。如果对象是有序的Map等对象,则转换后的JSON字符串也是有序的。
SortedMap<Object, Object> sortedMap = new TreeMap<Object, Object>() {
private static final long serialVersionUID = 1L;
{
put("attributes", "ddd");
put("b", "ggg");
put("c", "fff");
}};
String s = JSONUtil.toJsonStr(sortedMap);
System.out.println(s);//{"attributes":"ddd","b":"ggg","c":"fff"}
//如果我们想获得格式化后的JSON,则:
JSONUtil.toJsonPrettyStr(sortedMap);
//JSON字符串解析
String html = "{\"name\":\"Something must have been changed since you leave\"}";
JSONObject jsonObject = JSONUtil.parseObj(html);
String str = jsonObject.getStr("name");
System.out.println(str);//Something must have been changed since you leave
//JSON转Bean
String json = "{\"ADT\":[[{\"BookingCode\":[\"N\",\"N\"]}]]}";
//json--》price
Price price = JSONUtil.toBean(json, Price.class);
price.getADT().get(0).get(0).getBookingCode().get(0);
大道至简,难得糊涂!有时候真的不需要思考太多造轮子的事情。使用 Hutool 会有种甜甜的在谈恋爱的感觉,快去试试吧~
本文暂时没有评论,来添加一个吧(●'◡'●)