使用Hutool要注意了!升级到6.0后你调用的所有方法都将报错

公众号赵侠客

引言

Hutool这个工具应该是家喻户晓了,它是一个开源的Java工具类库,提供了丰富的静态工具方法来简化Java开发中的常见代码。今天本来是想尝鲜体验一下Hutool新版本都更新了什么新功能,于是从5.x.x升到到了6.0.0,然后就出现了各种包名不存在的错误,我当时就蒙了。

图:Hutool升级6.0后报错

回想当年Mybatis-Plus从2.0升级到3.0时所有包名及方法都需要改一遍的痛苦经历仍然历历在目,至今还有很多项目在使用Mybatis-Plus2.0,因为升级修改的太多了,真的太痛苦了,干脆就不升级了。难道Hutool要重蹈Mybatis-plus的覆辙了?如果你使用了Hutool,以后想要升级到6.0时,那么你将要把所有的包名都改一遍,因为Hutool从5.0升级到6.0后包名全改了!!!

图:StrUtil在Hutool 5.0包名为cn.hutool.*

Hutool的作者Looly在gitee上也回应了6.0包名修改,说是为了兼容性考虑!!!

图:Hutool 作者回应更改包名

为什么改包名?

作者说更改包名是为了大改后能兼容,那为什么包名改成org.dromara?。在搞清为什么要将包名改为org.dromara前我们需要搞清楚这个dromara是什么?从官网介绍来看dromara是一个聚集了一群开源爱好者的非赢利性组织,可以认为是中国版的Apache,那么就很好理解了,开源项目加入Apache那包名肯定要改成org.apache了。

图:Dromara官网

从Dromara 发布的消息来看,Hutool早在2021年3月15号就加入了该组织

图:Dromara宣布Hutool加入

Dromara社区旗下的顶级项目除了Hutool外还有很多我们耳熟能详的项目,我用过的就有:流程引擎框架LiteFlow、ElasticSearch客户端easy-es。

图:Dromara社区的顶级项目

现在大家应该明白Hutool为什么要把包名改成org.dromara了吧?

主要改了哪些

  1. 包名修改,包名变更为org.dromara.hutool
  2. 重新整理规整,内部工具类重新整理规整,减少无用模块,工具类归类到对应package中
  3. 重构Http模块,被人诟病的http模块做重构,采用门面模式,支持包括HttpUrlConnection、HttpClient4、HttpClient5、OkHttp3等库。
  4. 性能优化,在能力范围之内尽量做性能优化,不跟其他高性能库"攀比"。
  5. 做减法,相比5.x版本做减法,大部分工作是删掉一些重复代码和无用的重载,使用上可能会增加代码量,但是相比减少了歧义
  6. 统一构造方法,构建一种对象不再使用混乱的createXXX、newXXX、ofXXX等名字,而是统一使用of或者ofXXX。

包名修改、重新整理规整

Util工具类修改了包名,不仅将所有的cn.hutool改成org.dromara.hutool,还按工具类的用途做了分包, 如字符串类工具类移到了org.dromara.hutool.core.text.,集合类的移到了 org.dromara.hutool.core.collection,时间的移到org.dromara.hutool.core.date*

5.0常用工具类

vbscript 复制代码
 
cn.hutool.core.util.StrUtil.isEmpty("admin");
cn.hutool.core.collection.CollUtil.isEmpty(new ArrayList<>());
cn.hutool.core.date.DateUtil.now();

6.0常用工具类

vbscript 复制代码
org.dromara.hutool.core.text.StrUtil.isEmpty("admin");
org.dromara.hutool.core.collection.CollUtil.isEmpty(new ArrayList<>());
org.dromara.hutool.core.date.DateUtil.now();

重构Http模块

5.0HttpUtill使用方法

java 复制代码
cn.hutool.core.util.StrUtil.isEmpty("admin");
cn.hutool.core.collection.CollUtil.isEmpty(new ArrayList<>());
cn.hutool.core.date.DateUtil.now();

6.0使用了门面模式+依赖SPI机制提供可选引擎

java 复制代码
//默认使用 org.dromara.hutool.http.client.engine.httpclient5.HttpClient5Engine
org.dromara.hutool.http.HttpUtil.get("https://www.baidu.com");    
        
final ClientEngine engine = new OkHttpEngine();
final Request req = Request.of("https://www.baidu.com/").method(Method.GET);
final Response res = engine.send(req);
log.info(res.body().getString());


final ClientEngine jdkHttpEngine = HttpUtil.createClient("jdkClient");
final Response send = jdkHttpEngine.send(Request.of("https://www.baidu.com").method(Method.GET));
log.info(send.body().getString());

//目前支持4种HTTP引擎
org.dromara.hutool.http.client.engine.httpclient5.HttpClient5Engine
org.dromara.hutool.http.client.engine.httpclient4.HttpClient4Engine
org.dromara.hutool.http.client.engine.okhttp.OkHttpEngine
org.dromara.hutool.http.client.engine.jdk.JdkClientEngine 

更多其它不兼容修改

StrUtil

