当前位置: 首页 > 工具软件 > Hutool > 使用案例 >

hutool使用

倪德业
2023-12-01

Hutool是一个Java工具包,它帮助我们简化每一行代码,避免重复造轮子。如果你有需要用到某些工具方法的时候,不妨在Hutool里面找找,可能就有。

简介

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。

Hutool中的工具方法来自每个用户的精雕细琢,它涵盖了Java开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当;

Hutool是项目中“util”包友好的替代,它节省了开发人员对项目中公用类和公用工具方法的封装时间,使开发专注于业务,同时可以最大限度的避免封装不完善带来的bug。

一个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)封装实现
    可以根据需求对每个模块单独引入,也可以通过引入hutool-all方式引入所有

Hutool-all是一个Hutool的集成打包产品,由于考虑到“懒人”用户及分不清各个模块作用的用户,“无脑”引入hutool-all模块是快速开始和深入应用的最佳方式。

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.4.1</version>
</dependency>

常用工具类

1.DateUtil

日期时间工具类,定义了一些常用的日期时间操作方法。

Date、long、Calendar之间的相互转换

//当前时间
Date date = DateUtil.date();
//当前时间
Date date2 = DateUtil.date(Calendar.getInstance());
//当前时间
Date date3 = DateUtil.date(System.currentTimeMillis());
//当前时间字符串,格式:yyyy-MM-dd HH:mm:ss
String now = DateUtil.now();
//当前日期字符串,格式:yyyy-MM-dd
String today= DateUtil.today();

字符串转日期

DateUtil.parse方法会自动识别一些常用格式,包括:

yyyy-MM-dd HH:mm:ss
 
yyyy-MM-dd
 
HH:mm:ss
 
yyyy-MM-dd HH:mm
 
yyyy-MM-dd HH:mm:ss.SSS
 
String dateStr = "2020-03-01";
Date date = DateUtil.parse(dateStr);

我们也可以使用自定义日期格式转化:

String dateStr = "2020/03/02";
Date date = DateUtil.parse(dateStr, "yyyy/MM/dd");

格式化日期输出

//结果 2020/03/01
String format = DateUtil.format(date, "yyyy/MM/dd");
​
//常用格式的格式化
String formatDate = DateUtil.formatDate(date);
String formatDateTime = DateUtil.formatDateTime(date);
String formatTime = DateUtil.formatTime(date);

获取Date对象的某个部分

//获得年的部分
int year = DateUtil.year(date);
//获得月份,从0开始计数
int month = DateUtil.month(date);
//获得月份,从0开始计数
Month monthEnum = DateUtil.monthEnum(date);
//获得日
int dayOfMonth = DateUtil.dayOfMonth(date);
//获得星期数,从周日算起
int dayOfWeek = DateUtil.dayOfWeek(date);
//获得星期枚举
Week dayOfWeekEnum = DateUtil.dayOfWeekEnum(date);

开始和结束时间
有的时候我们需要获得每天的开始时间、结束时间,每月的开始和结束时间等等,DateUtil也提供了相关方法:

//一天的开始,结果:2020-03-01 00:00:00
Date beginOfDay = DateUtil.beginOfDay(date);
​
//一天的结束,结果:2020-03-01 23:59:59
Date endOfDay = DateUtil.endOfDay(date);

日期时间偏移

日期或时间的偏移指针对某个日期增加或减少分、小时、天等等,达到日期变更的目的。Hutool也针对其做了大量封装

Date newDate = DateUtil.offset(date, DateField.DAY_OF_MONTH, 2);
​
DateTime newDate2 = DateUtil.offsetDay(date, 3);
​
DateTime newDate3 = DateUtil.offsetHour(date, -3);

针对当前时间,提供了简化的偏移方法(例如昨天、上周、上个月等):

//昨天
DateUtil.yesterday()
//明天
DateUtil.tomorrow()
//上周
DateUtil.lastWeek()
//下周
DateUtil.nextWeek()
//上个月
DateUtil.lastMonth()
//下个月
DateUtil.nextMonth()

日期时间差
有时候我们需要计算两个日期之间的时间差(相差天数、相差小时数等等),Hutool将此类方法封装为between方法:

