From 5be66c636b7f0ccde22703b3cb5eee5dcfce30dc Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 12 Nov 2023 19:17:19 +0800 Subject: [PATCH 01/45] prepare 5.8.24 --- CHANGELOG.md | 7 +++++++ README-EN.md | 6 +++--- README.md | 6 +++--- bin/version.txt | 2 +- docs/js/version.js | 2 +- hutool-all/pom.xml | 2 +- hutool-aop/pom.xml | 2 +- hutool-bloomFilter/pom.xml | 2 +- hutool-bom/pom.xml | 2 +- hutool-cache/pom.xml | 2 +- hutool-captcha/pom.xml | 2 +- hutool-core/pom.xml | 2 +- hutool-cron/pom.xml | 2 +- hutool-crypto/pom.xml | 2 +- hutool-db/pom.xml | 2 +- hutool-dfa/pom.xml | 2 +- hutool-extra/pom.xml | 2 +- hutool-http/pom.xml | 2 +- hutool-json/pom.xml | 2 +- hutool-jwt/pom.xml | 2 +- hutool-log/pom.xml | 2 +- hutool-poi/pom.xml | 2 +- hutool-script/pom.xml | 2 +- hutool-setting/pom.xml | 2 +- hutool-socket/pom.xml | 2 +- hutool-system/pom.xml | 2 +- pom.xml | 2 +- 27 files changed, 37 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db857215e..9f83bec8d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ # 🚀Changelog +------------------------------------------------------------------------------------------------------------- +# 5.8.24(2023-11-12) + +### 🐣新特性 + +### 🐞Bug修复 + ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) diff --git a/README-EN.md b/README-EN.md index 12c571594..6deac7710 100755 --- a/README-EN.md +++ b/README-EN.md @@ -151,18 +151,18 @@ We provide the T-Shirt and Sweater with Hutool Logo, please visit the shop: cn.hutool hutool-all - 5.8.23 + 5.8.24 ``` ### 🍐Gradle ``` -implementation 'cn.hutool:hutool-all:5.8.23' +implementation 'cn.hutool:hutool-all:5.8.24' ``` ## 📥Download -- [Maven Repo](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.23/) +- [Maven Repo](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.24/) > 🔔️note: > Hutool 5.x supports JDK8+ and is not tested on Android platforms, and cannot guarantee that all tool classes or tool methods are available. diff --git a/README.md b/README.md index c3df8cd0b..c093a728b 100755 --- a/README.md +++ b/README.md @@ -144,20 +144,20 @@ Hutool = Hu + tool,是原公司项目底层代码剥离后的开源库,“Hu cn.hutool hutool-all - 5.8.23 + 5.8.24 ``` ### 🍐Gradle ``` -implementation 'cn.hutool:hutool-all:5.8.23' +implementation 'cn.hutool:hutool-all:5.8.24' ``` ### 📥下载jar 点击以下链接,下载`hutool-all-X.X.X.jar`即可: -- [Maven中央库](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.23/) +- [Maven中央库](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.24/) > 🔔️注意 > Hutool 5.x支持JDK8+,对Android平台没有测试,不能保证所有工具类或工具方法可用。 diff --git a/bin/version.txt b/bin/version.txt index e1ff3f5ba..2ee3614df 100755 --- a/bin/version.txt +++ b/bin/version.txt @@ -1 +1 @@ -5.8.23 +5.8.24 diff --git a/docs/js/version.js b/docs/js/version.js index 9096578c0..08f1b8dce 100755 --- a/docs/js/version.js +++ b/docs/js/version.js @@ -1 +1 @@ -var version = '5.8.23' \ No newline at end of file +var version = '5.8.24' \ No newline at end of file diff --git a/hutool-all/pom.xml b/hutool-all/pom.xml index 9ebe69fa5..98a2b0b45 100755 --- a/hutool-all/pom.xml +++ b/hutool-all/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-all diff --git a/hutool-aop/pom.xml b/hutool-aop/pom.xml index 116a07ea7..a386d492d 100755 --- a/hutool-aop/pom.xml +++ b/hutool-aop/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-aop diff --git a/hutool-bloomFilter/pom.xml b/hutool-bloomFilter/pom.xml index 972014aa9..99450138a 100755 --- a/hutool-bloomFilter/pom.xml +++ b/hutool-bloomFilter/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-bloomFilter diff --git a/hutool-bom/pom.xml b/hutool-bom/pom.xml index 89acf6ca8..75c000811 100755 --- a/hutool-bom/pom.xml +++ b/hutool-bom/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-bom diff --git a/hutool-cache/pom.xml b/hutool-cache/pom.xml index 2f4d809cd..ce50b14ad 100755 --- a/hutool-cache/pom.xml +++ b/hutool-cache/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-cache diff --git a/hutool-captcha/pom.xml b/hutool-captcha/pom.xml index 0f358a72b..3e9249d1c 100755 --- a/hutool-captcha/pom.xml +++ b/hutool-captcha/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-captcha diff --git a/hutool-core/pom.xml b/hutool-core/pom.xml index 6403f7c59..3d8e75335 100755 --- a/hutool-core/pom.xml +++ b/hutool-core/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-core diff --git a/hutool-cron/pom.xml b/hutool-cron/pom.xml index c632c4b69..b1aa11153 100755 --- a/hutool-cron/pom.xml +++ b/hutool-cron/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-cron diff --git a/hutool-crypto/pom.xml b/hutool-crypto/pom.xml index d48d44ec2..d106f6032 100755 --- a/hutool-crypto/pom.xml +++ b/hutool-crypto/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-crypto diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml index f4d7b10b8..7cd682ec5 100755 --- a/hutool-db/pom.xml +++ b/hutool-db/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-db diff --git a/hutool-dfa/pom.xml b/hutool-dfa/pom.xml index a467e88c0..fcf451fe9 100755 --- a/hutool-dfa/pom.xml +++ b/hutool-dfa/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-dfa diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml index 086d12468..2865d3df9 100755 --- a/hutool-extra/pom.xml +++ b/hutool-extra/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-extra diff --git a/hutool-http/pom.xml b/hutool-http/pom.xml index 94271dac0..1a6eee26e 100755 --- a/hutool-http/pom.xml +++ b/hutool-http/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-http diff --git a/hutool-json/pom.xml b/hutool-json/pom.xml index 9135f1845..0f10b0255 100755 --- a/hutool-json/pom.xml +++ b/hutool-json/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-json diff --git a/hutool-jwt/pom.xml b/hutool-jwt/pom.xml index 8a86ab83e..4092f97a8 100755 --- a/hutool-jwt/pom.xml +++ b/hutool-jwt/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-jwt diff --git a/hutool-log/pom.xml b/hutool-log/pom.xml index 62a5d636e..70fd8667d 100755 --- a/hutool-log/pom.xml +++ b/hutool-log/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-log diff --git a/hutool-poi/pom.xml b/hutool-poi/pom.xml index c439d0e54..9a05a8038 100755 --- a/hutool-poi/pom.xml +++ b/hutool-poi/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-poi diff --git a/hutool-script/pom.xml b/hutool-script/pom.xml index a19f01d66..019bacdb8 100755 --- a/hutool-script/pom.xml +++ b/hutool-script/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-script diff --git a/hutool-setting/pom.xml b/hutool-setting/pom.xml index 0d97a98a6..d7f941140 100755 --- a/hutool-setting/pom.xml +++ b/hutool-setting/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-setting diff --git a/hutool-socket/pom.xml b/hutool-socket/pom.xml index ea8e7c2bc..b47d5e1de 100755 --- a/hutool-socket/pom.xml +++ b/hutool-socket/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-socket diff --git a/hutool-system/pom.xml b/hutool-system/pom.xml index f17be3d03..38e6feed9 100755 --- a/hutool-system/pom.xml +++ b/hutool-system/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool-system diff --git a/pom.xml b/pom.xml index b2dc0732a..e61fb7297 100755 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 5.8.23 + 5.8.24-SNAPSHOT hutool Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。 https://github.com/dromara/hutool From 7c1fafce99c2be8a5005957cda74212253f642c9 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 14 Nov 2023 08:50:43 +0800 Subject: [PATCH 02/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8DLocalDateTime#parseDate?= =?UTF-8?q?=E6=9C=AA=E5=88=A4=E6=96=AD=E7=A9=BA=E9=97=AE=E9=A2=98=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- .../src/main/java/cn/hutool/core/date/LocalDateTimeUtil.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f83bec8d..2ac4ca0dd 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,12 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.24(2023-11-12) +# 5.8.24(2023-11-14) ### 🐣新特性 ### 🐞Bug修复 +* 【core 】 修复LocalDateTime#parseDate未判断空问题问题(issue#I8FN7F@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) diff --git a/hutool-core/src/main/java/cn/hutool/core/date/LocalDateTimeUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/LocalDateTimeUtil.java index bdc7de543..6a08abf9d 100755 --- a/hutool-core/src/main/java/cn/hutool/core/date/LocalDateTimeUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/LocalDateTimeUtil.java @@ -318,7 +318,7 @@ public class LocalDateTimeUtil { * @since 5.3.10 */ public static LocalDate parseDate(CharSequence text, DateTimeFormatter formatter) { - if (null == text) { + if (StrUtil.isBlank(text)) { return null; } if (null == formatter) { From 5cf19ea460080e1d201688372040237519bab445 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 14 Nov 2023 09:07:06 +0800 Subject: [PATCH 03/45] =?UTF-8?q?Cache=E5=A2=9E=E5=8A=A0get=E9=87=8D?= =?UTF-8?q?=E8=BD=BD=EF=BC=8C=E5=8F=AF=E8=87=AA=E5=AE=9A=E4=B9=89=E8=B6=85?= =?UTF-8?q?=E6=97=B6=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../src/main/java/cn/hutool/cache/Cache.java | 15 +++++++++++++++ .../java/cn/hutool/cache/impl/AbstractCache.java | 7 ++++++- .../main/java/cn/hutool/cache/impl/NoCache.java | 5 +++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ac4ca0dd..adeedf528 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ # 5.8.24(2023-11-14) ### 🐣新特性 +* 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) ### 🐞Bug修复 * 【core 】 修复LocalDateTime#parseDate未判断空问题问题(issue#I8FN7F@Gitee) diff --git a/hutool-cache/src/main/java/cn/hutool/cache/Cache.java b/hutool-cache/src/main/java/cn/hutool/cache/Cache.java index ec021402e..0e07162eb 100755 --- a/hutool-cache/src/main/java/cn/hutool/cache/Cache.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/Cache.java @@ -92,6 +92,21 @@ public interface Cache extends Iterable, Serializable { */ V get(K key, boolean isUpdateLastAccess, Func0 supplier); + /** + * 从缓存中获得对象,当对象不在缓存中或已经过期返回Func0回调产生的对象 + *

+ * 调用此方法时,会检查上次调用时间,如果与当前时间差值大于超时时间返回{@code null},否则返回值。 + *