java 复制代码
- StrUtil.utf8Bytes(data));
+ ByteUtil.toUtf8Bytes(data));

NumberUtil

java 复制代码
- import cn.hutool.core.util.NumberUtil;
+ import org.dromara.hutool.core.math.NumberUtil;

ArrayUtil

java 复制代码
- import import cn.hutool.core.util.ArrayUtil;
+ import import org.dromara.hutool.core.array.ArrayUtil;

ObjectUtil

java 复制代码
- cn.hutool.core.util.ObjectUtil.isNotEmpty(obj)
+ org.dromara.hutool.core.util.ObjUtil.isNotEmpty(obj)

lambda整体结构、命名都规范了,以SerXxx开头

java 复制代码
- import cn.hutool.core.lang.func.Func1;
+ import org.dromara.hutool.core.func.SerFunction;
- import cn.hutool.core.lang.Filter;
+ import java.util.function.Predicate;

修改Base64

java 复制代码
- cn.hutool.core.codec.Base64Encoder.encode(encryptAesKey);
+ org.dromara.hutool.core.codec.binary.Base64.encode(encryptAesKey);
- cn.hutool.core.codec.Base64Decoder.decode(pubKey);
+ org.dromara.hutool.core.codec.binary.Base64.decode(pubKey);

generateKey

java 复制代码
- cn.hutool.crypto.SecureUtil.generateKey(str)
+ org.dromara.hutool.crypto.KeyUtil.generateKey(str)

反射操作field

java 复制代码
- cn.hutool.core.util.ReflectUtil.getFields(clazz)
+ org.dromara.hutool.core.reflect.FieldUtil.getFields(clazz)
- ReflectUtil.setFieldValue(clientPrincipal, "authorities", authorities);
+ FieldUtil.setFieldValue(clientPrincipal, "authorities", authorities);

日期时间

java 复制代码
- cn.hutool.core.date.LocalDateTimeUtil
- cn.hutool.core.date.DateUtil.date()
- cn.hutool.core.date.DateUtil;
+ org.dromara.hutool.core.date.DateUtil;
+ org.dromara.hutool.core.date.DateUtil.now();

dfa

java 复制代码
- import cn.hutool.dfa.WordTree;
+ import org.dromara.hutool.core.text.dfa.WordTree;
- cn.hutool.core.text.replacer.ReplacerChain#replace(str)
- org.dromara.hutool.core.text.replacer.ReplacerChain#apply(str)

Dict

java 复制代码
- import cn.hutool.core.lang.Dict;
+ import org.dromara.hutool.core.map.Dict;

JSONObject

java 复制代码
- jsonObject.putOpt(key,value).putOpt(key,value)

UtilException

java 复制代码
- cn.hutool.core.exceptions.UtilException

FileUtil

java 复制代码
- import cn.hutool.core.io.FileUtil;
+ import org.dromara.hutool.core.io.file.FileUtil;
- FileUtil.exist(file))
+ FileUtil.exists(file))
-FileUtil.cleanEmpty
- cn.hutool.core.io.FileUtil.extName(filePath)
+ org.dromara.hutool.core.io.file.FileNameUtil.extName(filePath)

CollUtil

java 复制代码
- cn.hutool.core.collection.CollUtil.newArrayList(obj);
+ org.dromara.hutool.core.collection.ListUtil.of(obj);
- CollUtil.split(phones, 200);
+ CollUtil.partition(phones, 200);
-ArrayUtil.toArray

tree

java 复制代码
- cn.hutool.core.lang.tree.Tree;
- cn.hutool.core.lang.tree.TreeNode;
- cn.hutool.core.lang.tree.TreeUtil;
+ org.dromara.hutool.core.tree.MapTree;
+ org.dromara.hutool.core.tree.TreeNode;
+ org.dromara.hutool.core.tree.TreeUtil;

create -> of

java 复制代码
- cn.hutool.json.JSONConfig.create()
- Xxx.create()
+ org.dromara.hutool.json.JSONConfig.of()
+ Xxx.of()

ReUtil

java 复制代码
- cn.hutool.core.util.ReUtil.RE_CHINESE;
+ org.dromara.hutool.core.regex.PatternPool.CHINESE;

DefaultSegment

java 复制代码
- cn.hutool.core.lang.DefaultSegment#getStartIndex
+ org.dromara.hutool.core.lang.range.DefaultSegment#getBeginIndex

http

java 复制代码
- cn.hutool.http.HttpUtil.post(url, data, timeout)
+ org.dromara.hutool.http.HttpGlobalConfig.setTimeout(TIMEOUT);
+ org.dromara.hutool.http.HttpUtil.post(url, data)
- cn.hutool.http.HttpUtil.toParams(map)
+ org.dromara.hutool.core.net.url.UrlQueryUtil.toQuery(map)

BeanUtil

java 复制代码
- cn.hutool.core.bean.BeanUtil;
- cn.hutool.core.bean.copier.CopyOptions;
+ org.dromara.hutool.core.bean.BeanUtil;
+ org.dromara.hutool.core.bean.copier.CopyOptions;