long betweenDay = DateUtil.between(date1, date2, DateUnit.DAY);

计时器

计时器用于计算某段代码或过程花费的时间

TimeInterval timer = DateUtil.timer();
 
//---------------------------------
//-------这是执行过程
//---------------------------------
 
timer.interval();//花费毫秒数
timer.intervalRestart();//返回花费时间,并重置开始时间
timer.intervalMinute();//花费分钟数

其它

//年龄
DateUtil.ageOfNow("1993-03-01");
 
//是否闰年
DateUtil.isLeapYear(2017);

2.Convert

类型转换工具类,用于各种类型数据的转换。里面封装了针对Java常见类型的转换,用于简化类型转换。Convert类中大部分方法为toXXX,参数为Object,可以实现将任意可能的类型转换为指定类型。同时支持第二个参数defaultValue用于在转换失败时返回一个默认值。

Java常见类型转换

转换为字符串:

int a = 1;
//aStr为"1"
String aStr = Convert.toStr(a);

long[] b = {1,2,3,4,5};
//bStr为:"[1, 2, 3, 4, 5]"
String bStr = Convert.toStr(b);

转换为指定类型数组:

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 = "2020-03-01";
Date value = Convert.toDate(a);

转换为集合

Object[] a = {"a", "你", "好", "", 1};
List<?> list = Convert.convert(List.class, a);
//从4.1.11开始可以这么用
List<?> list = Convert.toList(a);

其它类型转换

标准类型

通过Convert.convert(Class, Object)方法可以将任意类型转换为指定类型,Hutool中预定义了许多类型转换,例如转换为URI、URL、Calendar等等。

泛型类型

通过convert(TypeReference reference, Object value)方法,自行new一个TypeReference对象可以对嵌套泛型进行类型转换。例如,我们想转换一个对象为List类型,此时传入的标准Class就无法满足要求,此时我们可以这样:

Object[] a = { “a”, “你”, “好”, “”, 1 };
List list = Convert.convert(new TypeReference<List>() {}, a);
复制代码
通过TypeReference实例化后制定泛型类型,即可转换对象为我们想要的目标类型。

半角和全角转换

在很多文本的统一化中这两个方法非常有用,主要对标点符号的全角半角转换。

半角转全角:

String a = "123456789,$()?!:;";
 
//结果为:"123456789,$()?!:;"
String sbc = Convert.toSBC(a);

全角转半角:

String a = "123456789,$()?!:;";
 
//结果为"123456789,$()?!:;"
String dbc = Convert.toDBC(a);

16进制(Hex)

在很多加密解密,以及中文字符串传输(比如表单提交)的时候,会用到16进制转换,就是Hex转换,为此Hutool中专门封装了HexUtil工具类,考虑到16进制转换也是转换的一部分,因此将其方法也放在Convert类中,便于理解和查找,使用同样非常简单:

转为16进制(Hex)字符串

String a = "字符串";
String hex = Convert.toHex(a, CharsetUtil.CHARSET_UTF_8);

将16进制(Hex)字符串转为普通字符串:

String hex = "e5ad97e7aca6e4b8b2";
String raw = Convert.hexToStr(hex, CharsetUtil.CHARSET_UTF_8);

因为字符串牵涉到编码问题,因此必须传入编码对象,此处使用UTF-8编码。 toHex方法同样支持传入byte[],同样也可以使用hexToBytes方法将16进制转为byte[]

Unicode和字符串转换

与16进制类似,Convert类同样可以在字符串和Unicode之间轻松转换:

String unicode = Convert.strToUnicode(a);
String raw = Convert.unicodeToStr(unicode);

编码转换

在接收表单的时候,我们常常被中文乱码所困扰,其实大多数原因是使用了不正确的编码方式解码了数据。于是Convert.convertCharset方法便派上用场了,它可以把乱码转为正确的编码方式:

String a = "我不是乱码";
//转换后result为乱码
String result = Convert.convertCharset(a, CharsetUtil.UTF_8, CharsetUtil.ISO_8859_1);
String raw = Convert.convertCharset(result, CharsetUtil.ISO_8859_1, "UTF-8");
Assert.assertEquals(raw, a);

时间单位转换

