全⽹最详细Hutool⼯具详解
很多⽅法请看官⽹地址:
简介
Hutool是⼀个⼩⽽全的Java⼯具类库,通过静态⽅法封装,降低相关API的学习成本,提⾼⼯作效率,使Java拥有函数式语⾔般的优雅,让Java语⾔也可以“甜甜的”。
Hutool中的⼯具⽅法来⾃每个⽤户的精雕细琢,它涵盖了Java开发底层代码中的⽅⽅⾯⾯,它既是⼤型项⽬开发中解决⼩问题的利器,也是⼩型项⽬中的效率担当;
Hutool是项⽬中“util”包友好的替代,它节省了开发⼈员对项⽬中公⽤类和公⽤⼯具⽅法的封装时间,使开发专注于业务,同时可以最⼤限度的避免封装不完善带来的bug。
Hutool名称的由来
Hutool = Hu + tool,是原公司项⽬底层代码剥离后的开源库,“Hu”是公司名称的表⽰,tool表⽰⼯具。Hutool谐⾳“糊涂”,⼀⽅⾯简洁易懂,⼀⽅⾯寓意“难得糊涂”。
Hutool如何改变我们的coding⽅式
Hutool的⽬标是使⽤⼀个⼯具⽅法代替⼀段复杂代码,从⽽最⼤限度的避免“复制粘贴”代码的问题,彻底改变我们写代码的⽅式。
以计算MD5为例:
【以前】打开搜索引擎 -> 搜“Java MD5加密” -> 打开某篇博客-> 复制粘贴 -> 改改好⽤
【现在】引⼊Hutool -> SecureUtil.md5()
Hutool的存在就是为了减少代码搜索成本,避免⽹络上参差不齐的代码出现导致的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封装
Maven
在项⽬的l的dependencies中加⼊以下内容:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.2</version>
</dependency>
痛点
在Java开发中我们要⾯对各种各样的类型转换问题,尤其是从命令⾏获取的⽤户参数、从HttpRequest获取的Parameter等等,这些参数类型多种多样,我们怎么去转换他们呢?常⽤的办法是先整成String,然后调⽤XXX.parseXXX⽅法,还要承受转换失败的风险,不得不加⼀层try catch,这个⼩⼩的过程混迹在业务代码中会显得⾮常难看和臃肿。
Convert类
Convert类可以说是⼀个⼯具⽅法类,⾥⾯封装了针对Java常见类型的转换,⽤于简化类型转换。Convert类中⼤部分⽅法为toXXX,参数为Object,可以实现将任意可能的类型转换为指定类型。同时⽀持第⼆个参数defaultValue⽤于在转换失败时返回⼀个默认值。
Java常见类型转换
1.转换为字符串:
int a = 1;
//aStr为"1"
String aStr = Str(a);
long[] b = {1,2,3,4,5};
//bStr为:"[1, 2, 3, 4, 5]"
String bStr = Str(b);
2.转换为指定类型数组:
String[] b = { "1", "2", "3", "4" };
//结果为Integer数组
Integer[] intArray = IntArray(b);
long[] c = {1,2,3,4,5};
//结果为Integer数组
Integer[] intArray2 = IntArray(c);
3.转换为⽇期对象:
String a = "2017-05-06";
Date value = Date(a);
4.转换为集合
Object[] a = {"a", "你", "好", "", 1};
List<?> list = vert(List.class, a);
//从4.1.11开始可以这么⽤
List<?> list = List(a);字符串转数组编码方式
其它类型转换
1.标准类型
通过vert(Class, Object)⽅法可以将任意类型转换为指定类型,Hutool中预定义了许多类型转换,例如转换为URI、URL、Calendar等等,这些类型的转换都依托于ConverterRegistry类。通过这个类和Converter接⼝,我们可以⾃定义⼀些类型转换。详细的使⽤请参阅“⾃定义类型转换”⼀节。
2.泛型类型
通过convert(TypeReference reference, Object value)⽅法,⾃⾏new⼀个TypeReference对象可以对嵌套泛型进⾏类型转换。例如,我们想转换⼀个对象为List类型,此时传⼊的标准Class就⽆法满⾜要求,此时我们可以这样:
Object[] a = { "a", "你", "好", "", 1 };
List<String> list = vert(new TypeReference<List<String>>() {}, a);
通过TypeReference实例化后制定泛型类型,即可转换对象为我们想要的⽬标类型。
16进制(Hex)
在很多加密解密,以及中⽂字符串传输(⽐如表单提交)的时候,会⽤到16进制转换,就是Hex转换,为此Hutool中专门封装了HexUtil⼯具类,考虑到16进制转换也是转换的⼀部分,因此将其⽅法也放在Convert类中,便于理解和查,使⽤同样⾮常简单:
转为16进制(Hex)字符串
String a = "我是⼀个⼩⼩的可爱的字符串";
//结果:"e68891e698afe4b880e4b8aae5b08fe5b08fe79a84e58fafe788b1e79a84e5ad97e7aca6e4b8b2"
String hex = Hex(a, CharsetUtil.CHARSET_UTF_8);
将16进制(Hex)字符串转为普通字符串:
String hex = "e68891e698afe4b880e4b8aae5b08fe5b08fe79a84e58fafe788b1e79a84e5ad97e7aca6e4b8b2";
//结果为:"我是⼀个⼩⼩的可爱的字符串"
String raw = Convert.hexStrToStr(hex, CharsetUtil.CHARSET_UTF_8);
//注意:在4.1.11之后hexStrToStr将改名为hexToStr
String raw = Convert.hexToStr(hex, CharsetUtil.CHARSET_UTF_8);
因为字符串牵涉到编码问题,因此必须传⼊编码对象,此处使⽤UTF-8编码。 toHex⽅法同样⽀持传⼊byte[],同样也可以使⽤hexToBytes⽅法将16进制转为byte[]
Unicode和字符串转换
与16进制类似,Convert类同样可以在字符串和Unicode之间轻松转换:
String a = "我是⼀个⼩⼩的可爱的字符串";
//结果为:"\\u6211\\u662f\\u4e00\\u4e2a\\u5c0f\\u5c0f\\u7684\\u53ef\\u7231\\u7684\\u5b57\\u7b26\\u4e32"
String unicode = Convert.strToUnicode(a);
//结果为:"我是⼀个⼩⼩的可爱的字符串"
String raw = Convert.unicodeToStr(unicode);
编码转换
在接收表单的时候,我们常常被中⽂乱码所困扰,其实⼤多数原因是使⽤了不正确的编码⽅式解码了数
据。于是vertCharset⽅法便派上⽤场了,它可以把乱码转为正确的编码⽅式:
String a = "我不是乱码";
//转换后result为乱码
String result = vertCharset(a, CharsetUtil.UTF_8, CharsetUtil.ISO_8859_1);
String raw = vertCharset(result, CharsetUtil.ISO_8859_1, "UTF-8");
Assert.assertEquals(raw, a);
注意经过测试,UTF-8编码后⽤GBK解码再⽤GBK编码后⽤UTF-8解码会存在某些中⽂转换失败的问题。
时间单位转换
long a = 4535345;
//结果为:75
long minutes = vertTime(a, TimeUnit.MILLISECONDS, TimeUnit.MINUTES);
⾦额⼤⼩写转换
⾯对财务类需求,Convert.digitToChinese将⾦钱数转换为⼤写形式:
double a = 67556.32;
//结果为:"陆万柒仟伍佰伍拾陆元叁⾓贰分"
String digitUppercase = Convert.digitToChinese(a);
注意转换为⼤写只能精确到分(⼩数点⼉后两位),之后的数字会被忽略。
原始类和包装类转换
有的时候,我们需要将包装类和原始类相互转换(⽐如Integer.class 和 int.class),这时候我们可以:
//去包装
Class<?> wrapClass = Integer.class;
//结果为:int.class
Class<?> unWraped = Convert.unWrap(wrapClass);
//包装
Class<?> primitiveClass = long.class;
//结果为:Long.class
Class<?> wraped = Convert.wrap(primitiveClass);
格式化为字符串
调⽤toString()⽅法即可返回格式为yyyy-MM-dd HH:mm:ss的字符串,调⽤toString(String format)可以返回指定格式的字符串。DateTime dateTime = new DateTime("2017-01-05 12:34:23", DatePattern.NORM_DATETIME_FORMAT);
//结果:2017-01-05 12:34:23
String dateStr = String();
//结果:2017/01/05
LocalDateTime⼯具-LocalDateTimeUtil
使⽤
⽇期转换
String dateStr = "2020-01-23T12:23:56";
DateTime dt = DateUtil.parse(dateStr);
// Date对象转换为LocalDateTime
LocalDateTime of = LocalDateTimeUtil.of(dt);
// 时间戳转换为LocalDateTime
of = LocalDateTimeUtil.Time());
⽇期字符串解析
// 解析ISO时间
LocalDateTime localDateTime = LocalDateTimeUtil.parse("2020-01-23T12:23:56");
// 解析⾃定义格式时间
localDateTime = LocalDateTimeUtil.parse("2020-01-23", DatePattern.NORM_DATE_PATTERN);
解析同样⽀持LocalDate:
LocalDate localDate = LocalDateTimeUtil.parseDate("2020-01-23");
// 解析⽇期时间为LocalDate,时间部分舍弃
localDate = LocalDateTimeUtil.parseDate("2020-01-23T12:23:56", DateTimeFormatter.ISO_DATE_TIME);
⽇期格式化
LocalDateTime localDateTime = LocalDateTimeUtil.parse("2020-01-23T12:23:56");
// "2020-01-23 12:23:56"
String format = LocalDateTimeUtil.format(localDateTime, DatePattern.NORM_DATETIME_PATTERN);
⽇期偏移
final LocalDateTime localDateTime = LocalDateTimeUtil.parse("2020-01-23T12:23:56");
// 增加⼀天
// "2020-01-24T12:23:56"
LocalDateTime offset = LocalDateTimeUtil.offset(localDateTime, 1, ChronoUnit.DAYS);
如果是减少时间,offset第⼆个参数传负数即可:
// "2020-01-22T12:23:56"
offset = LocalDateTimeUtil.offset(localDateTime, -1, ChronoUnit.DAYS);
⽇期偏移
LocalDateTime start = LocalDateTimeUtil.parse("2019-02-02T00:00:00");
LocalDateTime end = LocalDateTimeUtil.parse("2020-02-02T00:00:00");
Duration between = LocalDateTimeUtil.between(start, end);
// 365
⼀天的开始和结束
LocalDateTime localDateTime = LocalDateTimeUtil.parse("2020-01-23T12:23:56");
// "2020-01-23T00:00"
LocalDateTime beginOfDay = LocalDateTimeUtil.beginOfDay(localDateTime);
// "2020-01-23T23:59:59.999999999"
LocalDateTime endOfDay = dOfDay(localDateTime);
字符串⼯具-StrUtil
这两个是去掉字符串的前缀后缀的,例如去个⽂件名的扩展名啥。
String fileName = veSuffix("pretty_girl.jpg", ".jpg") //fileName -> pretty_girl
还有忽略⼤⼩写的removePrefixIgnoreCase和removeSuffixIgnoreCase都⽐较实⽤。
2. sub⽅法
不得不提⼀下这个⽅法,有⼈说String有了subString你还写它⼲啥,我想说subString⽅法越界啥的都会报异常,你还得⾃⼰判断,难受死了,我把各种情况判断都加进来了,⽽且index的位置还⽀持负数哦,-1表⽰最后⼀个字符(这个思想来⾃于Python,如果学过Python的应该会很喜欢的),还有就是如果不⼩⼼把第⼀个位置和第⼆个位置搞反了,也会⾃动修正(例如想截取第4个和第2个字符之间的部分也是可以的哦~)举个栗⼦
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.format⽅法
String template = "{}爱{},就像⽼⿏爱⼤⽶";
String str = StrUtil.format(template, "我", "你"); //str -> 我爱你,就像⽼⿏爱⼤⽶
参数我定义成了Object类型,如果传别的类型的也可以,会⾃动调⽤toString()⽅法的。
Digester
以MD5为例:
Digester md5 = new Digester(DigestAlgorithm.MD5);
// 5393554e94bf0eb6436f240a4fd71282
String digestHex = md5.digestHex(testStr);
当然,做为最为常⽤的⽅法,MD5等⽅法被封装为⼯具⽅法在DigestUtil中,以上代码可以进⼀步简化为:
// 5393554e94bf0eb6436f240a4fd71282
String md5Hex1 = DigestUtil.md5Hex(testStr);
Hutool-http
最简单的使⽤莫过于⽤HttpUtil⼯具类快速请求某个页⾯:
//GET请求
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论