+ * 每次调用此方法会可选是否刷新最后访问时间,{@code true}表示会重新计算超时时间。 + * + * @param key 键 + * @param isUpdateLastAccess 是否更新最后访问时间,即重新计算超时时间。 + * @param timeout 自定义超时时间 + * @param supplier 如果不存在回调方法,用于生产值对象 + * @return 值对象 + */ + V get(K key, boolean isUpdateLastAccess, long timeout, Func0 supplier); + /** * 从缓存中获得对象,当对象不在缓存中或已经过期返回{@code null} *

diff --git a/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java b/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java index 4ea05b1ff..b33acd3a3 100755 --- a/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java @@ -109,6 +109,11 @@ public abstract class AbstractCache implements Cache { @Override public V get(K key, boolean isUpdateLastAccess, Func0 supplier) { + return get(key, isUpdateLastAccess, this.timeout, supplier); + } + + @Override + public V get(K key, boolean isUpdateLastAccess, long timeout, Func0 supplier) { V v = get(key, isUpdateLastAccess); if (null == v && null != supplier) { //每个key单独获取一把锁,降低锁的粒度提高并发能力,see pr#1385@Github @@ -125,7 +130,7 @@ public abstract class AbstractCache implements Cache { throw ExceptionUtil.wrapRuntime(e); //throw new RuntimeException(e); } - put(key, v, this.timeout); + put(key, v, timeout); } else { v = co.get(isUpdateLastAccess); } diff --git a/hutool-cache/src/main/java/cn/hutool/cache/impl/NoCache.java b/hutool-cache/src/main/java/cn/hutool/cache/impl/NoCache.java index 553efd5e2..96bc03b98 100755 --- a/hutool-cache/src/main/java/cn/hutool/cache/impl/NoCache.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/impl/NoCache.java @@ -58,6 +58,11 @@ public class NoCache implements Cache { @Override public V get(K key, boolean isUpdateLastAccess, Func0 supplier) { + return get(key, isUpdateLastAccess, 0, supplier); + } + + @Override + public V get(K key, boolean isUpdateLastAccess, long timeout, Func0 supplier) { try { return (null == supplier) ? null : supplier.call(); } catch (Exception e) { From 9c0f791ac545582fb8f92d6f9516a6b49ca514df Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 15 Nov 2023 19:08:31 +0800 Subject: [PATCH 04/45] =?UTF-8?q?JWT#sign=E5=A2=9E=E5=8A=A0=E9=87=8D?= =?UTF-8?q?=E8=BD=BD=EF=BC=8C=E5=8F=AF=E9=80=89=E6=98=AF=E5=90=A6=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E9=BB=98=E8=AE=A4=E7=9A=84typ=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 +- .../src/main/java/cn/hutool/jwt/JWT.java | 35 ++++++++++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index adeedf528..8f600f77d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,11 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.24(2023-11-14) +# 5.8.24(2023-11-15) ### 🐣新特性 * 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) +* 【cache 】 JWT#sign增加重载,可选是否增加默认的typ参数(issue#3386@Github) ### 🐞Bug修复 * 【core 】 修复LocalDateTime#parseDate未判断空问题问题(issue#I8FN7F@Gitee) diff --git a/hutool-jwt/src/main/java/cn/hutool/jwt/JWT.java b/hutool-jwt/src/main/java/cn/hutool/jwt/JWT.java index e7214aa48..1d511d74c 100755 --- a/hutool-jwt/src/main/java/cn/hutool/jwt/JWT.java +++ b/hutool-jwt/src/main/java/cn/hutool/jwt/JWT.java @@ -302,7 +302,18 @@ public class JWT implements RegisteredPayload { * @return JWT字符串 */ public String sign() { - return sign(this.signer); + return sign(true); + } + + /** + * 签名生成JWT字符串 + * + * @param addTypeIfNot 如果'typ'头不存在,是否赋值默认值 + * @return JWT字符串 + * @since 5.8.24 + */ + public String sign(boolean addTypeIfNot) { + return sign(this.signer, addTypeIfNot); } /** @@ -312,19 +323,33 @@ public class JWT implements RegisteredPayload { * @return JWT字符串 */ public String sign(JWTSigner signer) { + return sign(signer, true); + } + + /** + * 签名生成JWT字符串 + * + * @param signer JWT签名器 + * @param addTypeIfNot 如果'typ'头不存在,是否赋值默认值 + * @return JWT字符串 + * @since 5.8.24 + */ + public String sign(JWTSigner signer, boolean addTypeIfNot) { Assert.notNull(signer, () -> new JWTException("No Signer provided!")); // 检查tye信息 - final String type = (String) this.header.getClaim(JWTHeader.TYPE); - if (StrUtil.isBlank(type)) { - this.header.setClaim(JWTHeader.TYPE, "JWT"); + if (addTypeIfNot) { + final String type = (String) this.header.getClaim(JWTHeader.TYPE); + if (StrUtil.isBlank(type)) { + this.header.setClaim(JWTHeader.TYPE, "JWT"); + } } // 检查头信息中是否有算法信息 final String algorithm = (String) this.header.getClaim(JWTHeader.ALGORITHM); if (StrUtil.isBlank(algorithm)) { this.header.setClaim(JWTHeader.ALGORITHM, - AlgorithmUtil.getId(signer.getAlgorithm())); + AlgorithmUtil.getId(signer.getAlgorithm())); } final String headerBase64 = Base64.encodeUrlSafe(this.header.toString(), charset); From 088f3ecfc0a5860962f29459a0f09871f37d92ec Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 16 Nov 2023 22:31:33 +0800 Subject: [PATCH 05/45] add ad --- README-EN.md | 7 +++++-- README.md | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/README-EN.md b/README-EN.md index 6deac7710..84fa1602d 100755 --- a/README-EN.md +++ b/README-EN.md @@ -47,8 +47,11 @@ -------------------------------------------------------------------------------

- - + 特别赞助:
+ + + +

------------------------------------------------------------------------------- diff --git a/README.md b/README.md index c093a728b..a13f96583 100755 --- a/README.md +++ b/README.md @@ -47,8 +47,11 @@ -------------------------------------------------------------------------------

- - + 特别赞助:
+ + + +

------------------------------------------------------------------------------- From b613d1e3a55527199355973a0ec8a32cba847346 Mon Sep 17 00:00:00 2001 From: lzpeng723 <1500913306@qq.com> Date: Sun, 19 Nov 2023 04:41:00 +0000 Subject: [PATCH 06/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B7=B2=E5=90=91=20re?= =?UTF-8?q?sponse=20=E4=B8=AD=E5=86=99=E5=85=A5=E6=96=87=E4=BB=B6=E5=90=8E?= =?UTF-8?q?=EF=BC=8C=20=E8=BF=98=E4=BC=9A=E7=BB=A7=E7=BB=AD=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=20response.send404("404=20Not=20Found=20!");=20?= =?UTF-8?q?=E6=AD=A4=E6=97=B6=E4=BC=9A=E5=9C=A8cn.hutool.http.server.HttpS?= =?UTF-8?q?erverResponse#send(int,=20long)=20=E6=8A=9B=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lzpeng723 <1500913306@qq.com> --- .../src/main/java/cn/hutool/http/server/action/RootAction.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hutool-http/src/main/java/cn/hutool/http/server/action/RootAction.java b/hutool-http/src/main/java/cn/hutool/http/server/action/RootAction.java index 8c10bd998..15ea39630 100644 --- a/hutool-http/src/main/java/cn/hutool/http/server/action/RootAction.java +++ b/hutool-http/src/main/java/cn/hutool/http/server/action/RootAction.java @@ -73,11 +73,13 @@ public class RootAction implements Action { file = FileUtil.file(file, indexFileName); if (file.exists() && file.isFile()) { response.write(file); + return; } } } else{ final String name = request.getParam("name"); response.write(file, name); + return; } } From 082391ae40613c1b3fa221248f5e0dbd80a85456 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 20 Nov 2023 09:47:17 +0800 Subject: [PATCH 07/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20RootAction=20send404?= =?UTF-8?q?=20=E6=8A=9B=E5=BC=82=E5=B8=B8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f600f77d..af072a9f7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.24(2023-11-15) +# 5.8.24(2023-11-20) ### 🐣新特性 * 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) @@ -10,6 +10,7 @@ ### 🐞Bug修复 * 【core 】 修复LocalDateTime#parseDate未判断空问题问题(issue#I8FN7F@Gitee) +* 【http 】 修复 RootAction send404 抛异常问题(pr#1107@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) From f8a92ca4a58d4db6ec26c92aaa9e3fffe3adf152 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 28 Nov 2023 18:02:27 +0800 Subject: [PATCH 08/45] remove ad --- README-EN.md | 4 ---- README.md | 4 ---- 2 files changed, 8 deletions(-) diff --git a/README-EN.md b/README-EN.md index 84fa1602d..741a0275f 100755 --- a/README-EN.md +++ b/README-EN.md @@ -47,10 +47,6 @@ -------------------------------------------------------------------------------

- 特别赞助:
- - -

diff --git a/README.md b/README.md index a13f96583..4c5f7abd9 100755 --- a/README.md +++ b/README.md @@ -47,10 +47,6 @@ -------------------------------------------------------------------------------

- 特别赞助:
- - -

From 41e4b3ffb03b8b7f7f25fb998698934b11117774 Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 29 Nov 2023 04:06:08 +0800 Subject: [PATCH 09/45] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=AF=86=E5=88=ABOpenG?= =?UTF-8?q?auss=E7=9A=84=E9=A9=B1=E5=8A=A8=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- .../src/main/java/cn/hutool/db/dialect/DialectFactory.java | 5 ++++- .../src/main/java/cn/hutool/db/dialect/DriverNamePool.java | 5 ++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af072a9f7..267aa6943 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,12 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.24(2023-11-20) +# 5.8.24(2023-11-29) ### 🐣新特性 * 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) * 【cache 】 JWT#sign增加重载,可选是否增加默认的typ参数(issue#3386@Github) +* 【db 】 增加识别OpenGauss的驱动类(issue#I8K6C0@Gitee) ### 🐞Bug修复 * 【core 】 修复LocalDateTime#parseDate未判断空问题问题(issue#I8FN7F@Gitee) diff --git a/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java b/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java index 0e439019a..6dfea6ae5 100755 --- a/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java @@ -161,9 +161,12 @@ public class DialectFactory implements DriverNamePool { } else if (nameContainsProductInfo.contains("sybase")) { // Sybase driver = DRIVER_SYBASE; - }else if (nameContainsProductInfo.contains("mariadb")) { + } else if (nameContainsProductInfo.contains("mariadb")) { // mariadb driver = DRIVER_MARIADB; + } else if (nameContainsProductInfo.contains("opengauss")) { + // OpenGauss + driver = DRIVER_OPENGAUSS; } return driver; diff --git a/hutool-db/src/main/java/cn/hutool/db/dialect/DriverNamePool.java b/hutool-db/src/main/java/cn/hutool/db/dialect/DriverNamePool.java index 51cdec818..aab7a8aca 100644 --- a/hutool-db/src/main/java/cn/hutool/db/dialect/DriverNamePool.java +++ b/hutool-db/src/main/java/cn/hutool/db/dialect/DriverNamePool.java @@ -108,5 +108,8 @@ public interface DriverNamePool { * JDBC 驱动 Sybase */ String DRIVER_SYBASE = "com.sybase.jdbc4.jdbc.SybDriver"; - + /** + * JDBC 驱动 OpenGauss + */ + String DRIVER_OPENGAUSS = "org.opengauss.Driver"; } From 824460e5c576b92e9763d32802398b9e82de1e2f Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 29 Nov 2023 10:41:00 +0800 Subject: [PATCH 10/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8DCharSequenceUtil?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E5=92=8C=E5=BC=95=E7=94=A8=EF=BC=8C=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E5=BE=AA=E7=8E=AF=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../cn/hutool/core/text/CharSequenceUtil.java | 530 +++++++++--------- 2 files changed, 263 insertions(+), 268 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 267aa6943..961ee4de4 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) * 【cache 】 JWT#sign增加重载,可选是否增加默认的typ参数(issue#3386@Github) * 【db 】 增加识别OpenGauss的驱动类(issue#I8K6C0@Gitee) +* 【core 】 修复CharSequenceUtil注释和引用,避免循环引用 ### 🐞Bug修复 * 【core 】 修复LocalDateTime#parseDate未判断空问题问题(issue#I8FN7F@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java b/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java index 495fcc9e6..6b48d9120 100755 --- a/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java @@ -10,13 +10,7 @@ import cn.hutool.core.lang.func.Func1; import cn.hutool.core.text.finder.CharFinder; import cn.hutool.core.text.finder.Finder; import cn.hutool.core.text.finder.StrFinder; -import cn.hutool.core.util.ArrayUtil; -import cn.hutool.core.util.CharUtil; -import cn.hutool.core.util.CharsetUtil; -import cn.hutool.core.util.DesensitizedUtil; -import cn.hutool.core.util.NumberUtil; -import cn.hutool.core.util.ReUtil; -import cn.hutool.core.util.StrUtil; +import cn.hutool.core.util.*; import java.nio.ByteBuffer; import java.nio.charset.Charset; @@ -65,10 +59,10 @@ public class CharSequenceUtil { * *

例:

*
    - *
  • {@code StrUtil.isBlank(null) // true}
  • - *
  • {@code StrUtil.isBlank("") // true}
  • - *
  • {@code StrUtil.isBlank(" \t\n") // true}
  • - *
  • {@code StrUtil.isBlank("abc") // false}
  • + *
  • {@code CharSequenceUtil.isBlank(null) // true}
  • + *
  • {@code CharSequenceUtil.isBlank("") // true}
  • + *
  • {@code CharSequenceUtil.isBlank(" \t\n") // true}
  • + *
  • {@code CharSequenceUtil.isBlank("abc") // false}
  • *
* *

注意:该方法与 {@link #isEmpty(CharSequence)} 的区别是: @@ -111,10 +105,10 @@ public class CharSequenceUtil { * *

例:

*
    - *
  • {@code StrUtil.isNotBlank(null) // false}
  • - *
  • {@code StrUtil.isNotBlank("") // false}
  • - *
  • {@code StrUtil.isNotBlank(" \t\n") // false}
  • - *
  • {@code StrUtil.isNotBlank("abc") // true}
  • + *
  • {@code CharSequenceUtil.isNotBlank(null) // false}
  • + *
  • {@code CharSequenceUtil.isNotBlank("") // false}
  • + *
  • {@code CharSequenceUtil.isNotBlank(" \t\n") // false}
  • + *
  • {@code CharSequenceUtil.isNotBlank("abc") // true}
  • *
* *

注意:该方法与 {@link #isNotEmpty(CharSequence)} 的区别是: @@ -136,10 +130,10 @@ public class CharSequenceUtil { * *

例:

*
    - *
  • {@code StrUtil.hasBlank() // true}
  • - *
  • {@code StrUtil.hasBlank("", null, " ") // true}
  • - *
  • {@code StrUtil.hasBlank("123", " ") // true}
  • - *
  • {@code StrUtil.hasBlank("123", "abc") // false}
  • + *
  • {@code CharSequenceUtil.hasBlank() // true}
  • + *
  • {@code CharSequenceUtil.hasBlank("", null, " ") // true}
  • + *
  • {@code CharSequenceUtil.hasBlank("123", " ") // true}
  • + *
  • {@code CharSequenceUtil.hasBlank("123", "abc") // false}
  • *
* *

注意:该方法与 {@link #isAllBlank(CharSequence...)} 的区别在于:

@@ -171,10 +165,10 @@ public class CharSequenceUtil { * *

例:

*
    - *
  • {@code StrUtil.isAllBlank() // true}
  • - *
  • {@code StrUtil.isAllBlank("", null, " ") // true}
  • - *
  • {@code StrUtil.isAllBlank("123", " ") // false}
  • - *
  • {@code StrUtil.isAllBlank("123", "abc") // false}
  • + *
  • {@code CharSequenceUtil.isAllBlank() // true}
  • + *
  • {@code CharSequenceUtil.isAllBlank("", null, " ") // true}
  • + *
  • {@code CharSequenceUtil.isAllBlank("123", " ") // false}
  • + *
  • {@code CharSequenceUtil.isAllBlank("123", "abc") // false}
  • *
* *

注意:该方法与 {@link #hasBlank(CharSequence...)} 的区别在于:

@@ -208,10 +202,10 @@ public class CharSequenceUtil { * *

例:

*
    - *
  • {@code StrUtil.isEmpty(null) // true}
  • - *
  • {@code StrUtil.isEmpty("") // true}
  • - *
  • {@code StrUtil.isEmpty(" \t\n") // false}
  • - *
  • {@code StrUtil.isEmpty("abc") // false}
  • + *
  • {@code CharSequenceUtil.isEmpty(null) // true}
  • + *
  • {@code CharSequenceUtil.isEmpty("") // true}
  • + *
  • {@code CharSequenceUtil.isEmpty(" \t\n") // false}
  • + *
  • {@code CharSequenceUtil.isEmpty("abc") // false}
  • *
* *

注意:该方法与 {@link #isBlank(CharSequence)} 的区别是:该方法不校验空白字符。

@@ -238,10 +232,10 @@ public class CharSequenceUtil { * *

例:

*
    - *
  • {@code StrUtil.isNotEmpty(null) // false}
  • - *
  • {@code StrUtil.isNotEmpty("") // false}
  • - *
  • {@code StrUtil.isNotEmpty(" \t\n") // true}
  • - *
  • {@code StrUtil.isNotEmpty("abc") // true}
  • + *
  • {@code CharSequenceUtil.isNotEmpty(null) // false}
  • + *
  • {@code CharSequenceUtil.isNotEmpty("") // false}
  • + *
  • {@code CharSequenceUtil.isNotEmpty(" \t\n") // true}
  • + *
  • {@code CharSequenceUtil.isNotEmpty("abc") // true}
  • *
* *

注意:该方法与 {@link #isNotBlank(CharSequence)} 的区别是:该方法不校验空白字符。

@@ -350,11 +344,11 @@ public class CharSequenceUtil { * *

例:

*
    - *
  • {@code StrUtil.hasEmpty() // true}
  • - *
  • {@code StrUtil.hasEmpty("", null) // true}
  • - *
  • {@code StrUtil.hasEmpty("123", "") // true}
  • - *
  • {@code StrUtil.hasEmpty("123", "abc") // false}
  • - *
  • {@code StrUtil.hasEmpty(" ", "\t", "\n") // false}
  • + *
  • {@code CharSequenceUtil.hasEmpty() // true}
  • + *
  • {@code CharSequenceUtil.hasEmpty("", null) // true}
  • + *
  • {@code CharSequenceUtil.hasEmpty("123", "") // true}
  • + *
  • {@code CharSequenceUtil.hasEmpty("123", "abc") // false}
  • + *
  • {@code CharSequenceUtil.hasEmpty(" ", "\t", "\n") // false}
  • *
* *

注意:该方法与 {@link #isAllEmpty(CharSequence...)} 的区别在于:

@@ -386,11 +380,11 @@ public class CharSequenceUtil { * *

例:

*
    - *
  • {@code StrUtil.isAllEmpty() // true}
  • - *
  • {@code StrUtil.isAllEmpty("", null) // true}
  • - *
  • {@code StrUtil.isAllEmpty("123", "") // false}
  • - *
  • {@code StrUtil.isAllEmpty("123", "abc") // false}
  • - *
  • {@code StrUtil.isAllEmpty(" ", "\t", "\n") // false}
  • + *
  • {@code CharSequenceUtil.isAllEmpty() // true}
  • + *
  • {@code CharSequenceUtil.isAllEmpty("", null) // true}
  • + *
  • {@code CharSequenceUtil.isAllEmpty("123", "") // false}
  • + *
  • {@code CharSequenceUtil.isAllEmpty("123", "abc") // false}
  • + *
  • {@code CharSequenceUtil.isAllEmpty(" ", "\t", "\n") // false}
  • *
* *

注意:该方法与 {@link #hasEmpty(CharSequence...)} 的区别在于:

@@ -422,11 +416,11 @@ public class CharSequenceUtil { * *

例:

*
    - *
  • {@code StrUtil.isAllNotEmpty() // false}
  • - *
  • {@code StrUtil.isAllNotEmpty("", null) // false}
  • - *
  • {@code StrUtil.isAllNotEmpty("123", "") // false}
  • - *
  • {@code StrUtil.isAllNotEmpty("123", "abc") // true}
  • - *
  • {@code StrUtil.isAllNotEmpty(" ", "\t", "\n") // true}
  • + *
  • {@code CharSequenceUtil.isAllNotEmpty() // false}
  • + *
  • {@code CharSequenceUtil.isAllNotEmpty("", null) // false}
  • + *
  • {@code CharSequenceUtil.isAllNotEmpty("123", "") // false}
  • + *
  • {@code CharSequenceUtil.isAllNotEmpty("123", "abc") // true}
  • + *
  • {@code CharSequenceUtil.isAllNotEmpty(" ", "\t", "\n") // true}
  • *
* *

注意:该方法与 {@link #isAllEmpty(CharSequence...)} 的区别在于:

@@ -534,11 +528,11 @@ public class CharSequenceUtil { * 除去字符串头尾部的空白,如果字符串是{@code null},返回{@code ""}。 * *
-	 * StrUtil.trimToEmpty(null)          = ""
-	 * StrUtil.trimToEmpty("")            = ""
-	 * StrUtil.trimToEmpty("     ")       = ""
-	 * StrUtil.trimToEmpty("abc")         = "abc"
-	 * StrUtil.trimToEmpty("    abc    ") = "abc"
+	 * CharSequenceUtil.trimToEmpty(null)          = ""
+	 * CharSequenceUtil.trimToEmpty("")            = ""
+	 * CharSequenceUtil.trimToEmpty("     ")       = ""
+	 * CharSequenceUtil.trimToEmpty("abc")         = "abc"
+	 * CharSequenceUtil.trimToEmpty("    abc    ") = "abc"
 	 * 
* * @param str 字符串 @@ -553,11 +547,11 @@ public class CharSequenceUtil { * 除去字符串头尾部的空白,如果字符串是{@code null}或者"",返回{@code null}。 * *
-	 * StrUtil.trimToNull(null)          = null
-	 * StrUtil.trimToNull("")            = null
-	 * StrUtil.trimToNull("     ")       = null
-	 * StrUtil.trimToNull("abc")         = "abc"
-	 * StrUtil.trimToEmpty("    abc    ") = "abc"
+	 * CharSequenceUtil.trimToNull(null)          = null
+	 * CharSequenceUtil.trimToNull("")            = null
+	 * CharSequenceUtil.trimToNull("     ")       = null
+	 * CharSequenceUtil.trimToNull("abc")         = "abc"
+	 * CharSequenceUtil.trimToEmpty("    abc    ") = "abc"
 	 * 
* * @param str 字符串 @@ -1169,17 +1163,17 @@ public class CharSequenceUtil { * 指定范围内查找字符串,忽略大小写
* *
-	 * StrUtil.indexOfIgnoreCase(null, *, *)          = -1
-	 * StrUtil.indexOfIgnoreCase(*, null, *)          = -1
-	 * StrUtil.indexOfIgnoreCase("", "", 0)           = 0
-	 * StrUtil.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
-	 * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
-	 * StrUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
-	 * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
-	 * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
-	 * StrUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
-	 * StrUtil.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
-	 * StrUtil.indexOfIgnoreCase("abc", "", 9)        = -1
+	 * CharSequenceUtil.indexOfIgnoreCase(null, *, *)          = -1
+	 * CharSequenceUtil.indexOfIgnoreCase(*, null, *)          = -1
+	 * CharSequenceUtil.indexOfIgnoreCase("", "", 0)           = 0
+	 * CharSequenceUtil.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
+	 * CharSequenceUtil.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
+	 * CharSequenceUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
+	 * CharSequenceUtil.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
+	 * CharSequenceUtil.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
+	 * CharSequenceUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
+	 * CharSequenceUtil.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
+	 * CharSequenceUtil.indexOfIgnoreCase("abc", "", 9)        = -1
 	 * 
* * @param str 字符串 @@ -1195,17 +1189,17 @@ public class CharSequenceUtil { * 指定范围内查找字符串 * *
-	 * StrUtil.indexOfIgnoreCase(null, *, *)          = -1
-	 * StrUtil.indexOfIgnoreCase(*, null, *)          = -1
-	 * StrUtil.indexOfIgnoreCase("", "", 0)           = 0
-	 * StrUtil.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
-	 * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
-	 * StrUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
-	 * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
-	 * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
-	 * StrUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
-	 * StrUtil.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
-	 * StrUtil.indexOfIgnoreCase("abc", "", 9)        = -1
+	 * CharSequenceUtil.indexOfIgnoreCase(null, *, *)          = -1
+	 * CharSequenceUtil.indexOfIgnoreCase(*, null, *)          = -1
+	 * CharSequenceUtil.indexOfIgnoreCase("", "", 0)           = 0
+	 * CharSequenceUtil.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
+	 * CharSequenceUtil.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
+	 * CharSequenceUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
+	 * CharSequenceUtil.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
+	 * CharSequenceUtil.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
+	 * CharSequenceUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
+	 * CharSequenceUtil.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
+	 * CharSequenceUtil.indexOfIgnoreCase("abc", "", 9)        = -1
 	 * 
* * @param str 字符串 @@ -1230,7 +1224,7 @@ public class CharSequenceUtil { */ public static int indexOf(CharSequence text, CharSequence searchStr, int from, boolean ignoreCase) { if (isEmpty(text) || isEmpty(searchStr)) { - if (StrUtil.equals(text, searchStr)) { + if (CharSequenceUtil.equals(text, searchStr)) { return 0; } else { return INDEX_NOT_FOUND; @@ -1278,7 +1272,7 @@ public class CharSequenceUtil { */ public static int lastIndexOf(CharSequence text, CharSequence searchStr, int from, boolean ignoreCase) { if (isEmpty(text) || isEmpty(searchStr)) { - if (StrUtil.equals(text, searchStr)) { + if (CharSequenceUtil.equals(text, searchStr)) { return 0; } else { return INDEX_NOT_FOUND; @@ -1298,17 +1292,17 @@ public class CharSequenceUtil { * 例子(*代表任意字符): * *
-	 * StrUtil.ordinalIndexOf(null, *, *)          = -1
-	 * StrUtil.ordinalIndexOf(*, null, *)          = -1
-	 * StrUtil.ordinalIndexOf("", "", *)           = 0
-	 * StrUtil.ordinalIndexOf("aabaabaa", "a", 1)  = 0
-	 * StrUtil.ordinalIndexOf("aabaabaa", "a", 2)  = 1
-	 * StrUtil.ordinalIndexOf("aabaabaa", "b", 1)  = 2
-	 * StrUtil.ordinalIndexOf("aabaabaa", "b", 2)  = 5
-	 * StrUtil.ordinalIndexOf("aabaabaa", "ab", 1) = 1
-	 * StrUtil.ordinalIndexOf("aabaabaa", "ab", 2) = 4
-	 * StrUtil.ordinalIndexOf("aabaabaa", "", 1)   = 0
-	 * StrUtil.ordinalIndexOf("aabaabaa", "", 2)   = 0
+	 * CharSequenceUtil.ordinalIndexOf(null, *, *)          = -1
+	 * CharSequenceUtil.ordinalIndexOf(*, null, *)          = -1
+	 * CharSequenceUtil.ordinalIndexOf("", "", *)           = 0
+	 * CharSequenceUtil.ordinalIndexOf("aabaabaa", "a", 1)  = 0
+	 * CharSequenceUtil.ordinalIndexOf("aabaabaa", "a", 2)  = 1
+	 * CharSequenceUtil.ordinalIndexOf("aabaabaa", "b", 1)  = 2
+	 * CharSequenceUtil.ordinalIndexOf("aabaabaa", "b", 2)  = 5
+	 * CharSequenceUtil.ordinalIndexOf("aabaabaa", "ab", 1) = 1
+	 * CharSequenceUtil.ordinalIndexOf("aabaabaa", "ab", 2) = 4
+	 * CharSequenceUtil.ordinalIndexOf("aabaabaa", "", 1)   = 0
+	 * CharSequenceUtil.ordinalIndexOf("aabaabaa", "", 2)   = 0
 	 * 
* * @param str 被检查的字符串,可以为null @@ -2106,13 +2100,13 @@ public class CharSequenceUtil { * 切割指定长度的后部分的字符串 * *
-	 * StrUtil.subSufByLength("abcde", 3)      =    "cde"
-	 * StrUtil.subSufByLength("abcde", 0)      =    ""
-	 * StrUtil.subSufByLength("abcde", -5)     =    ""
-	 * StrUtil.subSufByLength("abcde", -1)     =    ""
-	 * StrUtil.subSufByLength("abcde", 5)       =    "abcde"
-	 * StrUtil.subSufByLength("abcde", 10)     =    "abcde"
-	 * StrUtil.subSufByLength(null, 3)               =    null
+	 * CharSequenceUtil.subSufByLength("abcde", 3)      =    "cde"
+	 * CharSequenceUtil.subSufByLength("abcde", 0)      =    ""
+	 * CharSequenceUtil.subSufByLength("abcde", -5)     =    ""
+	 * CharSequenceUtil.subSufByLength("abcde", -1)     =    ""
+	 * CharSequenceUtil.subSufByLength("abcde", 5)       =    "abcde"
+	 * CharSequenceUtil.subSufByLength("abcde", 10)     =    "abcde"
+	 * CharSequenceUtil.subSufByLength(null, 3)               =    null
 	 * 
* * @param string 字符串 @@ -2156,14 +2150,14 @@ public class CharSequenceUtil { * 如果分隔字符串为空串"",则返回空串,如果分隔字符串未找到,返回原字符串,举例如下: * *
-	 * StrUtil.subBefore(null, *, false)      = null
-	 * StrUtil.subBefore("", *, false)        = ""
-	 * StrUtil.subBefore("abc", "a", false)   = ""
-	 * StrUtil.subBefore("abcba", "b", false) = "a"
-	 * StrUtil.subBefore("abc", "c", false)   = "ab"
-	 * StrUtil.subBefore("abc", "d", false)   = "abc"
-	 * StrUtil.subBefore("abc", "", false)    = ""
-	 * StrUtil.subBefore("abc", null, false)  = "abc"
+	 * CharSequenceUtil.subBefore(null, *, false)      = null
+	 * CharSequenceUtil.subBefore("", *, false)        = ""
+	 * CharSequenceUtil.subBefore("abc", "a", false)   = ""
+	 * CharSequenceUtil.subBefore("abcba", "b", false) = "a"
+	 * CharSequenceUtil.subBefore("abc", "c", false)   = "ab"
+	 * CharSequenceUtil.subBefore("abc", "d", false)   = "abc"
+	 * CharSequenceUtil.subBefore("abc", "", false)    = ""
+	 * CharSequenceUtil.subBefore("abc", null, false)  = "abc"
 	 * 
* * @param string 被查找的字符串 @@ -2198,12 +2192,12 @@ public class CharSequenceUtil { * 如果分隔字符串未找到,返回原字符串,举例如下: * *
-	 * StrUtil.subBefore(null, *, false)      = null
-	 * StrUtil.subBefore("", *, false)        = ""
-	 * StrUtil.subBefore("abc", 'a', false)   = ""
-	 * StrUtil.subBefore("abcba", 'b', false) = "a"
-	 * StrUtil.subBefore("abc", 'c', false)   = "ab"
-	 * StrUtil.subBefore("abc", 'd', false)   = "abc"
+	 * CharSequenceUtil.subBefore(null, *, false)      = null
+	 * CharSequenceUtil.subBefore("", *, false)        = ""
+	 * CharSequenceUtil.subBefore("abc", 'a', false)   = ""
+	 * CharSequenceUtil.subBefore("abcba", 'b', false) = "a"
+	 * CharSequenceUtil.subBefore("abc", 'c', false)   = "ab"
+	 * CharSequenceUtil.subBefore("abc", 'd', false)   = "abc"
 	 * 
* * @param string 被查找的字符串 @@ -2234,14 +2228,14 @@ public class CharSequenceUtil { * 如果分隔字符串为空串(null或""),则返回空串,如果分隔字符串未找到,返回空串,举例如下: * *
-	 * StrUtil.subAfter(null, *, false)      = null
-	 * StrUtil.subAfter("", *, false)        = ""
-	 * StrUtil.subAfter(*, null, false)      = ""
-	 * StrUtil.subAfter("abc", "a", false)   = "bc"
-	 * StrUtil.subAfter("abcba", "b", false) = "cba"
-	 * StrUtil.subAfter("abc", "c", false)   = ""
-	 * StrUtil.subAfter("abc", "d", false)   = ""
-	 * StrUtil.subAfter("abc", "", false)    = "abc"
+	 * CharSequenceUtil.subAfter(null, *, false)      = null
+	 * CharSequenceUtil.subAfter("", *, false)        = ""
+	 * CharSequenceUtil.subAfter(*, null, false)      = ""
+	 * CharSequenceUtil.subAfter("abc", "a", false)   = "bc"
+	 * CharSequenceUtil.subAfter("abcba", "b", false) = "cba"
+	 * CharSequenceUtil.subAfter("abc", "c", false)   = ""
+	 * CharSequenceUtil.subAfter("abc", "d", false)   = ""
+	 * CharSequenceUtil.subAfter("abc", "", false)    = "abc"
 	 * 
* * @param string 被查找的字符串 @@ -2272,12 +2266,12 @@ public class CharSequenceUtil { * 如果分隔字符串为空串(null或""),则返回空串,如果分隔字符串未找到,返回空串,举例如下: * *
-	 * StrUtil.subAfter(null, *, false)      = null
-	 * StrUtil.subAfter("", *, false)        = ""
-	 * StrUtil.subAfter("abc", 'a', false)   = "bc"
-	 * StrUtil.subAfter("abcba", 'b', false) = "cba"
-	 * StrUtil.subAfter("abc", 'c', false)   = ""
-	 * StrUtil.subAfter("abc", 'd', false)   = ""
+	 * CharSequenceUtil.subAfter(null, *, false)      = null
+	 * CharSequenceUtil.subAfter("", *, false)        = ""
+	 * CharSequenceUtil.subAfter("abc", 'a', false)   = "bc"
+	 * CharSequenceUtil.subAfter("abcba", 'b', false) = "cba"
+	 * CharSequenceUtil.subAfter("abc", 'c', false)   = ""
+	 * CharSequenceUtil.subAfter("abc", 'd', false)   = ""
 	 * 
* * @param string 被查找的字符串 @@ -2304,16 +2298,16 @@ public class CharSequenceUtil { * 栗子: * *
-	 * StrUtil.subBetween("wx[b]yz", "[", "]") = "b"
-	 * StrUtil.subBetween(null, *, *)          = null
-	 * StrUtil.subBetween(*, null, *)          = null
-	 * StrUtil.subBetween(*, *, null)          = null
-	 * StrUtil.subBetween("", "", "")          = ""
-	 * StrUtil.subBetween("", "", "]")         = null
-	 * StrUtil.subBetween("", "[", "]")        = null
-	 * StrUtil.subBetween("yabcz", "", "")     = ""
-	 * StrUtil.subBetween("yabcz", "y", "z")   = "abc"
-	 * StrUtil.subBetween("yabczyabcz", "y", "z")   = "abc"
+	 * CharSequenceUtil.subBetween("wx[b]yz", "[", "]") = "b"
+	 * CharSequenceUtil.subBetween(null, *, *)          = null
+	 * CharSequenceUtil.subBetween(*, null, *)          = null
+	 * CharSequenceUtil.subBetween(*, *, null)          = null
+	 * CharSequenceUtil.subBetween("", "", "")          = ""
+	 * CharSequenceUtil.subBetween("", "", "]")         = null
+	 * CharSequenceUtil.subBetween("", "[", "]")        = null
+	 * CharSequenceUtil.subBetween("yabcz", "", "")     = ""
+	 * CharSequenceUtil.subBetween("yabcz", "y", "z")   = "abc"
+	 * CharSequenceUtil.subBetween("yabczyabcz", "y", "z")   = "abc"
 	 * 
* * @param str 被切割的字符串 @@ -2347,12 +2341,12 @@ public class CharSequenceUtil { * 栗子: * *
-	 * StrUtil.subBetween(null, *)            = null
-	 * StrUtil.subBetween("", "")             = ""
-	 * StrUtil.subBetween("", "tag")          = null
-	 * StrUtil.subBetween("tagabctag", null)  = null
-	 * StrUtil.subBetween("tagabctag", "")    = ""
-	 * StrUtil.subBetween("tagabctag", "tag") = "abc"
+	 * CharSequenceUtil.subBetween(null, *)            = null
+	 * CharSequenceUtil.subBetween("", "")             = ""
+	 * CharSequenceUtil.subBetween("", "tag")          = null
+	 * CharSequenceUtil.subBetween("tagabctag", null)  = null
+	 * CharSequenceUtil.subBetween("tagabctag", "")    = ""
+	 * CharSequenceUtil.subBetween("tagabctag", "tag") = "abc"
 	 * 
* * @param str 被切割的字符串 @@ -2370,17 +2364,17 @@ public class CharSequenceUtil { * 栗子: * *
-	 * StrUtil.subBetweenAll("wx[b]y[z]", "[", "]") 		= ["b","z"]
-	 * StrUtil.subBetweenAll(null, *, *)          			= []
-	 * StrUtil.subBetweenAll(*, null, *)          			= []
-	 * StrUtil.subBetweenAll(*, *, null)          			= []
-	 * StrUtil.subBetweenAll("", "", "")          			= []
-	 * StrUtil.subBetweenAll("", "", "]")         			= []
-	 * StrUtil.subBetweenAll("", "[", "]")        			= []
-	 * StrUtil.subBetweenAll("yabcz", "", "")     			= []
-	 * StrUtil.subBetweenAll("yabcz", "y", "z")   			= ["abc"]
-	 * StrUtil.subBetweenAll("yabczyabcz", "y", "z")   		= ["abc","abc"]
-	 * StrUtil.subBetweenAll("[yabc[zy]abcz]", "[", "]");   = ["zy"]           重叠时只截取内部,
+	 * CharSequenceUtil.subBetweenAll("wx[b]y[z]", "[", "]") 		= ["b","z"]
+	 * CharSequenceUtil.subBetweenAll(null, *, *)          			= []
+	 * CharSequenceUtil.subBetweenAll(*, null, *)          			= []
+	 * CharSequenceUtil.subBetweenAll(*, *, null)          			= []
+	 * CharSequenceUtil.subBetweenAll("", "", "")          			= []
+	 * CharSequenceUtil.subBetweenAll("", "", "]")         			= []
+	 * CharSequenceUtil.subBetweenAll("", "[", "]")        			= []
+	 * CharSequenceUtil.subBetweenAll("yabcz", "", "")     			= []
+	 * CharSequenceUtil.subBetweenAll("yabcz", "y", "z")   			= ["abc"]
+	 * CharSequenceUtil.subBetweenAll("yabczyabcz", "y", "z")   		= ["abc","abc"]
+	 * CharSequenceUtil.subBetweenAll("[yabc[zy]abcz]", "[", "]");   = ["zy"]           重叠时只截取内部,
 	 * 
* * @param str 被切割的字符串 @@ -2425,15 +2419,15 @@ public class CharSequenceUtil { * 栗子: * *
-	 * StrUtil.subBetweenAll(null, *)          			= []
-	 * StrUtil.subBetweenAll(*, null)          			= []
-	 * StrUtil.subBetweenAll(*, *)          			= []
-	 * StrUtil.subBetweenAll("", "")          			= []
-	 * StrUtil.subBetweenAll("", "#")         			= []
-	 * StrUtil.subBetweenAll("gotanks", "")     		= []
-	 * StrUtil.subBetweenAll("#gotanks#", "#")   		= ["gotanks"]
-	 * StrUtil.subBetweenAll("#hello# #world#!", "#")   = ["hello", "world"]
-	 * StrUtil.subBetweenAll("#hello# world#!", "#");   = ["hello"]
+	 * CharSequenceUtil.subBetweenAll(null, *)          			= []
+	 * CharSequenceUtil.subBetweenAll(*, null)          			= []
+	 * CharSequenceUtil.subBetweenAll(*, *)          			= []
+	 * CharSequenceUtil.subBetweenAll("", "")          			= []
+	 * CharSequenceUtil.subBetweenAll("", "#")         			= []
+	 * CharSequenceUtil.subBetweenAll("gotanks", "")     		= []
+	 * CharSequenceUtil.subBetweenAll("#gotanks#", "#")   		= ["gotanks"]
+	 * CharSequenceUtil.subBetweenAll("#hello# #world#!", "#")   = ["hello", "world"]
+	 * CharSequenceUtil.subBetweenAll("#hello# world#!", "#");   = ["hello"]
 	 * 
* * @param str 被切割的字符串 @@ -2452,9 +2446,9 @@ public class CharSequenceUtil { * 重复某个字符 * *
-	 * StrUtil.repeat('e', 0)  = ""
-	 * StrUtil.repeat('e', 3)  = "eee"
-	 * StrUtil.repeat('e', -2) = ""
+	 * CharSequenceUtil.repeat('e', 0)  = ""
+	 * CharSequenceUtil.repeat('e', 3)  = "eee"
+	 * CharSequenceUtil.repeat('e', -2) = ""
 	 * 
* * @param c 被重复的字符 @@ -2522,7 +2516,7 @@ public class CharSequenceUtil { return null; } if (padLen <= 0) { - return StrUtil.EMPTY; + return CharSequenceUtil.EMPTY; } final int strLen = str.length(); if (strLen == padLen) { @@ -2543,9 +2537,9 @@ public class CharSequenceUtil { * 重复某个字符串并通过分界符连接 * *
-	 * StrUtil.repeatAndJoin("?", 5, ",")   = "?,?,?,?,?"
-	 * StrUtil.repeatAndJoin("?", 0, ",")   = ""
-	 * StrUtil.repeatAndJoin("?", 5, null) = "?????"
+	 * CharSequenceUtil.repeatAndJoin("?", 5, ",")   = "?,?,?,?,?"
+	 * CharSequenceUtil.repeatAndJoin("?", 0, ",")   = ""
+	 * CharSequenceUtil.repeatAndJoin("?", 5, null) = "?????"
 	 * 
* * @param str 被重复的字符串 @@ -3071,10 +3065,10 @@ public class CharSequenceUtil { * 同:leftPad (org.apache.commons.lang3.leftPad) * *
-	 * StrUtil.padPre(null, *, *);//null
-	 * StrUtil.padPre("1", 3, "ABC");//"AB1"
-	 * StrUtil.padPre("123", 2, "ABC");//"12"
-	 * StrUtil.padPre("1039", -1, "0");//"103"
+	 * CharSequenceUtil.padPre(null, *, *);//null
+	 * CharSequenceUtil.padPre("1", 3, "ABC");//"AB1"
+	 * CharSequenceUtil.padPre("123", 2, "ABC");//"12"
+	 * CharSequenceUtil.padPre("1039", -1, "0");//"103"
 	 * 
* * @param str 字符串 @@ -3102,9 +3096,9 @@ public class CharSequenceUtil { * 同:leftPad (org.apache.commons.lang3.leftPad) * *
-	 * StrUtil.padPre(null, *, *);//null
-	 * StrUtil.padPre("1", 3, '0');//"001"
-	 * StrUtil.padPre("123", 2, '0');//"12"
+	 * CharSequenceUtil.padPre(null, *, *);//null
+	 * CharSequenceUtil.padPre("1", 3, '0');//"001"
+	 * CharSequenceUtil.padPre("123", 2, '0');//"12"
 	 * 
* * @param str 字符串 @@ -3131,10 +3125,10 @@ public class CharSequenceUtil { * 补充字符串以满足最小长度,如果提供的字符串大于指定长度,截断之 * *
-	 * StrUtil.padAfter(null, *, *);//null
-	 * StrUtil.padAfter("1", 3, '0');//"100"
-	 * StrUtil.padAfter("123", 2, '0');//"23"
-	 * StrUtil.padAfter("123", -1, '0')//"" 空串
+	 * CharSequenceUtil.padAfter(null, *, *);//null
+	 * CharSequenceUtil.padAfter("1", 3, '0');//"100"
+	 * CharSequenceUtil.padAfter("123", 2, '0');//"23"
+	 * CharSequenceUtil.padAfter("123", -1, '0')//"" 空串
 	 * 
* * @param str 字符串,如果为{@code null},直接返回null @@ -3161,9 +3155,9 @@ public class CharSequenceUtil { * 补充字符串以满足最小长度 * *
-	 * StrUtil.padAfter(null, *, *);//null
-	 * StrUtil.padAfter("1", 3, "ABC");//"1AB"
-	 * StrUtil.padAfter("123", 2, "ABC");//"23"
+	 * CharSequenceUtil.padAfter(null, *, *);//null
+	 * CharSequenceUtil.padAfter("1", 3, "ABC");//"1AB"
+	 * CharSequenceUtil.padAfter("123", 2, "ABC");//"23"
 	 * 
* * @param str 字符串,如果为{@code null},直接返回null @@ -3193,12 +3187,12 @@ public class CharSequenceUtil { * 居中字符串,两边补充指定字符串,如果指定长度小于字符串,则返回原字符串 * *
-	 * StrUtil.center(null, *)   = null
-	 * StrUtil.center("", 4)     = "    "
-	 * StrUtil.center("ab", -1)  = "ab"
-	 * StrUtil.center("ab", 4)   = " ab "
-	 * StrUtil.center("abcd", 2) = "abcd"
-	 * StrUtil.center("a", 4)    = " a  "
+	 * CharSequenceUtil.center(null, *)   = null
+	 * CharSequenceUtil.center("", 4)     = "    "
+	 * CharSequenceUtil.center("ab", -1)  = "ab"
+	 * CharSequenceUtil.center("ab", 4)   = " ab "
+	 * CharSequenceUtil.center("abcd", 2) = "abcd"
+	 * CharSequenceUtil.center("a", 4)    = " a  "
 	 * 
* * @param str 字符串 @@ -3214,14 +3208,14 @@ public class CharSequenceUtil { * 居中字符串,两边补充指定字符串,如果指定长度小于字符串,则返回原字符串 * *
-	 * StrUtil.center(null, *, *)     = null
-	 * StrUtil.center("", 4, ' ')     = "    "
-	 * StrUtil.center("ab", -1, ' ')  = "ab"
-	 * StrUtil.center("ab", 4, ' ')   = " ab "
-	 * StrUtil.center("abcd", 2, ' ') = "abcd"
-	 * StrUtil.center("a", 4, ' ')    = " a  "
-	 * StrUtil.center("a", 4, 'y')   = "yayy"
-	 * StrUtil.center("abc", 7, ' ')   = "  abc  "
+	 * CharSequenceUtil.center(null, *, *)     = null
+	 * CharSequenceUtil.center("", 4, ' ')     = "    "
+	 * CharSequenceUtil.center("ab", -1, ' ')  = "ab"
+	 * CharSequenceUtil.center("ab", 4, ' ')   = " ab "
+	 * CharSequenceUtil.center("abcd", 2, ' ') = "abcd"
+	 * CharSequenceUtil.center("a", 4, ' ')    = " a  "
+	 * CharSequenceUtil.center("a", 4, 'y')   = "yayy"
+	 * CharSequenceUtil.center("abc", 7, ' ')   = "  abc  "
 	 * 
* * @param str 字符串 @@ -3248,15 +3242,15 @@ public class CharSequenceUtil { * 居中字符串,两边补充指定字符串,如果指定长度小于字符串,则返回原字符串 * *
-	 * StrUtil.center(null, *, *)     = null
-	 * StrUtil.center("", 4, " ")     = "    "
-	 * StrUtil.center("ab", -1, " ")  = "ab"
-	 * StrUtil.center("ab", 4, " ")   = " ab "
-	 * StrUtil.center("abcd", 2, " ") = "abcd"
-	 * StrUtil.center("a", 4, " ")    = " a  "
-	 * StrUtil.center("a", 4, "yz")   = "yayz"
-	 * StrUtil.center("abc", 7, null) = "  abc  "
-	 * StrUtil.center("abc", 7, "")   = "  abc  "
+	 * CharSequenceUtil.center(null, *, *)     = null
+	 * CharSequenceUtil.center("", 4, " ")     = "    "
+	 * CharSequenceUtil.center("ab", -1, " ")  = "ab"
+	 * CharSequenceUtil.center("ab", 4, " ")   = " ab "
+	 * CharSequenceUtil.center("abcd", 2, " ") = "abcd"
+	 * CharSequenceUtil.center("a", 4, " ")    = " a  "
+	 * CharSequenceUtil.center("a", 4, "yz")   = "yayz"
+	 * CharSequenceUtil.center("abc", 7, null) = "  abc  "
+	 * CharSequenceUtil.center("abc", 7, "")   = "  abc  "
 	 * 
* * @param str 字符串 @@ -3300,13 +3294,13 @@ public class CharSequenceUtil { * 参数为 {@code null} 或者 "" 返回 {@code 0}. * *
-	 * StrUtil.count(null, *)       = 0
-	 * StrUtil.count("", *)         = 0
-	 * StrUtil.count("abba", null)  = 0
-	 * StrUtil.count("abba", "")    = 0
-	 * StrUtil.count("abba", "a")   = 2
-	 * StrUtil.count("abba", "ab")  = 1
-	 * StrUtil.count("abba", "xxx") = 0
+	 * CharSequenceUtil.count(null, *)       = 0
+	 * CharSequenceUtil.count("", *)         = 0
+	 * CharSequenceUtil.count("abba", null)  = 0
+	 * CharSequenceUtil.count("abba", "")    = 0
+	 * CharSequenceUtil.count("abba", "a")   = 2
+	 * CharSequenceUtil.count("abba", "ab")  = 1
+	 * CharSequenceUtil.count("abba", "xxx") = 0
 	 * 
* * @param content 被查找的字符串 @@ -3356,16 +3350,16 @@ public class CharSequenceUtil { * 比较两个字符串,用于排序 * *
-	 * StrUtil.compare(null, null, *)     = 0
-	 * StrUtil.compare(null , "a", true)  < 0
-	 * StrUtil.compare(null , "a", false) > 0
-	 * StrUtil.compare("a", null, true)   > 0
-	 * StrUtil.compare("a", null, false)  < 0
-	 * StrUtil.compare("abc", "abc", *)   = 0
-	 * StrUtil.compare("a", "b", *)       < 0
-	 * StrUtil.compare("b", "a", *)       > 0
-	 * StrUtil.compare("a", "B", *)       > 0
-	 * StrUtil.compare("ab", "abc", *)    < 0
+	 * CharSequenceUtil.compare(null, null, *)     = 0
+	 * CharSequenceUtil.compare(null , "a", true)  < 0
+	 * CharSequenceUtil.compare(null , "a", false) > 0
+	 * CharSequenceUtil.compare("a", null, true)   > 0
+	 * CharSequenceUtil.compare("a", null, false)  < 0
+	 * CharSequenceUtil.compare("abc", "abc", *)   = 0
+	 * CharSequenceUtil.compare("a", "b", *)       < 0
+	 * CharSequenceUtil.compare("b", "a", *)       > 0
+	 * CharSequenceUtil.compare("a", "B", *)       > 0
+	 * CharSequenceUtil.compare("ab", "abc", *)    < 0
 	 * 
* * @param str1 字符串1 @@ -3390,18 +3384,18 @@ public class CharSequenceUtil { * 比较两个字符串,用于排序,大小写不敏感 * *
-	 * StrUtil.compareIgnoreCase(null, null, *)     = 0
-	 * StrUtil.compareIgnoreCase(null , "a", true)  < 0
-	 * StrUtil.compareIgnoreCase(null , "a", false) > 0
-	 * StrUtil.compareIgnoreCase("a", null, true)   > 0
-	 * StrUtil.compareIgnoreCase("a", null, false)  < 0
-	 * StrUtil.compareIgnoreCase("abc", "abc", *)   = 0
-	 * StrUtil.compareIgnoreCase("abc", "ABC", *)   = 0
-	 * StrUtil.compareIgnoreCase("a", "b", *)       < 0
-	 * StrUtil.compareIgnoreCase("b", "a", *)       > 0
-	 * StrUtil.compareIgnoreCase("a", "B", *)       < 0
-	 * StrUtil.compareIgnoreCase("A", "b", *)       < 0
-	 * StrUtil.compareIgnoreCase("ab", "abc", *)    < 0
+	 * CharSequenceUtil.compareIgnoreCase(null, null, *)     = 0
+	 * CharSequenceUtil.compareIgnoreCase(null , "a", true)  < 0
+	 * CharSequenceUtil.compareIgnoreCase(null , "a", false) > 0
+	 * CharSequenceUtil.compareIgnoreCase("a", null, true)   > 0
+	 * CharSequenceUtil.compareIgnoreCase("a", null, false)  < 0
+	 * CharSequenceUtil.compareIgnoreCase("abc", "abc", *)   = 0
+	 * CharSequenceUtil.compareIgnoreCase("abc", "ABC", *)   = 0
+	 * CharSequenceUtil.compareIgnoreCase("a", "b", *)       < 0
+	 * CharSequenceUtil.compareIgnoreCase("b", "a", *)       > 0
+	 * CharSequenceUtil.compareIgnoreCase("a", "B", *)       < 0
+	 * CharSequenceUtil.compareIgnoreCase("A", "b", *)       < 0
+	 * CharSequenceUtil.compareIgnoreCase("ab", "abc", *)    < 0
 	 * 
* * @param str1 字符串1 @@ -3427,14 +3421,14 @@ public class CharSequenceUtil { * null版本排在最小:即: * *
-	 * StrUtil.compareVersion(null, "v1") < 0
-	 * StrUtil.compareVersion("v1", "v1")  = 0
-	 * StrUtil.compareVersion(null, null)   = 0
-	 * StrUtil.compareVersion("v1", null) > 0
-	 * StrUtil.compareVersion("1.0.0", "1.0.2") < 0
-	 * StrUtil.compareVersion("1.0.2", "1.0.2a") < 0
-	 * StrUtil.compareVersion("1.13.0", "1.12.1c") > 0
-	 * StrUtil.compareVersion("V0.0.20170102", "V0.0.20170101") > 0
+	 * CharSequenceUtil.compareVersion(null, "v1") < 0
+	 * CharSequenceUtil.compareVersion("v1", "v1")  = 0
+	 * CharSequenceUtil.compareVersion(null, null)   = 0
+	 * CharSequenceUtil.compareVersion("v1", null) > 0
+	 * CharSequenceUtil.compareVersion("1.0.0", "1.0.2") < 0
+	 * CharSequenceUtil.compareVersion("1.0.2", "1.0.2a") < 0
+	 * CharSequenceUtil.compareVersion("1.13.0", "1.12.1c") > 0
+	 * CharSequenceUtil.compareVersion("V0.0.20170102", "V0.0.20170101") > 0
 	 * 
* * @param version1 版本1 @@ -3828,13 +3822,13 @@ public class CharSequenceUtil { * 俗称:脱敏功能,后面其他功能,可以见:DesensitizedUtil(脱敏工具类) * *
-	 * StrUtil.hide(null,*,*)=null
-	 * StrUtil.hide("",0,*)=""
-	 * StrUtil.hide("jackduan@163.com",-1,4)   ****duan@163.com
-	 * StrUtil.hide("jackduan@163.com",2,3)    ja*kduan@163.com
-	 * StrUtil.hide("jackduan@163.com",3,2)    jackduan@163.com
-	 * StrUtil.hide("jackduan@163.com",16,16)  jackduan@163.com
-	 * StrUtil.hide("jackduan@163.com",16,17)  jackduan@163.com
+	 * CharSequenceUtil.hide(null,*,*)=null
+	 * CharSequenceUtil.hide("",0,*)=""
+	 * CharSequenceUtil.hide("jackduan@163.com",-1,4)   ****duan@163.com
+	 * CharSequenceUtil.hide("jackduan@163.com",2,3)    ja*kduan@163.com
+	 * CharSequenceUtil.hide("jackduan@163.com",3,2)    jackduan@163.com
+	 * CharSequenceUtil.hide("jackduan@163.com",16,16)  jackduan@163.com
+	 * CharSequenceUtil.hide("jackduan@163.com",16,17)  jackduan@163.com
 	 * 
* * @param str 字符串 @@ -3851,16 +3845,16 @@ public class CharSequenceUtil { * 脱敏,使用默认的脱敏策略 * *
-	 * StrUtil.desensitized("100", DesensitizedUtil.DesensitizedType.USER_ID)) =  "0"
-	 * StrUtil.desensitized("段正淳", DesensitizedUtil.DesensitizedType.CHINESE_NAME)) = "段**"
-	 * StrUtil.desensitized("51343620000320711X", DesensitizedUtil.DesensitizedType.ID_CARD)) = "5***************1X"
-	 * StrUtil.desensitized("09157518479", DesensitizedUtil.DesensitizedType.FIXED_PHONE)) = "0915*****79"
-	 * StrUtil.desensitized("18049531999", DesensitizedUtil.DesensitizedType.MOBILE_PHONE)) = "180****1999"
-	 * StrUtil.desensitized("北京市海淀区马连洼街道289号", DesensitizedUtil.DesensitizedType.ADDRESS)) = "北京市海淀区马********"
-	 * StrUtil.desensitized("duandazhi-jack@gmail.com.cn", DesensitizedUtil.DesensitizedType.EMAIL)) = "d*************@gmail.com.cn"
-	 * StrUtil.desensitized("1234567890", DesensitizedUtil.DesensitizedType.PASSWORD)) = "**********"
-	 * StrUtil.desensitized("苏D40000", DesensitizedUtil.DesensitizedType.CAR_LICENSE)) = "苏D4***0"
-	 * StrUtil.desensitized("11011111222233333256", DesensitizedType.BANK_CARD)) = "1101 **** **** **** 3256"
+	 * CharSequenceUtil.desensitized("100", DesensitizedUtil.DesensitizedType.USER_ID)) =  "0"
+	 * CharSequenceUtil.desensitized("段正淳", DesensitizedUtil.DesensitizedType.CHINESE_NAME)) = "段**"
+	 * CharSequenceUtil.desensitized("51343620000320711X", DesensitizedUtil.DesensitizedType.ID_CARD)) = "5***************1X"
+	 * CharSequenceUtil.desensitized("09157518479", DesensitizedUtil.DesensitizedType.FIXED_PHONE)) = "0915*****79"
+	 * CharSequenceUtil.desensitized("18049531999", DesensitizedUtil.DesensitizedType.MOBILE_PHONE)) = "180****1999"
+	 * CharSequenceUtil.desensitized("北京市海淀区马连洼街道289号", DesensitizedUtil.DesensitizedType.ADDRESS)) = "北京市海淀区马********"
+	 * CharSequenceUtil.desensitized("duandazhi-jack@gmail.com.cn", DesensitizedUtil.DesensitizedType.EMAIL)) = "d*************@gmail.com.cn"
+	 * CharSequenceUtil.desensitized("1234567890", DesensitizedUtil.DesensitizedType.PASSWORD)) = "**********"
+	 * CharSequenceUtil.desensitized("苏D40000", DesensitizedUtil.DesensitizedType.CAR_LICENSE)) = "苏D4***0"
+	 * CharSequenceUtil.desensitized("11011111222233333256", DesensitizedType.BANK_CARD)) = "1101 **** **** **** 3256"
 	 * 
* * @param str 字符串 @@ -4005,7 +3999,7 @@ public class CharSequenceUtil { */ @SuppressWarnings("unchecked") public static T firstNonEmpty(T... strs) { - return ArrayUtil.firstMatch(StrUtil::isNotEmpty, strs); + return ArrayUtil.firstMatch(CharSequenceUtil::isNotEmpty, strs); } /** @@ -4019,7 +4013,7 @@ public class CharSequenceUtil { */ @SuppressWarnings("unchecked") public static T firstNonBlank(T... strs) { - return ArrayUtil.firstMatch(StrUtil::isNotBlank, strs); + return ArrayUtil.firstMatch(CharSequenceUtil::isNotBlank, strs); } // ------------------------------------------------------------------------ lower and upper @@ -4161,9 +4155,9 @@ public class CharSequenceUtil { * 切换给定字符串中的大小写。大写转小写,小写转大写。 * *
-	 * StrUtil.swapCase(null)                 = null
-	 * StrUtil.swapCase("")                   = ""
-	 * StrUtil.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
+	 * CharSequenceUtil.swapCase(null)                 = null
+	 * CharSequenceUtil.swapCase("")                   = ""
+	 * CharSequenceUtil.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
 	 * 
* * @param str 字符串 @@ -4257,7 +4251,7 @@ public class CharSequenceUtil { * @return 是否包围,空串不包围 */ public static boolean isSurround(CharSequence str, CharSequence prefix, CharSequence suffix) { - if (StrUtil.isBlank(str)) { + if (CharSequenceUtil.isBlank(str)) { return false; } if (str.length() < (prefix.length() + suffix.length())) { @@ -4277,7 +4271,7 @@ public class CharSequenceUtil { * @return 是否包围,空串不包围 */ public static boolean isSurround(CharSequence str, char prefix, char suffix) { - if (StrUtil.isBlank(str)) { + if (CharSequenceUtil.isBlank(str)) { return false; } if (str.length() < 2) { @@ -4462,7 +4456,7 @@ public class CharSequenceUtil { * @since 3.2.3 */ public static boolean isAllCharMatch(CharSequence value, Matcher matcher) { - if (StrUtil.isBlank(value)) { + if (CharSequenceUtil.isBlank(value)) { return false; } for (int i = value.length(); --i >= 0; ) { From f9356b6933d50d4bee208cdd227ac8345e9c1a20 Mon Sep 17 00:00:00 2001 From: handy Date: Thu, 30 Nov 2023 17:13:46 +0800 Subject: [PATCH 11/45] =?UTF-8?q?=E4=BF=AE=E6=94=B9readme=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README-EN.md | 6 +++++- README.md | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/README-EN.md b/README-EN.md index 741a0275f..2f7cc2c31 100755 --- a/README-EN.md +++ b/README-EN.md @@ -115,7 +115,7 @@ Each module can be introduced individually, or all modules can be introduced by ## 📝Doc -[📘Chinese documentation](https://www.hutool.cn/docs/) +[📘Chinese documentation](https://doc.hutool.cn/pages/index/) [📘Chinese back-up documentation](https://plus.hutool.cn/) @@ -209,6 +209,10 @@ Hutool welcomes anyone to contribute code to Hutool, but the author suffers from 3. Newly added methods do not use third-party library methods,Unless the method tool is add to the '**extra module**'. 4. Please pull request to the `v5-dev` branch. Hutool uses a new branch after 5.x: `v5-master` is the master branch, which indicates the version of the central library that has been released, and this branch does not allow pr or modifications. +### 📖 Documentation source code + +[Documentation source code](https://gitee.com/loolly_admin/hutool-doc-handy) + ------------------------------------------------------------------------------- ## ⭐Star Hutool diff --git a/README.md b/README.md index 4c5f7abd9..758f7ecce 100755 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ Hutool = Hu + tool,是原公司项目底层代码剥离后的开源库,“Hu ## 📝文档 -[📘中文文档](https://www.hutool.cn/docs/) +[📘中文文档](https://doc.hutool.cn/pages/index/) [📘中文备用文档](https://plus.hutool.cn/) @@ -212,6 +212,10 @@ Hutool欢迎任何人为Hutool添砖加瓦,贡献代码,不过维护者是 4. 请pull request到`v5-dev`分支。Hutool在5.x版本后使用了新的分支:`v5-master`是主分支,表示已经发布中央库的版本,这个分支不允许pr,也不允许修改。 5. 我们如果关闭了你的issue或pr,请不要诧异,这是我们保持问题处理整洁的一种方式,你依旧可以继续讨论,当有讨论结果时我们会重新打开。 +### 📖文档源码地址 + +[文档源码地址](https://gitee.com/loolly_admin/hutool-doc-handy) 点击前往添砖加瓦 + ------------------------------------------------------------------------------- ## ⭐Star Hutool From b989e266232b735a54451eb47012800a87d70c0d Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 1 Dec 2023 09:26:34 +0800 Subject: [PATCH 12/45] update dependency --- hutool-extra/pom.xml | 2 +- hutool-log/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml index 2865d3df9..a9ccd837d 100755 --- a/hutool-extra/pom.xml +++ b/hutool-extra/pom.xml @@ -394,7 +394,7 @@ ch.qos.logback logback-classic - 1.2.11 + 1.4.13 test diff --git a/hutool-log/pom.xml b/hutool-log/pom.xml index 70fd8667d..4a4f1bafd 100755 --- a/hutool-log/pom.xml +++ b/hutool-log/pom.xml @@ -21,7 +21,7 @@ 1.7.36 - 1.4.6 + 1.4.13 1.2.17 2.20.0 1.2 From 870758c3d079a3426a7a06b1a16be73058371313 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 1 Dec 2023 18:28:35 +0800 Subject: [PATCH 13/45] fix comment --- hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java index a29962c3a..864a14437 100755 --- a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java @@ -28,7 +28,7 @@ import java.util.function.Function; import java.util.stream.Collectors; /** - * 时间工具类 + * 日期时间工具类 * * @author xiaoleilu * @see LocalDateTimeUtil java8日志工具类 From 3e098270ea2212753c63be2c47323b64589a3906 Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 3 Dec 2023 22:34:17 +0800 Subject: [PATCH 14/45] add test --- .../cn/hutool/core/bean/IssueI8JASOTest.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 hutool-core/src/test/java/cn/hutool/core/bean/IssueI8JASOTest.java diff --git a/hutool-core/src/test/java/cn/hutool/core/bean/IssueI8JASOTest.java b/hutool-core/src/test/java/cn/hutool/core/bean/IssueI8JASOTest.java new file mode 100644 index 000000000..93bc9753d --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/bean/IssueI8JASOTest.java @@ -0,0 +1,33 @@ +package cn.hutool.core.bean; + +import cn.hutool.core.annotation.Alias; +import lombok.Data; +import lombok.Setter; +import org.junit.Assert; +import org.junit.Test; + +public class IssueI8JASOTest { + + @Test + public void copyTest() { + final UserOne userOne = new UserOne(); + userOne.setEmail("123@qq.com"); + final UserTwo userTwo = new UserTwo(); + BeanUtil.copyProperties(userOne, userTwo); + Assert.assertEquals(userOne.getEmail(), userTwo.getEmail()); + } + + @Data + public static class UserOne { + private Long id; + @Alias("邮箱") + private String email; + } + + @Data + public static class UserTwo { + private Long id; + @Alias("邮箱") + private String email; + } +} From d406130183b4fd2effe6a6c68d08c163445527a5 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 4 Dec 2023 18:26:12 +0800 Subject: [PATCH 15/45] fix comment --- hutool-core/src/main/java/cn/hutool/core/codec/Morse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/codec/Morse.java b/hutool-core/src/main/java/cn/hutool/core/codec/Morse.java index 403ba21c3..0ed10b05b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/codec/Morse.java +++ b/hutool-core/src/main/java/cn/hutool/core/codec/Morse.java @@ -10,7 +10,7 @@ import cn.hutool.core.util.StrUtil; /** * 莫尔斯电码的编码和解码实现
- * 参考:https://github.com/TakWolf/Java-MorseCoder + * 参考:https://github.com/TakWolf-Deprecated/Java-MorseCoder * * @author looly, TakWolf * @since 4.4.1 From 26c0ea6a896eec6b545c9dbbfdd131eb1c7525f8 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 4 Dec 2023 18:39:07 +0800 Subject: [PATCH 16/45] fix comment --- .../main/java/cn/hutool/core/convert/NumberWordFormatter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java b/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java index e835593e4..e93978015 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java @@ -5,7 +5,8 @@ import cn.hutool.core.util.StrUtil; /** * 将浮点数类型的number转换成英语的表达方式
- * 参考博客:http://blog.csdn.net/eric_sunah/article/details/8713226 + * 参考博客:http://blog.csdn.net/eric_sunah/article/details/8713226
+ * 本质上此类为金额转英文表达,因此没有四舍五入考虑,小数点超过两位直接忽略。 * * @author Looly,totalo * @since 3.0.9 From d09f74131831c18e1bea4ca48a81ba6229bebb9a Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 4 Dec 2023 19:05:11 +0800 Subject: [PATCH 17/45] add test --- .../src/test/java/cn/hutool/core/util/StrUtilTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java index 558ae6b24..d2bbce4e2 100755 --- a/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java @@ -670,6 +670,13 @@ public class StrUtilTest { Assert.assertEquals(str, ret); } + @Test + public void truncateUtf8Test2() { + final String str = "这是This一"; + final String ret = StrUtil.truncateUtf8(str, 12); + Assert.assertEquals("这是Thi...", ret); + } + @Test public void truncateByByteLengthTest() { final String str = "This is English"; From 9a69843f5e0f2b7318d0e2e6de89e147e7a928e9 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 4 Dec 2023 19:20:33 +0800 Subject: [PATCH 18/45] fix test --- .../src/test/java/cn/hutool/core/util/StrUtilTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java index d2bbce4e2..5a99ca85c 100755 --- a/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java @@ -673,8 +673,8 @@ public class StrUtilTest { @Test public void truncateUtf8Test2() { final String str = "这是This一"; - final String ret = StrUtil.truncateUtf8(str, 12); - Assert.assertEquals("这是Thi...", ret); + final String ret = StrUtil.truncateUtf8(str, 13); + Assert.assertEquals("这是This一", ret); } @Test From 86aba711f192932a9e1251350e1e8f9e1f5be211 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 4 Dec 2023 19:39:40 +0800 Subject: [PATCH 19/45] fix test --- .../src/test/java/cn/hutool/core/util/StrUtilTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java index 5a99ca85c..d1e1ca03b 100755 --- a/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/StrUtilTest.java @@ -3,6 +3,7 @@ package cn.hutool.core.util; import java.nio.charset.StandardCharsets; import java.util.List; +import cn.hutool.core.lang.Console; import cn.hutool.core.lang.Dict; import org.junit.Assert; import org.junit.Test; @@ -677,6 +678,13 @@ public class StrUtilTest { Assert.assertEquals("这是This一", ret); } + @Test + public void truncateUtf8Test3() { + final String str = "一二三四"; + final String ret = StrUtil.truncateUtf8(str, 11); + Assert.assertEquals("一二...", ret); + } + @Test public void truncateByByteLengthTest() { final String str = "This is English"; From fb1b82889828d7cfdd7b8378736a87b1340bb3c9 Mon Sep 17 00:00:00 2001 From: Charles7c Date: Mon, 4 Dec 2023 21:56:03 +0800 Subject: [PATCH 20/45] =?UTF-8?q?SpringUtil=E5=A2=9E=E5=8A=A0getProperty?= =?UTF-8?q?=E9=87=8D=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/hutool/extra/spring/SpringUtil.java | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/hutool-extra/src/main/java/cn/hutool/extra/spring/SpringUtil.java b/hutool-extra/src/main/java/cn/hutool/extra/spring/SpringUtil.java index 203888014..f8219f8d1 100755 --- a/hutool-extra/src/main/java/cn/hutool/extra/spring/SpringUtil.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/spring/SpringUtil.java @@ -182,10 +182,35 @@ public class SpringUtil implements BeanFactoryPostProcessor, ApplicationContextA * @since 5.3.3 */ public static String getProperty(String key) { + return getProperty(key, null); + } + + /** + * 获取配置文件配置项的值 + * + * @param key 配置项key + * @param defaultValue 默认值 + * @return 属性值 + * @since 5.8.24 + */ + public static String getProperty(String key, String defaultValue) { + return getProperty(key, String.class, defaultValue); + } + + /** + * 获取配置文件配置项的值 + * + * @param key 配置项key + * @param targetType 配置项类型 + * @param defaultValue 默认值 + * @return 属性值 + * @since 5.8.24 + */ + public static T getProperty(String key, Class targetType, T defaultValue) { if (null == applicationContext) { return null; } - return applicationContext.getEnvironment().getProperty(key); + return applicationContext.getEnvironment().getProperty(key, targetType, defaultValue); } /** From c61946650ee3b4be7f1478e65b07b71e46df6d5d Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 4 Dec 2023 23:27:25 +0800 Subject: [PATCH 21/45] fix comment --- hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java index 2ccd49633..5695c7c23 100755 --- a/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java @@ -488,7 +488,9 @@ public class StrUtil extends CharSequenceUtil implements StrPool { } /** - * 截断字符串,使用其按照指定编码为字节后不超过maxBytes长度 + * 截断字符串,使用其按照指定编码为字节后不超过maxBytes长度
+ * 此方法用于截取总bytes数不超过指定长度,如果字符出没有超出原样输出,如果超出了,则截取掉超出部分,并可选添加..., + * 但是添加“...”后总长度也不超过限制长度。 * * @param str 原始字符串 * @param charset 指定编码 From c359a547cf2dd7cbe73320dc94bf0db9a3a79053 Mon Sep 17 00:00:00 2001 From: bwcx_jzy Date: Tue, 5 Dec 2023 16:45:33 +0800 Subject: [PATCH 22/45] =?UTF-8?q?fix=20Archiver=20=E6=9C=80=E5=90=8E?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=20Entry=20=E4=B8=BA=E7=A9=BA=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=A4=B9=E6=97=B6=E6=9C=AA=E5=85=B3=E9=97=AD=20Entry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../compress/archiver/StreamArchiver.java | 2 ++ .../hutool/extra/compress/ArchiverTest.java | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/StreamArchiver.java b/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/StreamArchiver.java index 5372b7381..99d5e38b1 100755 --- a/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/StreamArchiver.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/StreamArchiver.java @@ -177,6 +177,8 @@ public class StreamArchiver implements Archiver { for (File childFile : files) { addInternal(childFile, entryName, filter); } + } else { + out.closeArchiveEntry(); } } else { if (file.isFile()) { diff --git a/hutool-extra/src/test/java/cn/hutool/extra/compress/ArchiverTest.java b/hutool-extra/src/test/java/cn/hutool/extra/compress/ArchiverTest.java index 8ba8d499a..3175efc3e 100644 --- a/hutool-extra/src/test/java/cn/hutool/extra/compress/ArchiverTest.java +++ b/hutool-extra/src/test/java/cn/hutool/extra/compress/ArchiverTest.java @@ -72,4 +72,36 @@ public class ArchiverTest { }) .finish().close(); } + + /** + * Add: D:\disk-all + * Add: D:\disk-all\els-app + * Add: D:\disk-all\els-app\db-backup + * Add: D:\disk-all\els-app\新建 文本文档.txt + * Add: D:\disk-all\新建 文本文档.txt + * Add: D:\disk-all\新建文件夹 + */ + @Test + @Ignore + public void emptyTest(){ + final File file = FileUtil.file("d:/disk-all.tgz"); + CompressUtil.createArchiver(CharsetUtil.CHARSET_UTF_8, "tgz", file) + .add(FileUtil.file("D:\\disk-all"), (f)->{ + Console.log("Add: {}", f.getPath()); + return true; + }) + .finish().close(); + } + + @Test + @Ignore + public void emptyZTest(){ + final File file = FileUtil.file("d:/disk-all.7z"); + CompressUtil.createArchiver(CharsetUtil.CHARSET_UTF_8, "7z", file) + .add(FileUtil.file("D:\\disk-all"), (f)->{ + Console.log("Add: {}", f.getPath()); + return true; + }) + .finish().close(); + } } From 2be48d006e91bb6e617aa1d62587fb6291e3bd96 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 5 Dec 2023 20:34:32 +0800 Subject: [PATCH 23/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8DArchiver=20=E6=9C=80?= =?UTF-8?q?=E5=90=8E=E4=B8=80=E4=B8=AA=20Entry=20=E4=B8=BA=E7=A9=BA?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=A4=B9=E6=97=B6=E6=9C=AA=E5=85=B3=E9=97=AD?= =?UTF-8?q?=20Entry=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 961ee4de4..741c9aaf5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.24(2023-11-29) +# 5.8.24(2023-12-05) ### 🐣新特性 * 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) @@ -12,7 +12,8 @@ ### 🐞Bug修复 * 【core 】 修复LocalDateTime#parseDate未判断空问题问题(issue#I8FN7F@Gitee) -* 【http 】 修复 RootAction send404 抛异常问题(pr#1107@Gitee) +* 【http 】 修复RootAction send404 抛异常问题(pr#1107@Gitee) +* 【extra 】 修复Archiver 最后一个 Entry 为空文件夹时未关闭 Entry问题(pr#1123@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) From 9866840b81d94e5739a2ff3957ff3f44701f4709 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 5 Dec 2023 20:46:56 +0800 Subject: [PATCH 24/45] =?UTF-8?q?SpringUtil=E5=A2=9E=E5=8A=A0getProperty?= =?UTF-8?q?=E9=87=8D=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../cn/hutool/extra/spring/SpringUtil.java | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 741c9aaf5..3d99cb460 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * 【cache 】 JWT#sign增加重载,可选是否增加默认的typ参数(issue#3386@Github) * 【db 】 增加识别OpenGauss的驱动类(issue#I8K6C0@Gitee) * 【core 】 修复CharSequenceUtil注释和引用,避免循环引用 +* 【extra 】 SpringUtil增加getProperty重载(pr#1122@Gitee) ### 🐞Bug修复 * 【core 】 修复LocalDateTime#parseDate未判断空问题问题(issue#I8FN7F@Gitee) diff --git a/hutool-extra/src/main/java/cn/hutool/extra/spring/SpringUtil.java b/hutool-extra/src/main/java/cn/hutool/extra/spring/SpringUtil.java index f8219f8d1..abbdbda40 100755 --- a/hutool-extra/src/main/java/cn/hutool/extra/spring/SpringUtil.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/spring/SpringUtil.java @@ -71,8 +71,8 @@ public class SpringUtil implements BeanFactoryPostProcessor, ApplicationContextA * @since 5.7.0 */ public static ListableBeanFactory getBeanFactory() { - final ListableBeanFactory factory = null == beanFactory ? applicationContext : beanFactory; - if(null == factory){ + final ListableBeanFactory factory = null == beanFactory ? applicationContext : beanFactory; + if (null == factory) { throw new UtilException("No ConfigurableListableBeanFactory or ApplicationContext injected, maybe not in the Spring environment?"); } return factory; @@ -182,26 +182,33 @@ public class SpringUtil implements BeanFactoryPostProcessor, ApplicationContextA * @since 5.3.3 */ public static String getProperty(String key) { - return getProperty(key, null); + if (null == applicationContext) { + return null; + } + return applicationContext.getEnvironment().getProperty(key); } /** * 获取配置文件配置项的值 * - * @param key 配置项key + * @param key 配置项key * @param defaultValue 默认值 * @return 属性值 * @since 5.8.24 */ public static String getProperty(String key, String defaultValue) { - return getProperty(key, String.class, defaultValue); + if (null == applicationContext) { + return null; + } + return applicationContext.getEnvironment().getProperty(key, defaultValue); } /** * 获取配置文件配置项的值 * - * @param key 配置项key - * @param targetType 配置项类型 + * @param 属性值类型 + * @param key 配置项key + * @param targetType 配置项类型 * @param defaultValue 默认值 * @return 属性值 * @since 5.8.24 From f85e69ab65fd2b2d6d7cabc34897432b2755ba3d Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 5 Dec 2023 21:48:15 +0800 Subject: [PATCH 25/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8DImgUtil.convert=20png?= =?UTF-8?q?=E8=BD=ACjpg=E5=9C=A8jdk9+=E4=B8=AD=E5=A4=B1=E8=B4=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../main/java/cn/hutool/core/img/ImgUtil.java | 31 ++++++++++--------- .../cn/hutool/core/img/IssueI8L8UATest.java | 15 +++++++++ 3 files changed, 33 insertions(+), 14 deletions(-) create mode 100644 hutool-core/src/test/java/cn/hutool/core/img/IssueI8L8UATest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d99cb460..b79ea152f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ * 【core 】 修复LocalDateTime#parseDate未判断空问题问题(issue#I8FN7F@Gitee) * 【http 】 修复RootAction send404 抛异常问题(pr#1107@Gitee) * 【extra 】 修复Archiver 最后一个 Entry 为空文件夹时未关闭 Entry问题(pr#1123@Gitee) +* 【core 】 修复ImgUtil.convert png转jpg在jdk9+中失败问题(issue#I8L8UA@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) diff --git a/hutool-core/src/main/java/cn/hutool/core/img/ImgUtil.java b/hutool-core/src/main/java/cn/hutool/core/img/ImgUtil.java index a27238a39..6c9a5e0f8 100755 --- a/hutool-core/src/main/java/cn/hutool/core/img/ImgUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/img/ImgUtil.java @@ -531,13 +531,7 @@ public class ImgUtil { FileUtil.copy(srcImageFile, destImageFile, true); } - ImageOutputStream imageOutputStream = null; - try { - imageOutputStream = getImageOutputStream(destImageFile); - convert(read(srcImageFile), destExtName, imageOutputStream, StrUtil.equalsIgnoreCase(IMAGE_TYPE_PNG, srcExtName)); - } finally { - IoUtil.close(imageOutputStream); - } + Img.from(srcImageFile).write(destImageFile); } /** @@ -560,16 +554,25 @@ public class ImgUtil { * @param srcImage 源图像流 * @param formatName 包含格式非正式名称的 String:如JPG、JPEG、GIF等 * @param destImageStream 目标图像输出流 - * @param isSrcPng 源图片是否为PNG格式 * @since 4.1.14 */ + public static void convert(Image srcImage, String formatName, ImageOutputStream destImageStream) { + Img.from(srcImage).setTargetImageType(formatName).write(destImageStream); + } + + /** + * 图像类型转换:GIF=》JPG、GIF=》PNG、PNG=》JPG、PNG=》GIF(X)、BMP=》PNG
+ * 此方法并不关闭流 + * + * @param srcImage 源图像流 + * @param formatName 包含格式非正式名称的 String:如JPG、JPEG、GIF等 + * @param destImageStream 目标图像输出流 + * @param isSrcPng 源图片是否为PNG格式(参数无效) + * @since 4.1.14 + */ + @Deprecated public static void convert(Image srcImage, String formatName, ImageOutputStream destImageStream, boolean isSrcPng) { - final BufferedImage src = toBufferedImage(srcImage, isSrcPng ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB); - try { - ImageIO.write(src, formatName, destImageStream); - } catch (IOException e) { - throw new IORuntimeException(e); - } + convert(srcImage, formatName, destImageStream); } // ---------------------------------------------------------------------------------------------------------------------- grey diff --git a/hutool-core/src/test/java/cn/hutool/core/img/IssueI8L8UATest.java b/hutool-core/src/test/java/cn/hutool/core/img/IssueI8L8UATest.java new file mode 100644 index 000000000..70fcc059c --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/img/IssueI8L8UATest.java @@ -0,0 +1,15 @@ +package cn.hutool.core.img; + +import cn.hutool.core.io.FileUtil; +import org.junit.Ignore; +import org.junit.Test; + +public class IssueI8L8UATest { + @Test + @Ignore + public void convertTest() { + ImgUtil.convert( + FileUtil.file("d:/test/1.png"), + FileUtil.file("d:/test/1.jpg")); + } +} From 9c351cfb84d4f1106ca844bdd1bdf4d71b3345a7 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 8 Dec 2023 23:12:17 +0800 Subject: [PATCH 26/45] fix comment --- .../java/cn/hutool/core/util/NumberUtil.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java index 87040d6cb..e5d748821 100755 --- a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java @@ -2321,80 +2321,80 @@ public class NumberUtil { } /** - * 如果给定值为0,返回1,否则返回原值 + * 如果给定值为{@code null},返回0,否则返回原值 * * @param number 值 - * @return 1或非0值 + * @return 0或非0值 */ public static int nullToZero(Integer number) { return number == null ? 0 : number; } /** - * 如果给定值为0,返回1,否则返回原值 + * 如果给定值为{@code null},返回0,否则返回原值 * * @param number 值 - * @return 1或非0值 + * @return 0或非0值 */ public static long nullToZero(Long number) { return number == null ? 0L : number; } /** - * 如果给定值为0,返回1,否则返回原值 + * 如果给定值为{@code null},返回0,否则返回原值 * * @param number 值 - * @return 1或非0值 + * @return 0或非0值 */ public static double nullToZero(Double number) { return number == null ? 0.0 : number; } /** - * 如果给定值为0,返回1,否则返回原值 + * 如果给定值为{@code null},返回0,否则返回原值 * * @param number 值 - * @return 1或非0值 + * @return 0或非0值 */ public static float nullToZero(Float number) { return number == null ? 0.0f : number; } /** - * 如果给定值为0,返回1,否则返回原值 + * 如果给定值为{@code null},返回0,否则返回原值 * * @param number 值 - * @return 1或非0值 + * @return 0或非0值 */ public static short nullToZero(Short number) { return number == null ? (short) 0 : number; } /** - * 如果给定值为0,返回1,否则返回原值 + * 如果给定值为{@code null},返回0,否则返回原值 * * @param number 值 - * @return 1或非0值 + * @return 0或非0值 */ public static byte nullToZero(Byte number) { return number == null ? (byte) 0 : number; } /** - * 如果给定值为0,返回1,否则返回原值 + * 如果给定值为{@code null},返回0,否则返回原值 * * @param number 值 - * @return 1或非0值 + * @return 0或非0值 */ public static BigDecimal nullToZero(BigDecimal number) { return number == null ? BigDecimal.ZERO : number; } /** - * 如果给定值为0,返回1,否则返回原值 + * 如果给定值为{@code null},返回0,否则返回原值 * * @param number 值 - * @return 1或非0值 + * @return 0或非0值 */ public static BigInteger nullToZero(BigInteger number) { return number == null ? BigInteger.ZERO : number; From 1e06dd4674b68e44915975e391e84ced6c43492e Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 9 Dec 2023 01:05:55 +0800 Subject: [PATCH 27/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8DStampedCache=E7=9A=84ge?= =?UTF-8?q?t=E6=96=B9=E6=B3=95=E9=9D=9E=E5=8E=9F=E5=AD=90=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 +- .../cn/hutool/cache/impl/AbstractCache.java | 10 +- .../java/cn/hutool/cache/impl/FIFOCache.java | 2 +- .../cn/hutool/cache/impl/ReentrantCache.java | 86 ++++++------ .../cn/hutool/cache/impl/StampedCache.java | 122 +++++++++++------- .../java/cn/hutool/cache/IssueI8MEIXTest.java | 30 +++++ 6 files changed, 144 insertions(+), 109 deletions(-) create mode 100644 hutool-cache/src/test/java/cn/hutool/cache/IssueI8MEIXTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index b79ea152f..a38f5a62f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.24(2023-12-05) +# 5.8.24(2023-12-09) ### 🐣新特性 * 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) @@ -16,6 +16,7 @@ * 【http 】 修复RootAction send404 抛异常问题(pr#1107@Gitee) * 【extra 】 修复Archiver 最后一个 Entry 为空文件夹时未关闭 Entry问题(pr#1123@Gitee) * 【core 】 修复ImgUtil.convert png转jpg在jdk9+中失败问题(issue#I8L8UA@Gitee) +* 【cache 】 修复StampedCache的get方法非原子问题(issue#I8MEIX@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) diff --git a/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java b/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java index b33acd3a3..56f4675e2 100755 --- a/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/impl/AbstractCache.java @@ -254,16 +254,10 @@ public abstract class AbstractCache implements Cache { * 移除key对应的对象,不加锁 * * @param key 键 - * @param withMissCount 是否计数丢失数 * @return 移除的对象,无返回null */ - protected CacheObj removeWithoutLock(K key, boolean withMissCount) { - final CacheObj co = cacheMap.remove(MutableObj.of(key)); - if (withMissCount) { - // 在丢失计数有效的情况下,移除一般为get时的超时操作,此处应该丢失数+1 - this.missCount.increment(); - } - return co; + protected CacheObj removeWithoutLock(K key) { + return cacheMap.remove(MutableObj.of(key)); } /** diff --git a/hutool-cache/src/main/java/cn/hutool/cache/impl/FIFOCache.java b/hutool-cache/src/main/java/cn/hutool/cache/impl/FIFOCache.java index a3fc35085..071ac5067 100755 --- a/hutool-cache/src/main/java/cn/hutool/cache/impl/FIFOCache.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/impl/FIFOCache.java @@ -71,7 +71,7 @@ public class FIFOCache extends StampedCache { // 清理结束后依旧是满的,则删除第一个被缓存的对象 if (isFull() && null != first) { - removeWithoutLock(first.key, false); + removeWithoutLock(first.key); onRemove(first.key, first.obj); count++; } diff --git a/hutool-cache/src/main/java/cn/hutool/cache/impl/ReentrantCache.java b/hutool-cache/src/main/java/cn/hutool/cache/impl/ReentrantCache.java index e45474040..8974c4d12 100755 --- a/hutool-cache/src/main/java/cn/hutool/cache/impl/ReentrantCache.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/impl/ReentrantCache.java @@ -33,49 +33,12 @@ public abstract class ReentrantCache extends AbstractCache { @Override public boolean containsKey(K key) { - lock.lock(); - try { - // 不存在或已移除 - final CacheObj co = getWithoutLock(key); - if (co == null) { - return false; - } - - if (false == co.isExpired()) { - // 命中 - return true; - } - } finally { - lock.unlock(); - } - - // 过期 - remove(key, true); - return false; + return null != getOrRemoveExpired(key, false, false); } @Override public V get(K key, boolean isUpdateLastAccess) { - CacheObj co; - lock.lock(); - try { - co = getWithoutLock(key); - } finally { - lock.unlock(); - } - - // 未命中 - if (null == co) { - missCount.increment(); - return null; - } else if (false == co.isExpired()) { - hitCount.increment(); - return co.get(isUpdateLastAccess); - } - - // 过期,既不算命中也不算非命中 - remove(key, true); - return null; + return getOrRemoveExpired(key, isUpdateLastAccess, true); } @Override @@ -102,7 +65,16 @@ public abstract class ReentrantCache extends AbstractCache { @Override public void remove(K key) { - remove(key, false); + lock.lock(); + CacheObj co; + try { + co = removeWithoutLock(key); + } finally { + lock.unlock(); + } + if (null != co) { + onRemove(co.key, co.obj); + } } @Override @@ -126,21 +98,37 @@ public abstract class ReentrantCache extends AbstractCache { } /** - * 移除key对应的对象 - * - * @param key 键 - * @param withMissCount 是否计数丢失数 + * 获得值或清除过期值 + * @param key 键 + * @param isUpdateLastAccess 是否更新最后访问时间 + * @param isUpdateCount 是否更新计数器 + * @return 值或null */ - private void remove(K key, boolean withMissCount) { - lock.lock(); + private V getOrRemoveExpired(final K key, final boolean isUpdateLastAccess, final boolean isUpdateCount) { CacheObj co; + lock.lock(); try { - co = removeWithoutLock(key, withMissCount); + co = getWithoutLock(key); + if(null != co && co.isExpired()){ + //过期移除 + removeWithoutLock(key); + co = null; + } } finally { lock.unlock(); } - if (null != co) { - onRemove(co.key, co.obj); + + // 未命中 + if (null == co) { + if(isUpdateCount){ + missCount.increment(); + } + return null; } + + if(isUpdateCount){ + hitCount.increment(); + } + return co.get(isUpdateLastAccess); } } diff --git a/hutool-cache/src/main/java/cn/hutool/cache/impl/StampedCache.java b/hutool-cache/src/main/java/cn/hutool/cache/impl/StampedCache.java index deaec6641..7727a1fbd 100755 --- a/hutool-cache/src/main/java/cn/hutool/cache/impl/StampedCache.java +++ b/hutool-cache/src/main/java/cn/hutool/cache/impl/StampedCache.java @@ -1,6 +1,7 @@ package cn.hutool.cache.impl; import cn.hutool.core.collection.CopiedIter; +import cn.hutool.core.thread.ThreadUtil; import java.util.Iterator; import java.util.concurrent.locks.StampedLock; @@ -13,7 +14,7 @@ import java.util.concurrent.locks.StampedLock; * @author looly * @since 5.7.15 */ -public abstract class StampedCache extends AbstractCache{ +public abstract class StampedCache extends AbstractCache { private static final long serialVersionUID = 1L; // 乐观锁,此处使用乐观锁解决读多写少的场景 @@ -33,54 +34,12 @@ public abstract class StampedCache extends AbstractCache{ @Override public boolean containsKey(K key) { - final long stamp = lock.readLock(); - try { - // 不存在或已移除 - final CacheObj co = getWithoutLock(key); - if (co == null) { - return false; - } - - if (false == co.isExpired()) { - // 命中 - return true; - } - } finally { - lock.unlockRead(stamp); - } - - // 过期 - remove(key, true); - return false; + return null != get(key, false, false); } @Override public V get(K key, boolean isUpdateLastAccess) { - // 尝试读取缓存,使用乐观读锁 - long stamp = lock.tryOptimisticRead(); - CacheObj co = getWithoutLock(key); - if(false == lock.validate(stamp)){ - // 有写线程修改了此对象,悲观读 - stamp = lock.readLock(); - try { - co = getWithoutLock(key); - } finally { - lock.unlockRead(stamp); - } - } - - // 未命中 - if (null == co) { - missCount.increment(); - return null; - } else if (false == co.isExpired()) { - hitCount.increment(); - return co.get(isUpdateLastAccess); - } - - // 过期,既不算命中也不算非命中 - remove(key, true); - return null; + return get(key, isUpdateLastAccess, true); } @Override @@ -107,7 +66,16 @@ public abstract class StampedCache extends AbstractCache{ @Override public void remove(K key) { - remove(key, false); + final long stamp = lock.writeLock(); + CacheObj co; + try { + co = removeWithoutLock(key); + } finally { + lock.unlockWrite(stamp); + } + if (null != co) { + onRemove(co.key, co.obj); + } } @Override @@ -121,21 +89,75 @@ public abstract class StampedCache extends AbstractCache{ } /** - * 移除key对应的对象 + * 获取值 + * + * @param key 键 + * @param isUpdateLastAccess 是否更新最后修改时间 + * @param isUpdateCount 是否更新命中数,get时更新,contains时不更新 + * @return 值或null + */ + private V get(K key, boolean isUpdateLastAccess, boolean isUpdateCount) { + // 尝试读取缓存,使用乐观读锁 + long stamp = lock.tryOptimisticRead(); + CacheObj co = getWithoutLock(key); + if (false == lock.validate(stamp)) { + // 有写线程修改了此对象,悲观读 + stamp = lock.readLock(); + try { + co = getWithoutLock(key); + } finally { + lock.unlockRead(stamp); + } + } + + // 未命中 + if (null == co) { + if (isUpdateCount) { + missCount.increment(); + } + return null; + } else if (false == co.isExpired()) { + if (isUpdateCount) { + hitCount.increment(); + } + return co.get(isUpdateLastAccess); + } + + // 悲观锁,二次检查 + return getOrRemoveExpired(key, isUpdateCount); + } + + /** + * 同步获取值,如果过期则移除之 * * @param key 键 - * @param withMissCount 是否计数丢失数 + * @param isUpdateCount 是否更新命中数,get时更新,contains时不更新 + * @return 有效值或null */ - private void remove(K key, boolean withMissCount) { + private V getOrRemoveExpired(K key, boolean isUpdateCount) { final long stamp = lock.writeLock(); CacheObj co; try { - co = removeWithoutLock(key, withMissCount); + co = getWithoutLock(key); + if (null == co) { + return null; + } + if (false == co.isExpired()) { + // 首先尝试获取值,如果值存在且有效,返回之 + if (isUpdateCount) { + hitCount.increment(); + } + return co.getValue(); + } + + // 无效移除 + co = removeWithoutLock(key); } finally { lock.unlockWrite(stamp); } if (null != co) { onRemove(co.key, co.obj); } + return null; } } diff --git a/hutool-cache/src/test/java/cn/hutool/cache/IssueI8MEIXTest.java b/hutool-cache/src/test/java/cn/hutool/cache/IssueI8MEIXTest.java new file mode 100644 index 000000000..4126f292f --- /dev/null +++ b/hutool-cache/src/test/java/cn/hutool/cache/IssueI8MEIXTest.java @@ -0,0 +1,30 @@ +package cn.hutool.cache; + +import cn.hutool.cache.impl.TimedCache; +import cn.hutool.core.lang.Console; +import cn.hutool.core.thread.ThreadUtil; +import org.junit.Ignore; +import org.junit.Test; + +public class IssueI8MEIXTest { + + @Test + @Ignore + public void getRemoveTest() { + final TimedCache cache = new TimedCache<>(200); + cache.put("a", "123"); + + ThreadUtil.sleep(300); + + // 测试时,在get后的remove前加sleep测试在读取过程中put新值的问题 + ThreadUtil.execute(()->{ + Console.log(cache.get("a")); + }); + + ThreadUtil.execute(()->{ + cache.put("a", "456"); + }); + + ThreadUtil.sleep(1000); + } +} From 4ab74605bef016493947845904bb65aa7cb522a7 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 11 Dec 2023 09:45:06 +0800 Subject: [PATCH 28/45] =?UTF-8?q?FileTypeUtil=E5=A2=9E=E5=8A=A0null?= =?UTF-8?q?=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 +- .../java/cn/hutool/core/io/FileTypeUtil.java | 76 ++++++++++--------- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a38f5a62f..0494af0b6 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.24(2023-12-09) +# 5.8.24(2023-12-11) ### 🐣新特性 * 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) @@ -10,6 +10,7 @@ * 【db 】 增加识别OpenGauss的驱动类(issue#I8K6C0@Gitee) * 【core 】 修复CharSequenceUtil注释和引用,避免循环引用 * 【extra 】 SpringUtil增加getProperty重载(pr#1122@Gitee) +* 【core 】 FileTypeUtil增加null判断(issue#3419@Github) ### 🐞Bug修复 * 【core 】 修复LocalDateTime#parseDate未判断空问题问题(issue#I8FN7F@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/io/FileTypeUtil.java b/hutool-core/src/main/java/cn/hutool/core/io/FileTypeUtil.java index 99bf5a9c9..cc2a83883 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/FileTypeUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/FileTypeUtil.java @@ -53,7 +53,7 @@ public class FileTypeUtil { * @return 文件类型,未找到为{@code null} */ public static String getType(String fileStreamHexHead) { - if(MapUtil.isNotEmpty(FILE_TYPE_MAP)){ + if (MapUtil.isNotEmpty(FILE_TYPE_MAP)) { for (final Entry fileTypeEntry : FILE_TYPE_MAP.entrySet()) { if (StrUtil.startWithIgnoreCase(fileStreamHexHead, fileTypeEntry.getKey())) { return fileTypeEntry.getValue(); @@ -67,39 +67,44 @@ public class FileTypeUtil { /** * 根据文件流的头部信息获得文件类型 * - * @param in 文件流 + * @param in 文件流 * @param fileHeadSize 自定义读取文件头部的大小 * @return 文件类型,未找到为{@code null} */ - public static String getType(InputStream in,int fileHeadSize) throws IORuntimeException { - return getType((IoUtil.readHex(in, fileHeadSize,false))); + public static String getType(InputStream in, int fileHeadSize) throws IORuntimeException { + return getType((IoUtil.readHex(in, fileHeadSize, false))); } /** * 根据文件流的头部信息获得文件类型
* 注意此方法会读取头部一些bytes,造成此流接下来读取时缺少部分bytes
* 因此如果想复用此流,流需支持{@link InputStream#reset()}方法。 - * @param in {@link InputStream} + * + * @param in {@link InputStream} * @param isExact 是否精确匹配,如果为false,使用前64个bytes匹配,如果为true,使用前8192bytes匹配 - * @return 类型,文件的扩展名,未找到为{@code null} - * @throws IORuntimeException 读取流引起的异常 + * @return 类型,文件的扩展名,提供的in为{@code null}或未找到为{@code null} + * @throws IORuntimeException 读取流引起的异常 */ - public static String getType(InputStream in,boolean isExact) throws IORuntimeException { + public static String getType(InputStream in, boolean isExact) throws IORuntimeException { + if (null == in) { + return null; + } return isExact - ?getType(IoUtil.readHex8192Upper(in)) - :getType(IoUtil.readHex64Upper(in)); + ? getType(IoUtil.readHex8192Upper(in)) + : getType(IoUtil.readHex64Upper(in)); } /** * 根据文件流的头部信息获得文件类型
* 注意此方法会读取头部64个bytes,造成此流接下来读取时缺少部分bytes
* 因此如果想复用此流,流需支持{@link InputStream#reset()}方法。 + * * @param in {@link InputStream} * @return 类型,文件的扩展名,未找到为{@code null} - * @throws IORuntimeException 读取流引起的异常 + * @throws IORuntimeException 读取流引起的异常 */ - public static String getType(InputStream in) throws IORuntimeException { - return getType(in,false); + public static String getType(InputStream in) throws IORuntimeException { + return getType(in, false); } /** @@ -116,10 +121,10 @@ public class FileTypeUtil { * @param in {@link InputStream} * @param filename 文件名 * @return 类型,文件的扩展名,未找到为{@code null} - * @throws IORuntimeException 读取流引起的异常 + * @throws IORuntimeException 读取流引起的异常 */ - public static String getType(InputStream in, String filename) throws IORuntimeException { - return getType(in,filename,false); + public static String getType(InputStream in, String filename) throws IORuntimeException { + return getType(in, filename, false); } /** @@ -132,14 +137,15 @@ public class FileTypeUtil { * 2、xls、doc、msi头信息无法区分,按照扩展名区分 * 3、zip可能为docx、xlsx、pptx、jar、war、ofd头信息无法区分,按照扩展名区分 * + * * @param in {@link InputStream} * @param filename 文件名 - * @param isExact 是否精确匹配,如果为false,使用前64个bytes匹配,如果为true,使用前8192bytes匹配 + * @param isExact 是否精确匹配,如果为false,使用前64个bytes匹配,如果为true,使用前8192bytes匹配 * @return 类型,文件的扩展名,未找到为{@code null} - * @throws IORuntimeException 读取流引起的异常 + * @throws IORuntimeException 读取流引起的异常 */ - public static String getType(InputStream in, String filename,boolean isExact) throws IORuntimeException { - String typeName = getType(in,isExact); + public static String getType(InputStream in, String filename, boolean isExact) throws IORuntimeException { + String typeName = getType(in, isExact); if (null == typeName) { // 未成功识别类型,扩展名辅助识别 typeName = FileUtil.extName(filename); @@ -190,19 +196,19 @@ public class FileTypeUtil { * 3、zip可能为jar、war头信息无法区分,按照扩展名区分 * * - * @param file 文件 {@link File} + * @param file 文件 {@link File} * @param isExact 是否精确匹配,如果为false,使用前64个bytes匹配,如果为true,使用前8192bytes匹配 * @return 类型,文件的扩展名,未找到为{@code null} - * @throws IORuntimeException 读取文件引起的异常 + * @throws IORuntimeException 读取文件引起的异常 */ - public static String getType(File file,boolean isExact) throws IORuntimeException { - if(false == FileUtil.isFile(file)){ + public static String getType(File file, boolean isExact) throws IORuntimeException { + if (false == FileUtil.isFile(file)) { throw new IllegalArgumentException("Not a regular file!"); } FileInputStream in = null; try { in = IoUtil.toStream(file); - return getType(in, file.getName(),isExact); + return getType(in, file.getName(), isExact); } finally { IoUtil.close(in); } @@ -219,22 +225,22 @@ public class FileTypeUtil { * * @param file 文件 {@link File} * @return 类型,文件的扩展名,未找到为{@code null} - * @throws IORuntimeException 读取文件引起的异常 + * @throws IORuntimeException 读取文件引起的异常 */ - public static String getType(File file) throws IORuntimeException { - return getType(file,false); + public static String getType(File file) throws IORuntimeException { + return getType(file, false); } /** * 通过路径获得文件类型 * - * @param path 路径,绝对路径或相对ClassPath的路径 + * @param path 路径,绝对路径或相对ClassPath的路径 * @param isExact 是否精确匹配,如果为false,使用前64个bytes匹配,如果为true,使用前8192bytes匹配 * @return 类型 - * @throws IORuntimeException 读取文件引起的异常 + * @throws IORuntimeException 读取文件引起的异常 */ - public static String getTypeByPath(String path,boolean isExact) throws IORuntimeException { - return getType(FileUtil.file(path),isExact); + public static String getTypeByPath(String path, boolean isExact) throws IORuntimeException { + return getType(FileUtil.file(path), isExact); } /** @@ -242,10 +248,10 @@ public class FileTypeUtil { * * @param path 路径,绝对路径或相对ClassPath的路径 * @return 类型 - * @throws IORuntimeException 读取文件引起的异常 + * @throws IORuntimeException 读取文件引起的异常 */ - public static String getTypeByPath(String path) throws IORuntimeException { - return getTypeByPath(path,false); + public static String getTypeByPath(String path) throws IORuntimeException { + return getTypeByPath(path, false); } From 32f2d0bd55defecb869fbf64d940bcc05642accc Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 12 Dec 2023 04:29:20 +0800 Subject: [PATCH 29/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8DStrSplitter.splitByRege?= =?UTF-8?q?x=E4=BD=BF=E7=94=A8=E7=A9=BA=E5=8F=82=E6=95=B0=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E7=9A=84OOM=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 +- .../core/text/finder/PatternFinder.java | 11 ++++- .../core/text/split/StrSplitterTest.java | 42 +++++++++++++------ 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0494af0b6..eb03c53cf 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.24(2023-12-11) +# 5.8.24(2023-12-12) ### 🐣新特性 * 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) @@ -18,6 +18,7 @@ * 【extra 】 修复Archiver 最后一个 Entry 为空文件夹时未关闭 Entry问题(pr#1123@Gitee) * 【core 】 修复ImgUtil.convert png转jpg在jdk9+中失败问题(issue#I8L8UA@Gitee) * 【cache 】 修复StampedCache的get方法非原子问题(issue#I8MEIX@Gitee) +* 【core 】 修复StrSplitter.splitByRegex使用空参数导致的OOM问题(issue#3421@Github) ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) diff --git a/hutool-core/src/main/java/cn/hutool/core/text/finder/PatternFinder.java b/hutool-core/src/main/java/cn/hutool/core/text/finder/PatternFinder.java index c258daed0..397993086 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/finder/PatternFinder.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/finder/PatternFinder.java @@ -49,9 +49,16 @@ public class PatternFinder extends TextFinder { @Override public int start(int from) { if (matcher.find(from)) { + final int end = matcher.end(); // 只有匹配到的字符串结尾在limit范围内,才算找到 - if(matcher.end() <= getValidEndIndex()){ - return matcher.start(); + if(end <= getValidEndIndex()){ + final int start = matcher.start(); + if(start == end){ + // issue#3421,如果匹配空串,按照未匹配对待,避免死循环 + return INDEX_NOT_FOUND; + } + + return start; } } return INDEX_NOT_FOUND; diff --git a/hutool-core/src/test/java/cn/hutool/core/text/split/StrSplitterTest.java b/hutool-core/src/test/java/cn/hutool/core/text/split/StrSplitterTest.java index 16f812f69..8498bf479 100644 --- a/hutool-core/src/test/java/cn/hutool/core/text/split/StrSplitterTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/text/split/StrSplitterTest.java @@ -1,5 +1,6 @@ package cn.hutool.core.text.split; +import cn.hutool.core.collection.ListUtil; import cn.hutool.core.text.StrSplitter; import org.junit.Assert; import org.junit.Test; @@ -15,8 +16,8 @@ public class StrSplitterTest { @Test public void splitByCharTest(){ - String str1 = "a, ,efedsfs, ddf"; - List split = StrSplitter.split(str1, ',', 0, true, true); + final String str1 = "a, ,efedsfs, ddf"; + final List split = StrSplitter.split(str1, ',', 0, true, true); Assert.assertEquals("ddf", split.get(2)); Assert.assertEquals(3, split.size()); @@ -24,32 +25,32 @@ public class StrSplitterTest { @Test public void splitByStrTest(){ - String str1 = "aabbccaaddaaee"; - List split = StrSplitter.split(str1, "aa", 0, true, true); + final String str1 = "aabbccaaddaaee"; + final List split = StrSplitter.split(str1, "aa", 0, true, true); Assert.assertEquals("ee", split.get(2)); Assert.assertEquals(3, split.size()); } @Test public void splitByBlankTest(){ - String str1 = "aa bbccaa ddaaee"; - List split = StrSplitter.split(str1, 0); + final String str1 = "aa bbccaa ddaaee"; + final List split = StrSplitter.split(str1, 0); Assert.assertEquals("ddaaee", split.get(2)); Assert.assertEquals(3, split.size()); } @Test public void splitPathTest(){ - String str1 = "/use/local/bin"; - List split = StrSplitter.splitPath(str1, 0); + final String str1 = "/use/local/bin"; + final List split = StrSplitter.splitPath(str1, 0); Assert.assertEquals("bin", split.get(2)); Assert.assertEquals(3, split.size()); } @Test public void splitMappingTest() { - String str = "1.2."; - List split = StrSplitter.split(str, '.', 0, true, true, Long::parseLong); + final String str = "1.2."; + final List split = StrSplitter.split(str, '.', 0, true, true, Long::parseLong); Assert.assertEquals(2, split.size()); Assert.assertEquals(Long.valueOf(1L), split.get(0)); Assert.assertEquals(Long.valueOf(2L), split.get(1)); @@ -57,7 +58,7 @@ public class StrSplitterTest { @Test public void splitEmptyTest(){ - String str = ""; + final String str = ""; final String[] split = str.split(","); final String[] strings = StrSplitter.splitToArray(str, ",", -1, false, false); Assert.assertNotNull(strings); @@ -66,7 +67,7 @@ public class StrSplitterTest { @Test public void splitNullTest(){ - String str = null; + final String str = null; final String[] strings = StrSplitter.splitToArray(str, ",", -1, false, false); Assert.assertNotNull(strings); Assert.assertEquals(0, strings.length); @@ -77,7 +78,7 @@ public class StrSplitterTest { */ @Test public void splitByRegexTest(){ - String text = "01 821 34567890182345617821"; + final String text = "01 821 34567890182345617821"; List strings = StrSplitter.splitByRegex(text, "21", 0, false, true); Assert.assertEquals(2, strings.size()); Assert.assertEquals("01 8", strings.get(0)); @@ -89,4 +90,19 @@ public class StrSplitterTest { Assert.assertEquals(" 345678901823456178", strings.get(1)); Assert.assertEquals("", strings.get(2)); } + + @Test + public void issue3421Test() { + List strings = StrSplitter.splitByRegex("", "", 0, false, false); + Assert.assertEquals(ListUtil.of(""), strings); + + strings = StrSplitter.splitByRegex("aaa", "", 0, false, false); + Assert.assertEquals(ListUtil.of("aaa"), strings); + + strings = StrSplitter.splitByRegex("", "aaa", 0, false, false); + Assert.assertEquals(ListUtil.of(""), strings); + + strings = StrSplitter.splitByRegex("", "", 0, false, true); + Assert.assertEquals(ListUtil.of(), strings); + } } From c45de2b7f4cc854fed62ed7024a3df858ff2afd3 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 12 Dec 2023 13:34:54 +0800 Subject: [PATCH 30/45] =?UTF-8?q?DateUtil.parse=E6=94=AF=E6=8C=81=E6=AF=AB?= =?UTF-8?q?=E7=A7=92=E6=97=B6=E9=97=B4=E6=88=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../src/main/java/cn/hutool/core/date/DateUtil.java | 3 +++ .../cn/hutool/core/annotation/TestIssueI8CLBJ.java | 2 +- .../test/java/cn/hutool/core/date/DateUtilTest.java | 11 +++++++++-- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb03c53cf..6925b203c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * 【core 】 修复CharSequenceUtil注释和引用,避免循环引用 * 【extra 】 SpringUtil增加getProperty重载(pr#1122@Gitee) * 【core 】 FileTypeUtil增加null判断(issue#3419@Github) +* 【core 】 DateUtil.parse支持毫秒时间戳(issue#I8NMP7@Gitee) ### 🐞Bug修复 * 【core 】 修复LocalDateTime#parseDate未判断空问题问题(issue#I8FN7F@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java index 864a14437..91badecb4 100755 --- a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java @@ -981,6 +981,9 @@ public class DateUtil extends CalendarUtil { return parse(dateStr, DatePattern.PURE_DATE_FORMAT); } else if (length == DatePattern.PURE_TIME_PATTERN.length()) { return parse(dateStr, DatePattern.PURE_TIME_FORMAT); + }else if(length == 13){ + // 时间戳 + return date(NumberUtil.parseLong(dateStr)); } } else if (ReUtil.isMatch(PatternPool.TIME, dateStr)) { // HH:mm:ss 或者 HH:mm 时间格式匹配单独解析 diff --git a/hutool-core/src/test/java/cn/hutool/core/annotation/TestIssueI8CLBJ.java b/hutool-core/src/test/java/cn/hutool/core/annotation/TestIssueI8CLBJ.java index 04c2a9267..fd80af15d 100644 --- a/hutool-core/src/test/java/cn/hutool/core/annotation/TestIssueI8CLBJ.java +++ b/hutool-core/src/test/java/cn/hutool/core/annotation/TestIssueI8CLBJ.java @@ -30,7 +30,7 @@ public class TestIssueI8CLBJ { Thread thread = new Thread(() -> { try { String valueFieldName = annotation.valueFieldName(); - System.out.println("valueFieldName:" + valueFieldName); + //Console.log("valueFieldName:" + valueFieldName); } catch (Exception e) { e.printStackTrace(); } diff --git a/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java index 776615120..02c72ae41 100755 --- a/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java @@ -1126,8 +1126,8 @@ public class DateUtilTest { @Test public void isLastDayTest() { - DateTime dateTime = DateUtil.parse("2022-09-30"); - int dayOfMonth = DateUtil.getLastDayOfMonth(dateTime); + final DateTime dateTime = DateUtil.parse("2022-09-30"); + final int dayOfMonth = DateUtil.getLastDayOfMonth(dateTime); Assert.assertEquals(dayOfMonth, dateTime.dayOfMonth()); Assert.assertTrue("not is last day of this month !!", DateUtil.isLastDayOfMonth(dateTime)); } @@ -1167,4 +1167,11 @@ public class DateUtilTest { Assert.assertNotNull(parse); Assert.assertEquals("2019-10-22 09:56:03", parse.toString()); } + + @Test + public void issueI8NMP7Test() { + final String str = "1702262524444"; + final DateTime parse = DateUtil.parse(str); + Assert.assertEquals("2023-12-11 10:42:04", Objects.requireNonNull(parse).toString()); + } } From b8f3529238f565cb2a40b6727d9b4769a2bf5e99 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 12 Dec 2023 22:14:54 +0800 Subject: [PATCH 31/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B5=8C=E5=A5=97SQL?= =?UTF-8?q?=E4=B8=ADorder=20by=E5=AD=90=E5=8F=A5=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E6=88=AA=E6=96=AD=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../src/main/java/cn/hutool/db/DialectRunner.java | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6925b203c..449d27dee 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ * 【core 】 修复ImgUtil.convert png转jpg在jdk9+中失败问题(issue#I8L8UA@Gitee) * 【cache 】 修复StampedCache的get方法非原子问题(issue#I8MEIX@Gitee) * 【core 】 修复StrSplitter.splitByRegex使用空参数导致的OOM问题(issue#3421@Github) +* 【db 】 修复嵌套SQL中order by子句错误截断问题(issue#I89RXV@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) diff --git a/hutool-db/src/main/java/cn/hutool/db/DialectRunner.java b/hutool-db/src/main/java/cn/hutool/db/DialectRunner.java index a891f3ba8..c0c7906e6 100644 --- a/hutool-db/src/main/java/cn/hutool/db/DialectRunner.java +++ b/hutool-db/src/main/java/cn/hutool/db/DialectRunner.java @@ -1,8 +1,11 @@ package cn.hutool.db; import cn.hutool.core.lang.Assert; +import cn.hutool.core.lang.PatternPool; +import cn.hutool.core.lang.RegexPool; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.db.dialect.Dialect; import cn.hutool.db.dialect.DialectFactory; @@ -18,6 +21,8 @@ import java.io.Serializable; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * 提供基于方言的原始增删改查执行封装 @@ -273,11 +278,14 @@ public class DialectRunner implements Serializable { checkConn(conn); String selectSql = sqlBuilder.build(); + // 去除order by 子句 - final int orderByIndex = StrUtil.lastIndexOfIgnoreCase(selectSql, " order by"); - if (orderByIndex > 0) { - selectSql = StrUtil.subPre(selectSql, orderByIndex); + final Pattern pattern = PatternPool.get("(.*?)[\\s]order[\\s]by[\\s][^\\s]+\\s(asc|desc)?", Pattern.CASE_INSENSITIVE); + final Matcher matcher = pattern.matcher(selectSql); + if (matcher.matches()) { + selectSql = matcher.group(1); } + return SqlExecutor.queryAndClosePs(dialect.psForCount(conn, SqlBuilder.of(selectSql).addParams(sqlBuilder.getParamValueArray())), new NumberHandler()).longValue(); From d46f00d2bead8ec4fbdc6307a70309b96786e46f Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 12 Dec 2023 23:04:27 +0800 Subject: [PATCH 32/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dgraalvm=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=90=8E=EF=BC=8C=E6=9C=AA=E8=AF=BB=E5=8F=96Content-L?= =?UTF-8?q?ength=E5=8F=AF=E8=83=BD=E5=AF=BC=E8=87=B4=E7=9A=84=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E6=97=B6=E9=97=B4=E8=BF=87=E9=95=BF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../hutool/http/server/HttpServerRequest.java | 20 ++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 449d27dee..dadd50756 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ * 【cache 】 修复StampedCache的get方法非原子问题(issue#I8MEIX@Gitee) * 【core 】 修复StrSplitter.splitByRegex使用空参数导致的OOM问题(issue#3421@Github) * 【db 】 修复嵌套SQL中order by子句错误截断问题(issue#I89RXV@Gitee) +* 【http 】 修复graalvm编译后,未读取Content-Length可能导致的读取时间过长问题(issue#I6Q30X@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) diff --git a/hutool-http/src/main/java/cn/hutool/http/server/HttpServerRequest.java b/hutool-http/src/main/java/cn/hutool/http/server/HttpServerRequest.java index 05555f58a..0872dadc6 100644 --- a/hutool-http/src/main/java/cn/hutool/http/server/HttpServerRequest.java +++ b/hutool-http/src/main/java/cn/hutool/http/server/HttpServerRequest.java @@ -3,6 +3,7 @@ package cn.hutool.http.server; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IoUtil; +import cn.hutool.core.io.LimitedInputStream; import cn.hutool.core.map.CaseInsensitiveMap; import cn.hutool.core.map.multi.ListValueMap; import cn.hutool.core.net.NetUtil; @@ -294,7 +295,24 @@ public class HttpServerRequest extends HttpServerBase { * @return 流 */ public InputStream getBodyStream() { - return this.httpExchange.getRequestBody(); + InputStream bodyStream = this.httpExchange.getRequestBody(); + + //issue#I6Q30X,读取body长度,避免读取结束后无法正常结束问题 + final String contentLengthStr = getHeader(Header.CONTENT_LENGTH); + long contentLength = 0; + if(StrUtil.isNotBlank(contentLengthStr)){ + try{ + contentLength = Long.parseLong(contentLengthStr); + } catch (final NumberFormatException ignore){ + // ignore + } + } + + if(contentLength > 0){ + bodyStream = new LimitedInputStream(bodyStream, contentLength); + } + + return bodyStream; } /** From a9682509256d834c4a07898cd6debd877fa0d3f0 Mon Sep 17 00:00:00 2001 From: micuncang Date: Wed, 13 Dec 2023 15:36:49 +0800 Subject: [PATCH 33/45] fix: https://github.com/dromara/hutool/issues/3426 --- .../engine/ikanalyzer/IKAnalyzerEngine.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/hutool-extra/src/main/java/cn/hutool/extra/tokenizer/engine/ikanalyzer/IKAnalyzerEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/tokenizer/engine/ikanalyzer/IKAnalyzerEngine.java index 6cb8c2e7a..5a7dc83c0 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/tokenizer/engine/ikanalyzer/IKAnalyzerEngine.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/tokenizer/engine/ikanalyzer/IKAnalyzerEngine.java @@ -1,17 +1,17 @@ package cn.hutool.extra.tokenizer.engine.ikanalyzer; -import org.wltea.analyzer.core.IKSegmenter; - +import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; -import cn.hutool.extra.tokenizer.TokenizerEngine; import cn.hutool.extra.tokenizer.Result; +import cn.hutool.extra.tokenizer.TokenizerEngine; +import org.wltea.analyzer.cfg.Configuration; +import org.wltea.analyzer.core.IKSegmenter; /** * IKAnalyzer分词引擎实现
* 项目地址:https://github.com/yozhao/IKAnalyzer - * - * @author looly * + * @author looly */ public class IKAnalyzerEngine implements TokenizerEngine { @@ -19,7 +19,6 @@ public class IKAnalyzerEngine implements TokenizerEngine { /** * 构造 - * */ public IKAnalyzerEngine() { this(new IKSegmenter(null, true)); @@ -27,7 +26,7 @@ public class IKAnalyzerEngine implements TokenizerEngine { /** * 构造 - * + * * @param seg {@link IKSegmenter} */ public IKAnalyzerEngine(IKSegmenter seg) { @@ -36,7 +35,8 @@ public class IKAnalyzerEngine implements TokenizerEngine { @Override public Result parse(CharSequence text) { - this.seg.reset(StrUtil.getReader(text)); - return new IKAnalyzerResult(this.seg); + IKSegmenter copySeg = new IKSegmenter(null, (Configuration) ReflectUtil.getFieldValue(this.seg, "cfg")); + copySeg.reset(StrUtil.getReader(text)); + return new IKAnalyzerResult(copySeg); } } From da1d89ff29c9673120b093ebb95b42c0f181d231 Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 13 Dec 2023 19:31:56 +0800 Subject: [PATCH 34/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8DJavaSourceCompiler.addS?= =?UTF-8?q?ource=E7=9B=AE=E5=BD=95=E5=A4=84=E7=90=86=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- .../main/java/cn/hutool/core/compiler/JavaSourceCompiler.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dadd50756..72efbb165 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.24(2023-12-12) +# 5.8.24(2023-12-13) ### 🐣新特性 * 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) @@ -22,6 +22,7 @@ * 【core 】 修复StrSplitter.splitByRegex使用空参数导致的OOM问题(issue#3421@Github) * 【db 】 修复嵌套SQL中order by子句错误截断问题(issue#I89RXV@Gitee) * 【http 】 修复graalvm编译后,未读取Content-Length可能导致的读取时间过长问题(issue#I6Q30X@Gitee) +* 【core 】 修复JavaSourceCompiler.addSource目录处理错误问题(issue#3425@Github) ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) diff --git a/hutool-core/src/main/java/cn/hutool/core/compiler/JavaSourceCompiler.java b/hutool-core/src/main/java/cn/hutool/core/compiler/JavaSourceCompiler.java index b14907160..5a9f84b53 100644 --- a/hutool-core/src/main/java/cn/hutool/core/compiler/JavaSourceCompiler.java +++ b/hutool-core/src/main/java/cn/hutool/core/compiler/JavaSourceCompiler.java @@ -244,7 +244,7 @@ public class JavaSourceCompiler { for (Resource resource : this.sourceList) { if (resource instanceof FileResource) { final File file = ((FileResource) resource).getFile(); - FileUtil.walkFiles(file, (subFile) -> list.addAll(JavaFileObjectUtil.getJavaFileObjects(file))); + FileUtil.walkFiles(file, (subFile) -> list.addAll(JavaFileObjectUtil.getJavaFileObjects(subFile))); } else { list.add(new JavaSourceFileObject(resource.getName(), resource.getStream())); } From 9bb370c4768cb9d3ebf5347044f34e6e9105b071 Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 14 Dec 2023 17:44:57 +0800 Subject: [PATCH 35/45] =?UTF-8?q?=E4=BC=98=E5=8C=96TokenizerEngine?= =?UTF-8?q?=E4=BD=BF=E7=94=A8IK=E5=88=86=E8=AF=8D=E5=99=A8=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=B9=B6=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- .../tokenizer/engine/ikanalyzer/IKAnalyzerEngine.java | 10 +++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72efbb165..daf09d5d9 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.24(2023-12-13) +# 5.8.24(2023-12-14) ### 🐣新特性 * 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) @@ -12,6 +12,7 @@ * 【extra 】 SpringUtil增加getProperty重载(pr#1122@Gitee) * 【core 】 FileTypeUtil增加null判断(issue#3419@Github) * 【core 】 DateUtil.parse支持毫秒时间戳(issue#I8NMP7@Gitee) +* 【extra 】 优化TokenizerEngine使用IK分词器支持并发(pr#3427@Github) ### 🐞Bug修复 * 【core 】 修复LocalDateTime#parseDate未判断空问题问题(issue#I8FN7F@Gitee) diff --git a/hutool-extra/src/main/java/cn/hutool/extra/tokenizer/engine/ikanalyzer/IKAnalyzerEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/tokenizer/engine/ikanalyzer/IKAnalyzerEngine.java index 5a7dc83c0..a030268fe 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/tokenizer/engine/ikanalyzer/IKAnalyzerEngine.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/tokenizer/engine/ikanalyzer/IKAnalyzerEngine.java @@ -1,10 +1,8 @@ package cn.hutool.extra.tokenizer.engine.ikanalyzer; -import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.tokenizer.Result; import cn.hutool.extra.tokenizer.TokenizerEngine; -import org.wltea.analyzer.cfg.Configuration; import org.wltea.analyzer.core.IKSegmenter; /** @@ -15,27 +13,25 @@ import org.wltea.analyzer.core.IKSegmenter; */ public class IKAnalyzerEngine implements TokenizerEngine { - private final IKSegmenter seg; - /** * 构造 */ public IKAnalyzerEngine() { - this(new IKSegmenter(null, true)); } /** * 构造 * * @param seg {@link IKSegmenter} + * @deprecated 并发问题,导致无法共用IKSegmenter,因此废弃 */ + @Deprecated public IKAnalyzerEngine(IKSegmenter seg) { - this.seg = seg; } @Override public Result parse(CharSequence text) { - IKSegmenter copySeg = new IKSegmenter(null, (Configuration) ReflectUtil.getFieldValue(this.seg, "cfg")); + final IKSegmenter copySeg = new IKSegmenter(null, true); copySeg.reset(StrUtil.getReader(text)); return new IKAnalyzerResult(copySeg); } From 3fc8da755f898a622b02b482f4ed8225b2f65859 Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 14 Dec 2023 21:49:23 +0800 Subject: [PATCH 36/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E6=88=B3=E8=BD=ACBean=E6=97=B6=E5=BC=82=E5=B8=B8=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../java/cn/hutool/json/IssueI8NMP7Test.java | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 hutool-json/src/test/java/cn/hutool/json/IssueI8NMP7Test.java diff --git a/CHANGELOG.md b/CHANGELOG.md index daf09d5d9..5557dcf46 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ * 【db 】 修复嵌套SQL中order by子句错误截断问题(issue#I89RXV@Gitee) * 【http 】 修复graalvm编译后,未读取Content-Length可能导致的读取时间过长问题(issue#I6Q30X@Gitee) * 【core 】 修复JavaSourceCompiler.addSource目录处理错误问题(issue#3425@Github) +* 【core 】 修复时间戳转Bean时异常问题(issue#I8NMP7@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) diff --git a/hutool-json/src/test/java/cn/hutool/json/IssueI8NMP7Test.java b/hutool-json/src/test/java/cn/hutool/json/IssueI8NMP7Test.java new file mode 100644 index 000000000..6bd9db836 --- /dev/null +++ b/hutool-json/src/test/java/cn/hutool/json/IssueI8NMP7Test.java @@ -0,0 +1,23 @@ +package cn.hutool.json; + +import lombok.Data; +import lombok.ToString; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Date; + +public class IssueI8NMP7Test { + @Test + public void toBeanTest() { + final String jsonString = "{\"enableTime\":\"1702262524444\"}"; + final DemoModel bean = JSONUtil.toBean(jsonString, JSONConfig.create(), DemoModel.class); + Assert.assertNotNull(bean.getEnableTime()); + } + + @Data + @ToString + static class DemoModel{ + private Date enableTime; + } +} From 168be856c06d2b8cd46897c82cce6033a42c5bbe Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 15 Dec 2023 22:00:10 +0800 Subject: [PATCH 37/45] =?UTF-8?q?Opt.ofEmptyAble=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=9B=B4=E5=A4=9A=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- hutool-core/src/main/java/cn/hutool/core/lang/Opt.java | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5557dcf46..9354e2c0e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.24(2023-12-14) +# 5.8.24(2023-12-15) ### 🐣新特性 * 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) @@ -13,6 +13,7 @@ * 【core 】 FileTypeUtil增加null判断(issue#3419@Github) * 【core 】 DateUtil.parse支持毫秒时间戳(issue#I8NMP7@Gitee) * 【extra 】 优化TokenizerEngine使用IK分词器支持并发(pr#3427@Github) +* 【core 】 Opt.ofEmptyAble支持更多类型(issue#I8OOSY@Gitee) ### 🐞Bug修复 * 【core 】 修复LocalDateTime#parseDate未判断空问题问题(issue#I8FN7F@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Opt.java b/hutool-core/src/main/java/cn/hutool/core/lang/Opt.java index 4dd92e76a..562bd8fc6 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/Opt.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/Opt.java @@ -1,8 +1,8 @@ package cn.hutool.core.lang; -import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.func.Func0; import cn.hutool.core.lang.func.VoidFunc0; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import java.util.Collection; @@ -80,12 +80,12 @@ public class Opt { * * @param 包裹里元素的类型 * @param 集合值类型 - * @param value 传入需要包裹的元素 + * @param value 传入需要包裹的元素,支持CharSequence、Map、Iterable、Iterator、Array类型 * @return 一个包裹里元素可能为空的 {@code Opt} * @since 5.7.17 */ public static > Opt ofEmptyAble(R value) { - return CollectionUtil.isEmpty(value) ? empty() : new Opt<>(value); + return ObjectUtil.isEmpty(value) ? empty() : new Opt<>(value); } /** From bc5ec5c5d21f687b3ac4dcfe5bae77c53e3d9c4b Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 19 Dec 2023 22:22:20 +0800 Subject: [PATCH 38/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8DPostgreSQL=E4=BD=BF?= =?UTF-8?q?=E7=94=A8upsert=E5=AD=97=E6=AE=B5=E5=A4=A7=E5=B0=8F=E5=86=99?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- .../java/cn/hutool/db/dialect/impl/PostgresqlDialect.java | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9354e2c0e..d59af9457 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.24(2023-12-15) +# 5.8.24(2023-12-19) ### 🐣新特性 * 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) @@ -26,6 +26,7 @@ * 【http 】 修复graalvm编译后,未读取Content-Length可能导致的读取时间过长问题(issue#I6Q30X@Gitee) * 【core 】 修复JavaSourceCompiler.addSource目录处理错误问题(issue#3425@Github) * 【core 】 修复时间戳转Bean时异常问题(issue#I8NMP7@Gitee) +* 【core 】 修复PostgreSQL使用upsert字段大小写问题问题(issue#I8PB4X@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) diff --git a/hutool-db/src/main/java/cn/hutool/db/dialect/impl/PostgresqlDialect.java b/hutool-db/src/main/java/cn/hutool/db/dialect/impl/PostgresqlDialect.java index 0a5e0fc7d..a7bd189e5 100644 --- a/hutool-db/src/main/java/cn/hutool/db/dialect/impl/PostgresqlDialect.java +++ b/hutool-db/src/main/java/cn/hutool/db/dialect/impl/PostgresqlDialect.java @@ -22,6 +22,9 @@ import java.sql.SQLException; public class PostgresqlDialect extends AnsiSqlDialect{ private static final long serialVersionUID = 3889210427543389642L; + /** + * 构造 + */ public PostgresqlDialect() { wrapper = new Wrapper('"'); } @@ -53,7 +56,7 @@ public class PostgresqlDialect extends AnsiSqlDialect{ final String wrapedField = (null != wrapper) ? wrapper.wrap(field) : field; fieldsPart.append(wrapedField); - updateHolder.append(wrapedField).append("=EXCLUDED.").append(field); + updateHolder.append(wrapedField).append("=EXCLUDED.").append(wrapedField); placeHolder.append("?"); builder.addParams(value); } From 9e853db9ee1ba9f36b8a46fcb999c00280b5563d Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 20 Dec 2023 12:58:03 +0800 Subject: [PATCH 39/45] add test --- .../java/cn/hutool/json/IssueI8PC9FTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 hutool-json/src/test/java/cn/hutool/json/IssueI8PC9FTest.java diff --git a/hutool-json/src/test/java/cn/hutool/json/IssueI8PC9FTest.java b/hutool-json/src/test/java/cn/hutool/json/IssueI8PC9FTest.java new file mode 100644 index 000000000..393fe3371 --- /dev/null +++ b/hutool-json/src/test/java/cn/hutool/json/IssueI8PC9FTest.java @@ -0,0 +1,24 @@ +package cn.hutool.json; + +import lombok.Data; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Map; + +public class IssueI8PC9FTest { + + @Test + public void toBeanIgnoreErrorTest() { + final String testJson = "{\"testMap\":\"\"}"; + final TestBean test = JSONUtil.parseObj(testJson, JSONConfig.create().setIgnoreError(true)) + .toBean(TestBean.class); + Assert.assertNotNull(test); + Assert.assertNull(test.getTestMap()); + } + + @Data + static class TestBean{ + private Map testMap; + } +} From cca184257a3d402ec223603f49f0b831fb38305f Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 20 Dec 2023 20:53:32 +0800 Subject: [PATCH 40/45] =?UTF-8?q?HTMLFilter=E4=BF=9D=E7=95=99p=E6=A0=87?= =?UTF-8?q?=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- .../main/java/cn/hutool/http/HTMLFilter.java | 1 + .../java/cn/hutool/http/HTMLFilterTest.java | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 hutool-http/src/test/java/cn/hutool/http/HTMLFilterTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index d59af9457..3e255206f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.24(2023-12-19) +# 5.8.24(2023-12-20) ### 🐣新特性 * 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) @@ -14,6 +14,7 @@ * 【core 】 DateUtil.parse支持毫秒时间戳(issue#I8NMP7@Gitee) * 【extra 】 优化TokenizerEngine使用IK分词器支持并发(pr#3427@Github) * 【core 】 Opt.ofEmptyAble支持更多类型(issue#I8OOSY@Gitee) +* 【http 】 HTMLFilter保留p标签(issue#3433@Gitee) ### 🐞Bug修复 * 【core 】 修复LocalDateTime#parseDate未判断空问题问题(issue#I8FN7F@Gitee) diff --git a/hutool-http/src/main/java/cn/hutool/http/HTMLFilter.java b/hutool-http/src/main/java/cn/hutool/http/HTMLFilter.java index ffed78541..3bfaee3a5 100644 --- a/hutool-http/src/main/java/cn/hutool/http/HTMLFilter.java +++ b/hutool-http/src/main/java/cn/hutool/http/HTMLFilter.java @@ -137,6 +137,7 @@ public final class HTMLFilter { vAllowed.put("strong", no_atts); vAllowed.put("i", no_atts); vAllowed.put("em", no_atts); + vAllowed.put("p", no_atts); vSelfClosingTags = new String[]{"img"}; vNeedClosingTags = new String[]{"a", "b", "strong", "i", "em"}; diff --git a/hutool-http/src/test/java/cn/hutool/http/HTMLFilterTest.java b/hutool-http/src/test/java/cn/hutool/http/HTMLFilterTest.java new file mode 100644 index 000000000..03045a9a7 --- /dev/null +++ b/hutool-http/src/test/java/cn/hutool/http/HTMLFilterTest.java @@ -0,0 +1,19 @@ +package cn.hutool.http; + +import org.junit.Assert; +import org.junit.Test; + +public class HTMLFilterTest { + @Test + public void issue3433Test() { + String p1 = "

a

"; + String p2 = "

a

"; + + final HTMLFilter htmlFilter = new HTMLFilter(); + String filter = htmlFilter.filter(p1); + Assert.assertEquals("

a

", filter); + + filter = htmlFilter.filter(p2); + Assert.assertEquals("

a

", filter); + } +} From 99ec3bbeb4a5cf0fa49269cfe1b64c7f7d73bf17 Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 20 Dec 2023 21:10:29 +0800 Subject: [PATCH 41/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8DTinyPinyinEngine?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E7=9A=84=E7=A9=BA=E6=8C=87=E9=92=88=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../extra/pinyin/engine/tinypinyin/TinyPinyinEngine.java | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e255206f..2d3039357 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ * 【core 】 修复JavaSourceCompiler.addSource目录处理错误问题(issue#3425@Github) * 【core 】 修复时间戳转Bean时异常问题(issue#I8NMP7@Gitee) * 【core 】 修复PostgreSQL使用upsert字段大小写问题问题(issue#I8PB4X@Gitee) +* 【extra 】 修复TinyPinyinEngine可能的空指针问题(issue#3437@Github) ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) diff --git a/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/tinypinyin/TinyPinyinEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/tinypinyin/TinyPinyinEngine.java index edc678cae..2ecf0dd1c 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/tinypinyin/TinyPinyinEngine.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/tinypinyin/TinyPinyinEngine.java @@ -1,5 +1,7 @@ package cn.hutool.extra.pinyin.engine.tinypinyin; +import cn.hutool.core.lang.Opt; +import cn.hutool.core.util.StrUtil; import cn.hutool.extra.pinyin.PinyinEngine; import com.github.promeg.pinyinhelper.Pinyin; @@ -51,7 +53,8 @@ public class TinyPinyinEngine implements PinyinEngine { @Override public String getPinyin(String str, String separator) { - return Pinyin.toPinyin(str, separator).toLowerCase(); + final String pinyin = Pinyin.toPinyin(str, separator); + return StrUtil.isEmpty(pinyin) ? pinyin : pinyin.toLowerCase(); } } From cd79e6e5f8e2d826176bae04f0497e7a7875878a Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 20 Dec 2023 22:53:38 +0800 Subject: [PATCH 42/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dgraalvm=E5=8E=9F?= =?UTF-8?q?=E7=94=9F=E6=89=93=E5=8C=85=E4=BD=BF=E7=94=A8http=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E8=A2=AB=E8=BD=AC=E4=B8=BAfile=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../src/main/java/cn/hutool/core/util/URLUtil.java | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d3039357..0e3e5b044 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ * 【core 】 修复时间戳转Bean时异常问题(issue#I8NMP7@Gitee) * 【core 】 修复PostgreSQL使用upsert字段大小写问题问题(issue#I8PB4X@Gitee) * 【extra 】 修复TinyPinyinEngine可能的空指针问题(issue#3437@Github) +* 【core 】 修复graalvm原生打包使用http工具被转为file协议问题(issue#I8PY3Y@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/URLUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/URLUtil.java index a66463e67..f4d384a61 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/URLUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/URLUtil.java @@ -147,6 +147,14 @@ public class URLUtil extends URLEncodeUtil { try { return new URL(null, url, handler); } catch (MalformedURLException e) { + // issue#I8PY3Y + if(e.getMessage().contains("Accessing an URL protocol that was not enabled")){ + // Graalvm打包需要手动指定参数开启协议: + // --enable-url-protocols=http + // --enable-url-protocols=https + throw new UtilException(e); + } + // 尝试文件路径 try { return new File(url).toURI().toURL(); From e5888f6bc6ada217f943ad07440280b685a97702 Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 20 Dec 2023 23:14:48 +0800 Subject: [PATCH 43/45] remove invalid import --- .../main/java/cn/hutool/core/map/MapUtil.java | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java b/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java index b76a5f514..62aa933ee 100755 --- a/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java @@ -3,29 +3,18 @@ package cn.hutool.core.map; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.exceptions.UtilException; -import cn.hutool.core.lang.*; +import cn.hutool.core.lang.Editor; +import cn.hutool.core.lang.Filter; +import cn.hutool.core.lang.Pair; +import cn.hutool.core.lang.TypeReference; import cn.hutool.core.stream.CollectorUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.JdkUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.NavigableMap; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiFunction; import java.util.function.Function; From aa85eff8f5bec08b7d2a47579e7d908589c82a9b Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 23 Dec 2023 16:14:14 +0800 Subject: [PATCH 44/45] =?UTF-8?q?=E4=BF=AE=E5=A4=8DcloneSheet=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E9=94=99=E8=AF=AF=E5=AF=BC=E8=87=B4=E9=9D=9EXSSFWorkb?= =?UTF-8?q?ook=E9=94=99=E8=AF=AF=E5=91=BD=E5=90=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e3e5b044..55470af25 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.24(2023-12-20) +# 5.8.24(2023-12-23) ### 🐣新特性 * 【cache 】 Cache增加get重载,可自定义超时时间(issue#I8G0DL@Gitee) @@ -30,6 +30,7 @@ * 【core 】 修复PostgreSQL使用upsert字段大小写问题问题(issue#I8PB4X@Gitee) * 【extra 】 修复TinyPinyinEngine可能的空指针问题(issue#3437@Github) * 【core 】 修复graalvm原生打包使用http工具被转为file协议问题(issue#I8PY3Y@Gitee) +* 【poi 】 修复cloneSheet参数错误导致非XSSFWorkbook错误命名问题(issue#I8QIBB@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.23(2023-11-12) diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java index 0e0481b7e..c86c134d6 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelBase.java @@ -189,7 +189,8 @@ public class ExcelBase> implements Closeable { sheet = workbook.cloneSheet(sheetIndex, newSheetName); } else { sheet = this.workbook.cloneSheet(sheetIndex); - this.workbook.setSheetName(sheetIndex, newSheetName); + // issue#I8QIBB,clone后的sheet的index应该重新获取 + this.workbook.setSheetName(workbook.getSheetIndex(sheet), newSheetName); } if (setAsCurrentSheet) { this.sheet = sheet; From 3ab447d45acac2a11bd61563db8b573eaaf08ef9 Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 24 Dec 2023 00:01:57 +0800 Subject: [PATCH 45/45] =?UTF-8?q?=F0=9F=8C=A8=EF=B8=8FRelease=205.8.24?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hutool-all/pom.xml | 2 +- hutool-aop/pom.xml | 2 +- hutool-bloomFilter/pom.xml | 2 +- hutool-bom/pom.xml | 2 +- hutool-cache/pom.xml | 2 +- hutool-captcha/pom.xml | 2 +- hutool-core/pom.xml | 2 +- hutool-cron/pom.xml | 2 +- hutool-crypto/pom.xml | 2 +- hutool-db/pom.xml | 2 +- hutool-dfa/pom.xml | 2 +- hutool-extra/pom.xml | 2 +- hutool-http/pom.xml | 2 +- hutool-json/pom.xml | 2 +- hutool-jwt/pom.xml | 2 +- hutool-log/pom.xml | 2 +- hutool-poi/pom.xml | 2 +- hutool-script/pom.xml | 2 +- hutool-setting/pom.xml | 2 +- hutool-socket/pom.xml | 2 +- hutool-system/pom.xml | 2 +- pom.xml | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/hutool-all/pom.xml b/hutool-all/pom.xml index 98a2b0b45..812fd1d85 100755 --- a/hutool-all/pom.xml +++ b/hutool-all/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-all diff --git a/hutool-aop/pom.xml b/hutool-aop/pom.xml index a386d492d..e6f2eafce 100755 --- a/hutool-aop/pom.xml +++ b/hutool-aop/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-aop diff --git a/hutool-bloomFilter/pom.xml b/hutool-bloomFilter/pom.xml index 99450138a..e4512d2aa 100755 --- a/hutool-bloomFilter/pom.xml +++ b/hutool-bloomFilter/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-bloomFilter diff --git a/hutool-bom/pom.xml b/hutool-bom/pom.xml index 75c000811..3c62f76ed 100755 --- a/hutool-bom/pom.xml +++ b/hutool-bom/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-bom diff --git a/hutool-cache/pom.xml b/hutool-cache/pom.xml index ce50b14ad..84b8181ce 100755 --- a/hutool-cache/pom.xml +++ b/hutool-cache/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-cache diff --git a/hutool-captcha/pom.xml b/hutool-captcha/pom.xml index 3e9249d1c..433f96f48 100755 --- a/hutool-captcha/pom.xml +++ b/hutool-captcha/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-captcha diff --git a/hutool-core/pom.xml b/hutool-core/pom.xml index 3d8e75335..ab1788362 100755 --- a/hutool-core/pom.xml +++ b/hutool-core/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-core diff --git a/hutool-cron/pom.xml b/hutool-cron/pom.xml index b1aa11153..36ed1823c 100755 --- a/hutool-cron/pom.xml +++ b/hutool-cron/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-cron diff --git a/hutool-crypto/pom.xml b/hutool-crypto/pom.xml index d106f6032..4bb3ca56f 100755 --- a/hutool-crypto/pom.xml +++ b/hutool-crypto/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-crypto diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml index 7cd682ec5..b6e87daa5 100755 --- a/hutool-db/pom.xml +++ b/hutool-db/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-db diff --git a/hutool-dfa/pom.xml b/hutool-dfa/pom.xml index fcf451fe9..7a49cd226 100755 --- a/hutool-dfa/pom.xml +++ b/hutool-dfa/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-dfa diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml index a9ccd837d..c817a1d25 100755 --- a/hutool-extra/pom.xml +++ b/hutool-extra/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-extra diff --git a/hutool-http/pom.xml b/hutool-http/pom.xml index 1a6eee26e..b55ae1617 100755 --- a/hutool-http/pom.xml +++ b/hutool-http/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-http diff --git a/hutool-json/pom.xml b/hutool-json/pom.xml index 0f10b0255..894451b6b 100755 --- a/hutool-json/pom.xml +++ b/hutool-json/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-json diff --git a/hutool-jwt/pom.xml b/hutool-jwt/pom.xml index 4092f97a8..49224ccdf 100755 --- a/hutool-jwt/pom.xml +++ b/hutool-jwt/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-jwt diff --git a/hutool-log/pom.xml b/hutool-log/pom.xml index 4a4f1bafd..63b568a64 100755 --- a/hutool-log/pom.xml +++ b/hutool-log/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-log diff --git a/hutool-poi/pom.xml b/hutool-poi/pom.xml index 9a05a8038..808fc8f62 100755 --- a/hutool-poi/pom.xml +++ b/hutool-poi/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-poi diff --git a/hutool-script/pom.xml b/hutool-script/pom.xml index 019bacdb8..7959a5a86 100755 --- a/hutool-script/pom.xml +++ b/hutool-script/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-script diff --git a/hutool-setting/pom.xml b/hutool-setting/pom.xml index d7f941140..eb196f1cc 100755 --- a/hutool-setting/pom.xml +++ b/hutool-setting/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-setting diff --git a/hutool-socket/pom.xml b/hutool-socket/pom.xml index b47d5e1de..2c7651f8e 100755 --- a/hutool-socket/pom.xml +++ b/hutool-socket/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-socket diff --git a/hutool-system/pom.xml b/hutool-system/pom.xml index 38e6feed9..7133dcc2d 100755 --- a/hutool-system/pom.xml +++ b/hutool-system/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool-system diff --git a/pom.xml b/pom.xml index e61fb7297..d1ab97eb3 100755 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 5.8.24-SNAPSHOT + 5.8.24 hutool Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。 https://github.com/dromara/hutool