Convert.convertTime方法主要用于转换时长单位,比如一个很大的毫秒,我想获得这个毫秒数对应多少分:

long a = 4535345;
 
//结果为:75
long minutes = Convert.convertTime(a, TimeUnit.MILLISECONDS, TimeUnit.MINUTES);

金额大小写转换

面对财务类需求,Convert.digitToChinese将金钱数转换为大写形式:

double money = 1234.56;
 
//结果为:"壹仟贰佰叁拾肆元伍角陆分"
String digitUppercase = Convert.digitToChinese(a);

注意 转换为大写只能精确到分(小数点儿后两位),之后的数字会被忽略。

原始类和包装类转换

有的时候,我们需要将包装类和原始类相互转换(比如Integer.classs 和 int.class),这时候我们可以:

//去包装
Class<?> wrapClass = Integer.class;
//结果为:int.class
Class<?> unWraped = Convert.unWrap(wrapClass);
 
//包装
Class<?> primitiveClass = long.class;
//结果为:Long.class
Class<?> wraped = Convert.wrap(primitiveClass);

3.StrUtil

字符串工具类,定义了一些常用的字符串操作方法。

hasBlank、hasEmpty方法

就是给定一些字符串,如果一旦有空的就返回true,常用于判断好多字段是否有空的(例如web表单数据)。

这两个方法的区别是hasEmpty只判断是否为null或者空字符串(“”),hasBlank则会把不可见字符也算做空,isEmpty和isBlank同理。

removePrefix、removeSuffix方法

这两个是去掉字符串的前缀后缀的,例如去个文件名的扩展名啥。

String fileName = StrUtil.removeSuffix("pretty_girl.jpg", ".jpg")  //fileName -> pretty_girl
还有忽略大小写的removePrefixIgnoreCase和removeSuffixIgnoreCase都比较实用。

sub方法

subString方法越界会报异常,得自己判断,sub把各种情况判断都加进来了,而且index的位置还支持负数,-1表示最后一个字符,如果不小心把第一个位置和第二个位置搞反了,也会自动修正

String str = "abcdefgh";
String strSub1 = StrUtil.sub(str, 2, 3);
String strSub2 = StrUtil.sub(str, 2, -3); 
String strSub3 = StrUtil.sub(str, 3, 2); 

format方法

String template = "{}和{}";
String str = StrUtil.format(template, "我", "你");
复制代码
参数是Object类型,传别的类型会自动调用toString()方法。

4.NumberUtil

数字处理工具类,可用于各种类型数字的加减乘除操作及判断类型。

double n1 = 1.234;
double n2 = 1.234;
double result;
//对float、double、BigDecimal做加减乘除操作
result = NumberUtil.add(n1, n2);
result = NumberUtil.sub(n1, n2);
result = NumberUtil.mul(n1, n2);
result = NumberUtil.div(n1, n2);
//保留两位小数
BigDecimal roundNum = NumberUtil.round(n1, 2);
String n3 = "1.234";
//判断是否为数字、整数、浮点数
NumberUtil.isNumber(n3);
NumberUtil.isInteger(n3);
NumberUtil.isDouble(n3);

5.BeanUtil

JavaBean的工具类,可用于Map与JavaBean对象的互相转换以及对象属性的拷贝。

Map转Bean

提供了Map对象键值对注入Bean,其方法有:

BeanUtil.fillBeanWithMap 使用Map填充bean

HashMap<String, Object> map = CollUtil.newHashMap();
map.put("name", "Joe");
map.put("age", 12);
map.put("openId", "DFDFSDFWERWER");
 
Person person = BeanUtil.fillBeanWithMap(map, new Person(), false);

BeanUtil.fillBeanWithMapIgnoreCase 使用Map填充bean,忽略大小写

HashMap<String, Object> map = CollUtil.newHashMap();
map.put("Name", "yxm");
map.put("aGe", 12);
map.put("openId", "DFDFSDFWERWER");
Person person = BeanUtil.fillBeanWithMapIgnoreCase(map, new Person(), false);

同时提供了map转bean的方法,与fillBean不同的是,此处并不是传Bean对象,而是Bean类,Hutool会自动调用默认构造方法创建对象。当然,前提是Bean类有默认构造方法(空构造),这些方法有:
mapToBean,mapToBeanIgnoreCase