EnumUtil

java 复制代码
- cn.hutool.core.util.EnumUtil;
+ org.dromara.hutool.core.util.EnumUtil;

IdUtil

java 复制代码
- cn.hutool.core.util.IdUtil;
+ org.dromara.hutool.core.data.id.IdUtil;

RegexPool

java 复制代码
- cn.hutool.core.lang.RegexPool
+ org.dromara.hutool.core.regex.RegexPool

URLDecoder

java 复制代码
- cn.hutool.core.net.URLDecoder;
+ org.dromara.hutool.core.net.url.URLDecoder;

SpringUtil

java 复制代码
- cn.hutool.extra.spring.SpringUtil;
+ org.dromara.hutool.extra.spring.SpringUtil;

SecureUtil

java 复制代码
- cn.hutool.crypto.SecureUtil;
- cn.hutool.crypto.asymmetric.KeyType;
- cn.hutool.crypto.symmetric.AES;
- cn.hutool.core.util.HexUtil;
- cn.hutool.crypto.BCUtil;
- cn.hutool.crypto.SmUtil;
- cn.hutool.crypto.asymmetric.SM2;
- cn.hutool.crypto.symmetric.SM4;
+ org.dromara.hutool.crypto.SecureUtil;
+ org.dromara.hutool.crypto.asymmetric.KeyType;
+ org.dromara.hutool.crypto.symmetric.AES;
+ org.dromara.hutool.core.codec.HexUtil;
+ org.dromara.hutool.crypto.asymmetric.SM2;
+ org.dromara.hutool.crypto.symmetric.SM4;
+ org.dromara.hutool.crypto.bc.BCUtil;
+ org.dromara.hutool.crypto.bc.SmUtil;

ImgUtil

java 复制代码
- cn.hutool.core.img.ImgUtil;
+ org.dromara.hutool.swing.img.ImgUtil;

RandomUtil

java 复制代码
- cn.hutool.core.util.RandomUtil;
+ org.dromara.hutool.core.util.RandomUtil;
- cn.hutool.core.io.IORuntimeException;
- cn.hutool.system.SystemUtil;
- RandomUtil.randomEleList(WORDS, wordCount);
+ RandomUtil.randomEles(WORDS, wordCount);

Captcha

java 复制代码
- cn.hutool.core.img.FontUtil;
- cn.hutool.captcha.CaptchaUtil;
- cn.hutool.captcha.CircleCaptcha;
- cn.hutool.captcha.GifCaptcha;
- cn.hutool.captcha.LineCaptcha;
- cn.hutool.captcha.ShearCaptcha
+ org.dromara.hutool.swing.captcha.CaptchaUtil;
+ org.dromara.hutool.swing.captcha.CircleCaptcha;
+ org.dromara.hutool.swing.captcha.GifCaptcha;
+ org.dromara.hutool.swing.captcha.LineCaptcha;
+ org.dromara.hutool.swing.captcha.ShearCaptcha

IoUtil

java 复制代码
- cn.hutool.core.io.IoUtil;
+ org.dromara.hutool.core.io.IoUtil;

sm2

java 复制代码
- (sm2.decryptFromBcd(content, KeyType.PrivateKey));
+ (sm2.decrypt(content, KeyType.PrivateKey));
- sm2.encryptBcd(content, KeyType.PublicKey);
+ sm2.encryptHex(content, KeyType.PublicKey);

最后

国产开源软件能靠自己活下来都挺不容易,被开源组织收编也是不错的出路,就是苦了我们这些开发者,全国使用Hutool的项目不在少数,针对这次重大改动本子提出一下几点建议:

  1. 重度依赖,这种项目来说最好就不要改了,继续使用5.0,作者说了5.0也会继续维护
  2. 轻度依赖,如果只是用了一些简单的工具类,全局替换包名升级还是可以的
  3. 新项目,我们需要思考有没有必要使用Hutool,是不是可以使用JDK17?很多新功能JDK都自带了,自己项目组是不是也应该维护起属于自己团队的工具类?
相关推荐
赫瑞18 分钟前
数据结构中的排列组合 —— Java实现
java·开发语言·数据结构
Victor35642 分钟前
MongoDB(87)如何使用GridFS?
后端
Victor3561 小时前
MongoDB(88)如何进行数据迁移?
后端
小红的布丁1 小时前
单线程 Redis 的高性能之道
redis·后端
GetcharZp1 小时前
Go 语言只能写后端?这款 2D 游戏引擎刷新你的认知!
后端
冬奇Lab1 小时前
一天一个开源项目(第68篇):DeerFlow - 字节跳动出品的深度研究与超级智能体框架
人工智能·开源·资讯
周末也要写八哥2 小时前
多进程和多线程的特点和区别
java·开发语言·jvm
惜茶2 小时前
vue+SpringBoot(前后端交互)
java·vue.js·spring boot
宁瑶琴2 小时前
COBOL语言的云计算
开发语言·后端·golang
杰克尼3 小时前
springCloud_day07(MQ高级)
java·spring·spring cloud