// 设置别名,用于对应bean的字段名
HashMap<String, String> mapping = CollUtil.newHashMap();
mapping.put("a_name", "name");
mapping.put("b_age", "age");
Person person = BeanUtil.mapToBean(map, Person.class, CopyOptions.create().setFieldMapping(mapping));

Bean转为Map

BeanUtil.beanToMap方法则是将一个Bean对象转为Map对象。

Person person = new Person();
person.setAge(14);
person.setOpenid("11213232");
person.setName("测试A11");
person.setSubName("sub名字");
 
Map<String, Object> map = BeanUtil.beanToMap(person);

Bean转Bean

Bean之间的转换主要是相同属性的复制,因此方法名为copyProperties,此方法支持Bean和Map之间的字段复制。

BeanUtil.copyProperties方法同样提供一个CopyOptions参数用于自定义属性复制。

Person p1 = new Person();
p1.setSlow(true);
p1.setName("测试");
p1.setSubName("sub测试");
 
Map<String, Object> map = MapUtil.newHashMap();
 
BeanUtil.copyProperties(p1, map);

6.ReflectUtil

Java反射工具类,可用于反射获取类的方法及创建对象。

//获取某个类的所有方法
Method[] methods = ReflectUtil.getMethods(PmsBrand.class);
//获取某个类的指定方法
Method method = ReflectUtil.getMethod(PmsBrand.class, "getId");
//使用反射来创建对象
PmsBrand pmsBrand = ReflectUtil.newInstance(PmsBrand.class);
//反射执行对象的方法
ReflectUtil.invoke(pmsBrand, "setId", 1);

7.CollUtil

集合操作的工具类,定义了一些常用的集合操作。

//数组转换为列表
String[] array = new String[]{"a", "b", "c", "d", "e"};
List<String> list = CollUtil.newArrayList(array);
List<String> list2 = CollUtil.newArrayList("1","2","3");
//join:数组转字符串时添加连接符号
String joinStr = CollUtil.join(list, ",");
//将以连接符号分隔的字符串再转换为列表
List<String> splitList = StrUtil.split(joinStr, ',');
//创建新的Map、Set、List
HashMap<Object, Object> newMap = CollUtil.newHashMap();
HashSet<Object> newHashSet = CollUtil.newHashSet();
ArrayList<Object> newList = CollUtil.newArrayList();
//判断列表是否为空
CollUtil.isEmpty(list);

zip方法:给定两个集合,然后两个集合中的元素一一对应,成为一个Map。此方法还有一个重载方法,可以传字符,然后给定分分隔符,字符串会被split成列表。

List<String> keys = CollUtil.newArrayList("a", "b", "c");
List<Integer> values = CollUtil.newArrayList(1, 2, 3);
Map<String, Integer> map = CollUtil.zip(keys, values);
System.out.println(map);    // {b=2, c=3, a=1}
​
String a = "a,b,c";
String b = "1,2,3";
Map<String, String> map2 = CollUtil.zip(a, b, ",");
System.out.println(map2);   // {b=2, c=3, a=1}

8.MapUtil

Map操作工具类,可用于创建Map对象及判断Map是否为空。

//将多个键值对加入到Map中
Map<Object, Object> map = MapUtil.of(new String[][]{
    {"key1", "value1"},
    {"key2", "value2"},
    {"key3", "value3"}
});
//判断Map是否为空
MapUtil.isEmpty(map);
MapUtil.isNotEmpty(map);
  • toListMap 行转列,合并相同的键,值合并为列表,将Map列表中相同key的值组成列表做为Map的value,例如传入数据是:
    [ {a: 1, b: 1, c: 1} {a: 2, b: 2} {a: 3, b: 3} {a: 4} ]
    结果为:
    { a: [1,2,3,4] b: [1,2,3,] c: [1] }

  • toMapList 列转行。将Map中值列表分别按照其位置与key组成新的map

  • join、joinIgnoreNull 将Map按照给定的分隔符转换为字符串

  • reverse Map的键和值互换

  • sort 排序Map

  • getAny 获取Map的部分key生成新的Map

  • get、getXXX 获取Map中指定类型的值

9.AnnotationUtil

注解工具类,可用于获取注解与注解中指定的值。

//获取指定类、方法、字段、构造器上的注解列表
Annotation[] annotationList = AnnotationUtil.getAnnotations(HutoolController.class, false);
//获取指定类型注解
Api api = AnnotationUtil.getAnnotation(HutoolController.class, Api.class);
//获取指定类型注解的值
Object annotationValue = AnnotationUtil.getAnnotationValue(HutoolController.class, RequestMapping.class);

10.SecureUtil

加密解密工具类,可用于MD5加密。

//MD5加密

String str = "123456";
String md5Str = SecureUtil.md5(str);
LOGGER.info("secureUtil md5:{}", md5Str);

对称加密

SecureUtil.aes

SecureUtil.des

摘要算法

SecureUtil.md5

SecureUtil.sha1

SecureUtil.hmac

SecureUtil.hmacMd5

SecureUtil.hmacSha1

非对称加密

SecureUtil.rsa

SecureUtil.dsa

UUID

SecureUtil.simpleUUID 方法提供无“-”的UUID

密钥生成

SecureUtil.generateKey 针对对称加密生成密钥

SecureUtil.generateKeyPair 生成密钥对(用于非对称加密)

SecureUtil.generateSignature 生成签名(用于非对称加密)

11. JWTUtil

JWT创建

Map<String, Object> map = new HashMap<String, Object>() {
    private static final long serialVersionUID = 1L;
    {
        put("uid", Integer.parseInt("123"));
        put("expire_time", System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 15);
    }
};

JWTUtil.createToken(map, "1234".getBytes());

JWT解析

String rightToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9." +
    "eyJzdWIiOiIxMjM0NTY3ODkwIiwiYWRtaW4iOnRydWUsIm5hbWUiOiJsb29seSJ9." +
    "U2aQkC2THYV9L0fTN-yBBI7gmo5xhmvMhATtu8v0zEA";

final JWT jwt = JWTUtil.parseToken(rightToken);

jwt.getHeader(JWTHeader.TYPE);
jwt.getPayload("sub");

JWT验证

String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9." +
    "eyJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbImFsbCJdLCJleHAiOjE2MjQwMDQ4MjIsInVzZXJJZCI6MSwiYXV0aG9yaXRpZXMiOlsiUk9MRV_op5LoibLkuozlj7ciLCJzeXNfbWVudV8xIiwiUk9MRV_op5LoibLkuIDlj7ciLCJzeXNfbWVudV8yIl0sImp0aSI6ImQ0YzVlYjgwLTA5ZTctNGU0ZC1hZTg3LTVkNGI5M2FhNmFiNiIsImNsaWVudF9pZCI6ImhhbmR5LXNob3AifQ." +
    "aixF1eKlAKS_k3ynFnStE7-IRGiD5YaqznvK2xEjBew";

JWTUtil.verify(token, "123456".getBytes());   

12.ExcelUtil

从文件中读取Excel为ExcelReader

ExcelReader reader = ExcelUtil.getReader(FileUtil.file("test.xlsx"));

从流中读取Excel为ExcelReader(比如从ClassPath中读取Excel文件)

ExcelReader reader = ExcelUtil.getReader(ResourceUtil.getStream("aaa.xlsx"));

读取指定的sheet

ExcelReader reader;

//通过sheet编号获取
reader = ExcelUtil.getReader(FileUtil.file("test.xlsx"), 0);
//通过sheet名获取
reader = ExcelUtil.getReader(FileUtil.file("test.xlsx"), "sheet1");

读取大数据量的Excel

private RowHandler createRowHandler() {
    return new RowHandler() {
        @Override
        public void handle(int sheetIndex, int rowIndex, List<Object> rowlist) {
            Console.log("[{}] [{}] {}", sheetIndex, rowIndex, rowlist);
        }
    };
}

ExcelUtil.readBySax("aaa.xlsx", 0, createRowHandler());

参考文档:
https://blog.csdn.net/qq_35946055/article/details/112257441
API:
https://apidoc.gitee.com/dromara/hutool/
https://hutool.cn/docs/index.html#/

 类似资料: