* 返回结果为{@link Duration}对象,通过调用toXXX方法返回相差单位 * - * @param startTime 开始时间 - * @param endTime 结束时间 + * @param startTimeInclude 开始时间(包含) + * @param endTimeExclude 结束时间(不包含) * @return 时间差 {@link Duration}对象 + * @see TemporalUtil#between(Temporal, Temporal) */ - public static Duration between(LocalDateTime startTime, LocalDateTime endTime) { - return Duration.between(startTime, endTime); + public static Duration between(LocalDateTime startTimeInclude, LocalDateTime endTimeExclude) { + return TemporalUtil.between(startTimeInclude, endTimeExclude); } + /** + * 获取两个日期的差,如果结束时间早于开始时间,获取结果为负。 + *
+ * 返回结果为时间差的long值 + * + * @param startTimeInclude 开始时间(包括) + * @param endTimeExclude 结束时间(不包括) + * @param unit 时间差单位 + * @return 时间差 + * @since 5.4.5 + */ + public static long between(LocalDateTime startTimeInclude, LocalDateTime endTimeExclude, ChronoUnit unit) { + return TemporalUtil.between(startTimeInclude, endTimeExclude, unit); + } + + /** + * 获取两个日期的表象时间差,如果结束时间早于开始时间,获取结果为负。 + *
+ * 比如2011年2月1日,和2021年8月11日,日相差了10天,月相差6月 + * + * @param startTimeInclude 开始时间(包括) + * @param endTimeExclude 结束时间(不包括) + * @return 时间差 + * @since 5.4.5 + */ + public static Period betweenPeriod(LocalDate startTimeInclude, LocalDate endTimeExclude) { + return Period.between(startTimeInclude, endTimeExclude); + } /** * 修改为一天的开始时间,例如:2020-02-02 00:00:00,000 diff --git a/hutool-core/src/main/java/cn/hutool/core/date/TemporalAccessorUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/TemporalAccessorUtil.java index d666301cb..3ecb8a5af 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/TemporalAccessorUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/TemporalAccessorUtil.java @@ -20,7 +20,7 @@ import java.time.temporal.TemporalField; * @author looly * @since 5.3.9 */ -public class TemporalAccessorUtil { +public class TemporalAccessorUtil extends TemporalUtil{ /** * 安全获取时间的某个属性,属性不存在返回0 diff --git a/hutool-core/src/main/java/cn/hutool/core/date/TemporalUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/TemporalUtil.java new file mode 100644 index 000000000..cd62f4e39 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/date/TemporalUtil.java @@ -0,0 +1,41 @@ +package cn.hutool.core.date; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.time.temporal.Temporal; + +/** + * {@link Temporal} 工具类封装 + * + * @author looly + * @since 5.4.5 + */ +public class TemporalUtil { + + /** + * 获取两个日期的差,如果结束时间早于开始时间,获取结果为负。 + *
+ * 返回结果为{@link Duration}对象,通过调用toXXX方法返回相差单位 + * + * @param startTimeInclude 开始时间(包含) + * @param endTimeExclude 结束时间(不包含) + * @return 时间差 {@link Duration}对象 + */ + public static Duration between(Temporal startTimeInclude, Temporal endTimeExclude) { + return Duration.between(startTimeInclude, endTimeExclude); + } + + /** + * 获取两个日期的差,如果结束时间早于开始时间,获取结果为负。 + *
+ * 返回结果为时间差的long值
+ *
+ * @param startTimeInclude 开始时间(包括)
+ * @param endTimeExclude 结束时间(不包括)
+ * @param unit 时间差单位
+ * @return 时间差
+ */
+ public static long between(Temporal startTimeInclude, Temporal endTimeExclude, ChronoUnit unit) {
+ return unit.between(startTimeInclude, endTimeExclude);
+ }
+}
diff --git a/hutool-core/src/main/java/cn/hutool/core/date/chinese/LunarInfo.java b/hutool-core/src/main/java/cn/hutool/core/date/chinese/LunarInfo.java
index a088d0c05..12863a4b6 100644
--- a/hutool-core/src/main/java/cn/hutool/core/date/chinese/LunarInfo.java
+++ b/hutool-core/src/main/java/cn/hutool/core/date/chinese/LunarInfo.java
@@ -40,13 +40,18 @@ public class LunarInfo {
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252,//2090-2099
};
+ // 支持的最大年限
+ public static final int MAX_YEAR = BASE_YEAR + LUNAR_CODE.length - 1;
+
/**
* 获取支持的最大年(包括)
*
* @return 最大年(包括)
+ * @deprecated 使用 {@link #MAX_YEAR}
*/
+ @Deprecated
public static int getMaxYear() {
- return BASE_YEAR + LUNAR_CODE.length - 1;
+ return MAX_YEAR;
}
/**
diff --git a/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java b/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java
index 6b3db398a..f7a76de1d 100644
--- a/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java
@@ -862,7 +862,7 @@ public class FileUtil extends PathUtil {
*/
public static File copyFile(String src, String dest, StandardCopyOption... options) throws IORuntimeException {
Assert.notBlank(src, "Source File path is blank !");
- Assert.notNull(src, "Destination File path is null !");
+ Assert.notBlank(dest, "Destination File path is blank !");
return copyFile(Paths.get(src), Paths.get(dest), options).toFile();
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Assert.java b/hutool-core/src/main/java/cn/hutool/core/lang/Assert.java
index c3137e67a..69557d274 100644
--- a/hutool-core/src/main/java/cn/hutool/core/lang/Assert.java
+++ b/hutool-core/src/main/java/cn/hutool/core/lang/Assert.java
@@ -68,7 +68,7 @@ public class Assert {
* 断言是否为假,如果为 {@code true} 抛出指定类型异常
* 并使用指定的函数获取错误信息返回
*
- * Assert.isFalse(i > 0, ()->{ + * Assert.isFalse(i > 0, ()->{ * // to query relation message * return new IllegalArgumentException("relation message to return"); * }); @@ -120,7 +120,7 @@ public class Assert { * 断言对象是否为{@code null} ,如果不为{@code null} 抛出指定类型异常 * 并使用指定的函数获取错误信息返回 *- * Assert.isNull(value, ()->{ + * Assert.isNull(value, ()->{ * // to query relation message * return new IllegalArgumentException("relation message to return"); * }); @@ -174,7 +174,7 @@ public class Assert { * 断言对象是否不为{@code null} ,如果为{@code null} 抛出指定类型异常 * 并使用指定的函数获取错误信息返回 *- * Assert.notNull(clazz, ()->{ + * Assert.notNull(clazz, ()->{ * // to query relation message * return new IllegalArgumentException("relation message to return"); * }); @@ -234,7 +234,7 @@ public class Assert { /** * 检查给定字符串是否为空,为空抛出自定义异常,并使用指定的函数获取错误信息返回。 *- * Assert.notEmpty(name, ()->{ + * Assert.notEmpty(name, ()->{ * // to query relation message * return new IllegalArgumentException("relation message to return"); * }); @@ -296,7 +296,7 @@ public class Assert { * 检查给定字符串是否为空白(null、空串或只包含空白符),为空抛出自定义异常。 * 并使用指定的函数获取错误信息返回 *- * Assert.notBlank(name, ()->{ + * Assert.notBlank(name, ()->{ * // to query relation message * return new IllegalArgumentException("relation message to return"); * }); @@ -357,7 +357,7 @@ public class Assert { * 断言给定字符串是否不被另一个字符串包含(即是否为子串) * 并使用指定的函数获取错误信息返回 *- * Assert.notContain(name, "rod", ()->{ + * Assert.notContain(name, "rod", ()->{ * // to query relation message * return new IllegalArgumentException("relation message to return "); * }); @@ -419,7 +419,7 @@ public class Assert { * 并使用指定的函数获取错误信息返回 * *- * Assert.notEmpty(array, ()->{ + * Assert.notEmpty(array, ()->{ * // to query relation message * return new IllegalArgumentException("relation message to return"); * }); @@ -479,7 +479,7 @@ public class Assert { * 断言给定数组是否不包含{@code null}元素,如果数组为空或 {@code null}将被认为不包含 * 并使用指定的函数获取错误信息返回 *- * Assert.noNullElements(array, ()->{ + * Assert.noNullElements(array, ()->{ * // to query relation message * return new IllegalArgumentException("relation message to return "); * }); @@ -538,7 +538,7 @@ public class Assert { * 断言给定集合非空 * 并使用指定的函数获取错误信息返回 *- * Assert.notEmpty(collection, ()->{ + * Assert.notEmpty(collection, ()->{ * // to query relation message * return new IllegalArgumentException("relation message to return"); * }); @@ -601,7 +601,7 @@ public class Assert { * 断言给定Map非空 * 并使用指定的函数获取错误信息返回 *- * Assert.notEmpty(map, ()->{ + * Assert.notEmpty(map, ()->{ * // to query relation message * return new IllegalArgumentException("relation message to return"); * }); @@ -744,7 +744,7 @@ public class Assert { * 检查boolean表达式,当检查结果为false时抛出 {@code IllegalStateException}。 * 并使用指定的函数获取错误信息返回 *- * Assert.state(id == null, ()->{ + * Assert.state(id == null, ()->{ * // to query relation message * return "relation message to return "; * }); 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 737f7347d..120d32f39 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java @@ -1967,20 +1967,20 @@ public class NumberUtil { /** * 数字转字符串
- * 调用{@link Number#toString()},并去除尾小数点儿后多余的0 + * 调用{@link Number#toString()}或 {@link BigDecimal#toPlainString()},并去除尾小数点儿后多余的0 * * @param number A Number * @return A String. */ public static String toStr(Number number) { - if (null == number) { - throw new NullPointerException("Number is null !"); - } - - if (false == ObjectUtil.isValidIfNumber(number)) { - throw new IllegalArgumentException("Number is non-finite!"); + Assert.notNull(number, "Number is null !"); + + // BigDecimal单独处理,使用非科学计数法 + if(number instanceof BigDecimal){ + return toStr((BigDecimal)number); } + Assert.isTrue(isValidNumber(number), "Number is non-finite!"); // 去掉小数点儿后多余的0 String string = number.toString(); if (string.indexOf('.') > 0 && string.indexOf('e') < 0 && string.indexOf('E') < 0) { @@ -1994,6 +1994,19 @@ public class NumberUtil { return string; } + /** + * {@link BigDecimal}数字转字符串
+ * 调用{@link BigDecimal#toPlainString()},并去除尾小数点儿后多余的0 + * + * @param bigDecimal A {@link BigDecimal} + * @return A String. + * @since 5.4.6 + */ + public static String toStr(BigDecimal bigDecimal) { + Assert.notNull(bigDecimal, "BigDecimal is null !"); + return bigDecimal.stripTrailingZeros().toPlainString(); + } + /** * 数字转{@link BigDecimal} * @@ -2005,6 +2018,17 @@ public class NumberUtil { if (null == number) { return BigDecimal.ZERO; } + + if(number instanceof BigDecimal){ + return (BigDecimal) number; + } else if (number instanceof Long) { + return new BigDecimal((Long) number); + } else if (number instanceof Integer) { + return new BigDecimal((Integer) number); + } else if (number instanceof BigInteger) { + return new BigDecimal((BigInteger) number); + } + return toBigDecimal(number.toString()); } @@ -2019,6 +2043,38 @@ public class NumberUtil { return (null == number) ? BigDecimal.ZERO : new BigDecimal(number); } + /** + * 数字转{@link BigInteger} + * + * @param number 数字 + * @return {@link BigInteger} + * @since 5.4.5 + */ + public static BigInteger toBigInteger(Number number) { + if (null == number) { + return BigInteger.ZERO; + } + + if(number instanceof BigInteger){ + return (BigInteger) number; + } else if (number instanceof Long) { + return BigInteger.valueOf((Long) number); + } + + return toBigInteger(number.longValue()); + } + + /** + * 数字转{@link BigInteger} + * + * @param number 数字 + * @return {@link BigInteger} + * @since 5.4.5 + */ + public static BigInteger toBigInteger(String number) { + return (null == number) ? BigInteger.ZERO : new BigInteger(number); + } + /** * 是否空白符
* 空白符包括空格、制表符、全角空格和不间断空格
diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java index 222eb936e..faa4000ca 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java @@ -139,7 +139,7 @@ public class ReflectUtil { } /** - * 查找指定类中的所有字段(包括非public字段),也包括父类和Object类的字段, 字段不存在则返回null
+ * 查找指定类中的指定name的字段(包括非public字段),也包括父类和Object类的字段, 字段不存在则返回null
* * @param beanClass 被查找字段的类,不能为null * @param name 字段名 @@ -148,26 +148,20 @@ public class ReflectUtil { */ public static Field getField(Class> beanClass, String name) throws SecurityException { final Field[] fields = getFields(beanClass); - if (ArrayUtil.isNotEmpty(fields)) { - for (Field field : fields) { - if ((name.equals(getFieldName(field)))) { - return field; - } - } - } - return null; + return ArrayUtil.firstMatch((field)->name.equals(getFieldName(field)), fields); } /** - * 获取指定类中字段名和字段对应的Map,包括其父类中的字段 + * 获取指定类中字段名和字段对应的有序Map,包括其父类中的字段
+ * 如果子类与父类中存在同名字段,则这两个字段同时存在,子类字段在前,父类字段在后。 * * @param beanClass 类 - * @return 字段名和字段对应的Map + * @return 字段名和字段对应的Map,有序 * @since 5.0.7 */ public static MapgetFieldMap(Class> beanClass) { final Field[] fields = getFields(beanClass); - final HashMap map = MapUtil.newHashMap(fields.length); + final HashMap map = MapUtil.newHashMap(fields.length, true); for (Field field : fields) { map.put(field.getName(), field); } @@ -175,7 +169,8 @@ public class ReflectUtil { } /** - * 获得一个类中所有字段列表,包括其父类中的字段 + * 获得一个类中所有字段列表,包括其父类中的字段
+ * 如果子类与父类中存在同名字段,则这两个字段同时存在,子类字段在前,父类字段在后。 * * @param beanClass 类 * @return 字段列表 @@ -192,14 +187,15 @@ public class ReflectUtil { } /** - * 获得一个类中所有字段列表,直接反射获取,无缓存 + * 获得一个类中所有字段列表,直接反射获取,无缓存
+ * 如果子类与父类中存在同名字段,则这两个字段同时存在,子类字段在前,父类字段在后。 * * @param beanClass 类 - * @param withSuperClassFieds 是否包括父类的字段列表 + * @param withSuperClassFields 是否包括父类的字段列表 * @return 字段列表 * @throws SecurityException 安全检查异常 */ - public static Field[] getFieldsDirectly(Class> beanClass, boolean withSuperClassFieds) throws SecurityException { + public static Field[] getFieldsDirectly(Class> beanClass, boolean withSuperClassFields) throws SecurityException { Assert.notNull(beanClass); Field[] allFields = null; @@ -212,7 +208,7 @@ public class ReflectUtil { } else { allFields = ArrayUtil.append(allFields, declaredFields); } - searchType = withSuperClassFieds ? searchType.getSuperclass() : null; + searchType = withSuperClassFields ? searchType.getSuperclass() : null; } return allFields; diff --git a/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java index e7162eb4f..eb0e34ea8 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java @@ -345,6 +345,19 @@ public class XmlUtil { // -------------------------------------------------------------------------------------- Write + /** + * 将XML文档转换为String
+ * 字符编码使用XML文档中的编码,获取不到则使用UTF-8
+ * 默认非格式化输出,若想格式化请使用{@link #format(Document)} + * + * @param doc XML文档 + * @return XML字符串 + * @since 5.4.5 + */ + public static String toStr(Node doc) { + return toStr(doc, false); + } + /** * 将XML文档转换为String
* 字符编码使用XML文档中的编码,获取不到则使用UTF-8
@@ -354,7 +367,20 @@ public class XmlUtil { * @return XML字符串 */ public static String toStr(Document doc) { - return toStr(doc, false); + return toStr((Node)doc); + } + + /** + * 将XML文档转换为String
+ * 字符编码使用XML文档中的编码,获取不到则使用UTF-8 + * + * @param doc XML文档 + * @param isPretty 是否格式化输出 + * @return XML字符串 + * @since 5.4.5 + */ + public static String toStr(Node doc, boolean isPretty) { + return toStr(doc, CharsetUtil.UTF_8, isPretty); } /** @@ -367,7 +393,21 @@ public class XmlUtil { * @since 3.0.9 */ public static String toStr(Document doc, boolean isPretty) { - return toStr(doc, CharsetUtil.UTF_8, isPretty); + return toStr((Node)doc, isPretty); + } + + /** + * 将XML文档转换为String
+ * 字符编码使用XML文档中的编码,获取不到则使用UTF-8 + * + * @param doc XML文档 + * @param charset 编码 + * @param isPretty 是否格式化输出 + * @return XML字符串 + * @since 5.4.5 + */ + public static String toStr(Node doc, String charset, boolean isPretty) { + return toStr(doc, charset, isPretty, false); } /** @@ -381,7 +421,7 @@ public class XmlUtil { * @since 3.0.9 */ public static String toStr(Document doc, String charset, boolean isPretty) { - return toStr(doc, charset, isPretty, false); + return toStr((Node)doc, charset, isPretty); } /** @@ -395,7 +435,7 @@ public class XmlUtil { * @return XML字符串 * @since 5.1.2 */ - public static String toStr(Document doc, String charset, boolean isPretty, boolean omitXmlDeclaration) { + public static String toStr(Node doc, String charset, boolean isPretty, boolean omitXmlDeclaration) { final StringWriter writer = StrUtil.getWriter(); try { write(doc, writer, charset, isPretty ? INDENT_DEFAULT : 0, omitXmlDeclaration); diff --git a/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java index 16284002e..a74683f05 100644 --- a/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java @@ -364,12 +364,26 @@ public class BeanUtilTest { @Getter @Setter - public static class Person { + public static class SubPersonWithOverlayTransientField extends PersonWithTransientField { + // 覆盖父类中 transient 属性 private String name; + } + + @Getter + @Setter + public static class Person { + private String name; private int age; private String openid; } + @Getter + @Setter + public static class PersonWithTransientField { + private transient String name; + private int age; + private String openid; + } public static class Person2 { public Person2(String name, int age, String openid) { @@ -383,6 +397,23 @@ public class BeanUtilTest { public String openid; } + /** + * #1173 + */ + @Test + public void beanToBeanOverlayFieldTest() { + SubPersonWithOverlayTransientField source = new SubPersonWithOverlayTransientField(); + source.setName("zhangsan"); + source.setAge(20); + source.setOpenid("1"); + SubPersonWithOverlayTransientField dest = new SubPersonWithOverlayTransientField(); + BeanUtil.copyProperties(source, dest); + + Assert.assertEquals(source.getName(), dest.getName()); + Assert.assertEquals(source.getAge(), dest.getAge()); + Assert.assertEquals(source.getOpenid(), dest.getOpenid()); + } + @Test public void beanToBeanTest() { // 修复对象无getter方法导致报错的问题 @@ -434,6 +465,8 @@ public class BeanUtilTest { @Data public static class HllFoodEntity implements Serializable { + private static final long serialVersionUID = 1L; + private String bookId; @Alias("code") private String code2; diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java index 52d063af0..43d5bd5f6 100644 --- a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java @@ -9,6 +9,8 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.atomic.AtomicIntegerArray; +import java.util.concurrent.atomic.AtomicLongArray; /** * 类型转换工具单元测试 @@ -222,6 +224,20 @@ public class ConvertTest { Assert.assertEquals("5.1.1", product.getVersion()); } + @Test + public void toAtomicIntegerArrayTest(){ + String str = "1,2"; + final AtomicIntegerArray atomicIntegerArray = Convert.convert(AtomicIntegerArray.class, str); + Assert.assertEquals("[1, 2]", atomicIntegerArray.toString()); + } + + @Test + public void toAtomicLongArrayTest(){ + String str = "1,2"; + final AtomicLongArray atomicLongArray = Convert.convert(AtomicLongArray.class, str); + Assert.assertEquals("[1, 2]", atomicLongArray.toString()); + } + @Data @AllArgsConstructor public static class Product implements Serializable { diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/StringConvertTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/StringConvertTest.java new file mode 100644 index 000000000..aeed15190 --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/convert/StringConvertTest.java @@ -0,0 +1,15 @@ +package cn.hutool.core.convert; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.TimeZone; + +public class StringConvertTest { + + @Test + public void timezoneToStrTest(){ + final String s = Convert.toStr(TimeZone.getTimeZone("Asia/Shanghai")); + Assert.assertEquals("Asia/Shanghai", s); + } +} diff --git a/hutool-core/src/test/java/cn/hutool/core/date/ChineseDateTest.java b/hutool-core/src/test/java/cn/hutool/core/date/ChineseDateTest.java index 877064d84..1792fd4ff 100644 --- a/hutool-core/src/test/java/cn/hutool/core/date/ChineseDateTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/date/ChineseDateTest.java @@ -85,4 +85,20 @@ public class ChineseDateTest { ChineseDate chineseDate = new ChineseDate(DateUtil.parseDate("2023-01-20")); Assert.assertTrue(StrUtil.isEmpty(chineseDate.getFestivals())); } + + @Test + public void dateTest(){ + // 修复这两个日期不正确的问题 + // 问题出在计算与1900-01-31相差天数的问题上了,相差天数非整天 + ChineseDate date = new ChineseDate(DateUtil.parseDate("1991-09-14")); + Assert.assertEquals("辛未羊年 八月初七", date.toString()); + date = new ChineseDate(DateUtil.parseDate("1991-09-15")); + Assert.assertEquals("辛未羊年 八月初八", date.toString()); + } + + @Test + public void dateTest2(){ + ChineseDate date = new ChineseDate(DateUtil.parse("2020-10-19 11:12:23")); + Assert.assertEquals("庚子鼠年 九月初三", date.toString()); + } } diff --git a/hutool-core/src/test/java/cn/hutool/core/net/UrlBuilderTest.java b/hutool-core/src/test/java/cn/hutool/core/net/UrlBuilderTest.java index fc861f3fe..fe1b95f47 100644 --- a/hutool-core/src/test/java/cn/hutool/core/net/UrlBuilderTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/net/UrlBuilderTest.java @@ -204,4 +204,10 @@ public class UrlBuilderTest { final UrlBuilder urlBuilder = UrlBuilder.ofHttp("http://a.com/aaa bbb.html", CharsetUtil.CHARSET_UTF_8); Assert.assertEquals("http://a.com/aaa%20bbb.html", urlBuilder.toString()); } + + @Test + public void dotEncodeTest(){ + final UrlBuilder urlBuilder = UrlBuilder.ofHttp("http://xtbgyy.digitalgd.com.cn/ebus/../../..", CharsetUtil.CHARSET_UTF_8); + Assert.assertEquals("http://xtbgyy.digitalgd.com.cn/ebus/../../..", urlBuilder.toString()); + } } diff --git a/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java index 8891b4986..10584a2a8 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java @@ -279,4 +279,12 @@ public class NumberUtilTest { final Set> set = Convert.convert(Set.class, ints); Assert.assertEquals(5, set.size()); } + + @Test + public void toStrTest(){ + Assert.assertEquals("1", NumberUtil.toStr(new BigDecimal("1.0000000000"))); + Assert.assertEquals("0", NumberUtil.toStr(NumberUtil.sub(new BigDecimal("9600.00000"), new BigDecimal("9600.00000")))); + Assert.assertEquals("0", NumberUtil.toStr(NumberUtil.sub(new BigDecimal("9600.0000000000"), new BigDecimal("9600.000000")))); + Assert.assertEquals("0", NumberUtil.toStr(new BigDecimal("9600.00000").subtract(new BigDecimal("9600.000000000")))); + } } diff --git a/hutool-cron/pom.xml b/hutool-cron/pom.xml index f4f0368c7..967030a24 100644 --- a/hutool-cron/pom.xml +++ b/hutool-cron/pom.xml @@ -7,7 +7,7 @@cn.hutool hutool-parent -5.4.5-SNAPSHOT +5.4.6-SNAPSHOT hutool-cron diff --git a/hutool-crypto/pom.xml b/hutool-crypto/pom.xml index 25acea0a2..f88bc3bd6 100644 --- a/hutool-crypto/pom.xml +++ b/hutool-crypto/pom.xml @@ -9,7 +9,7 @@cn.hutool hutool-parent -5.4.5-SNAPSHOT +5.4.6-SNAPSHOT hutool-crypto diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml index 99518169b..3781e1697 100644 --- a/hutool-db/pom.xml +++ b/hutool-db/pom.xml @@ -9,7 +9,7 @@cn.hutool hutool-parent -5.4.5-SNAPSHOT +5.4.6-SNAPSHOT hutool-db diff --git a/hutool-dfa/pom.xml b/hutool-dfa/pom.xml index 1d2a09ab2..6cf12759b 100644 --- a/hutool-dfa/pom.xml +++ b/hutool-dfa/pom.xml @@ -7,7 +7,7 @@cn.hutool hutool-parent -5.4.5-SNAPSHOT +5.4.6-SNAPSHOT hutool-dfa diff --git a/hutool-extra/bopomofo4j-temp/bopomofo4j-c6e41074-5302-42b6-9bdf-8742cb416a62.jar b/hutool-extra/bopomofo4j-temp/bopomofo4j-c6e41074-5302-42b6-9bdf-8742cb416a62.jar new file mode 100644 index 000000000..6ae573b55 Binary files /dev/null and b/hutool-extra/bopomofo4j-temp/bopomofo4j-c6e41074-5302-42b6-9bdf-8742cb416a62.jar differ diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml index f91f5ac87..d07297970 100644 --- a/hutool-extra/pom.xml +++ b/hutool-extra/pom.xml @@ -9,7 +9,7 @@cn.hutool hutool-parent -5.4.5-SNAPSHOT +5.4.6-SNAPSHOT hutool-extra @@ -233,6 +233,12 @@1.1.8 true ++ com.rnkrsoft.bopomofo4j +bopomofo4j +1.0.0 +true +cglib cglib diff --git a/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/bopomofo4j/Bopomofo4jEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/bopomofo4j/Bopomofo4jEngine.java new file mode 100644 index 000000000..09409cab8 --- /dev/null +++ b/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/bopomofo4j/Bopomofo4jEngine.java @@ -0,0 +1,43 @@ +package cn.hutool.extra.pinyin.engine.bopomofo4j; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.pinyin.PinyinEngine; +import com.rnkrsoft.bopomofo4j.Bopomofo4j; +import com.rnkrsoft.bopomofo4j.ToneType; + +/** + * 封装了Bopomofo4j的引擎。 + * + *+ * Bopomofo4j封装,项目:https://gitee.com/rnkrsoft/Bopomofo4j。 + *
+ * + *+ * 引入: + *
+ * <dependency> + * <groupId>com.rnkrsoft.bopomofo4j</groupId> + * <artifactId>bopomofo4j</artifactId> + * <version>1.0.0</version> + * </dependency> + *+ * + * @author looly + * @since 5.4.5 + */ +public class Bopomofo4jEngine implements PinyinEngine { + + public Bopomofo4jEngine(){ + Bopomofo4j.local(); + } + + @Override + public String getPinyin(char c) { + return Bopomofo4j.pinyin(String.valueOf(c), ToneType.WITHOUT_TONE, false, false, StrUtil.EMPTY); + } + + @Override + public String getPinyin(String str, String separator) { + return Bopomofo4j.pinyin(str, ToneType.WITHOUT_TONE, false, false, separator); + } +} diff --git a/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/bopomofo4j/package-info.java b/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/bopomofo4j/package-info.java new file mode 100644 index 000000000..8e56f1b49 --- /dev/null +++ b/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/bopomofo4j/package-info.java @@ -0,0 +1,20 @@ +/** + * 封装了Bopomofo4j的引擎。 + * + *+ * Bopomofo4j封装,项目:https://gitee.com/rnkrsoft/Bopomofo4j。 + *
+ * + *+ * 引入: + *
+ * <dependency> + * <groupId>com.rnkrsoft.bopomofo4j</groupId> + * <artifactId>bopomofo4j</artifactId> + * <version>1.0.0</version> + * </dependency> + *+ * + * @author looly + */ +package cn.hutool.extra.pinyin.engine.bopomofo4j; \ No newline at end of file diff --git a/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.pinyin.PinyinEngine b/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.pinyin.PinyinEngine index 5526a0a33..c91f32dd3 100644 --- a/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.pinyin.PinyinEngine +++ b/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.pinyin.PinyinEngine @@ -1,3 +1,4 @@ cn.hutool.extra.pinyin.engine.tinypinyin.TinyPinyinEngine cn.hutool.extra.pinyin.engine.jpinyin.JPinyinEngine -cn.hutool.extra.pinyin.engine.pinyin4j.Pinyin4jEngine \ No newline at end of file +cn.hutool.extra.pinyin.engine.pinyin4j.Pinyin4jEngine +cn.hutool.extra.pinyin.engine.bopomofo4j.Bopomofo4jEngine \ No newline at end of file diff --git a/hutool-extra/src/test/java/cn/hutool/extra/pinyin/PinyinUtilTest.java b/hutool-extra/src/test/java/cn/hutool/extra/pinyin/PinyinUtilTest.java index 751fa53ee..a39c8c1db 100644 --- a/hutool-extra/src/test/java/cn/hutool/extra/pinyin/PinyinUtilTest.java +++ b/hutool-extra/src/test/java/cn/hutool/extra/pinyin/PinyinUtilTest.java @@ -1,5 +1,6 @@ package cn.hutool.extra.pinyin; +import cn.hutool.extra.pinyin.engine.bopomofo4j.Bopomofo4jEngine; import cn.hutool.extra.pinyin.engine.pinyin4j.Pinyin4jEngine; import org.junit.Assert; import org.junit.Test; @@ -19,6 +20,13 @@ public class PinyinUtilTest { Assert.assertEquals("ni hao h", pinyin); } + @Test + public void getPinyinByBopomofo4jTest() { + final Bopomofo4jEngine engine = new Bopomofo4jEngine(); + final String pinyin = engine.getPinyin("你好h", " "); + Assert.assertEquals("ni haoh", pinyin); + } + @Test public void getPinyinUpperCaseTest(){ final String pinyin = PinyinUtil.getPinyin("你好怡", " "); @@ -37,4 +45,11 @@ public class PinyinUtilTest { final String result = engine.getFirstLetter("林海", ""); Assert.assertEquals("lh", result); } + + @Test + public void getFirstLetterByBopomofo4jTest(){ + final Bopomofo4jEngine engine = new Bopomofo4jEngine(); + final String result = engine.getFirstLetter("林海", ""); + Assert.assertEquals("lh", result); + } } diff --git a/hutool-http/pom.xml b/hutool-http/pom.xml index a7b33873e..ad3171410 100644 --- a/hutool-http/pom.xml +++ b/hutool-http/pom.xml @@ -9,7 +9,7 @@cn.hutool hutool-parent -5.4.5-SNAPSHOT +5.4.6-SNAPSHOT hutool-http diff --git a/hutool-http/src/main/java/cn/hutool/http/Header.java b/hutool-http/src/main/java/cn/hutool/http/Header.java index 1c90606c5..86dc86245 100644 --- a/hutool-http/src/main/java/cn/hutool/http/Header.java +++ b/hutool-http/src/main/java/cn/hutool/http/Header.java @@ -9,9 +9,19 @@ public enum Header { //------------------------------------------------------------- 通用头域 /** - * 提供验证头 + * 提供验证头,例如: + *+ * Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l + **/ AUTHORIZATION("Authorization"), + /** + * 提供给代理服务器的用于身份验证的凭证,例如: + *+ * Proxy-Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l + *+ */ + PROXY_AUTHORIZATION("Proxy-Authorization"), /** * 提供日期和时间标志,说明报文是什么时间创建的 */ diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpConnection.java b/hutool-http/src/main/java/cn/hutool/http/HttpConnection.java index 7dd41123e..bf1d7dcf2 100644 --- a/hutool-http/src/main/java/cn/hutool/http/HttpConnection.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpConnection.java @@ -531,7 +531,7 @@ public class HttpConnection { final URLConnection conn = openConnection(); if (false == conn instanceof HttpURLConnection) { // 防止其它协议造成的转换异常 - throw new HttpException("'{}' is not a http connection, make sure URL is format for http.", conn.getClass().getName()); + throw new HttpException("'{}' of URL [{}] is not a http connection, make sure URL is format for http.", conn.getClass().getName(), this.url); } return (HttpURLConnection) conn; diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java b/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java index b0cae62d8..daba627c1 100644 --- a/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java @@ -1,6 +1,5 @@ package cn.hutool.http; -import cn.hutool.core.codec.Base64; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.io.IORuntimeException; @@ -981,16 +980,32 @@ public class HttpRequest extends HttpBase{ } /** - * 简单验证 + * 简单验证,生成的头信息类似于: + * + * Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l + ** * @param username 用户名 * @param password 密码 - * @return HttpRequest + * @return this */ public HttpRequest basicAuth(String username, String password) { - final String data = username.concat(":").concat(password); - final String base64 = Base64.encode(data, charset); - return auth("Basic " + base64); + return auth(HttpUtil.buildBasicAuth(username, password, charset)); + } + + /** + * 简单代理验证,生成的头信息类似于: + *+ * Proxy-Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l + *+ * + * @param username 用户名 + * @param password 密码 + * @return this + * @since 5.4.6 + */ + public HttpRequest basicProxyAuth(String username, String password) { + return proxyAuth(HttpUtil.buildBasicAuth(username, password, charset)); } /** @@ -1005,6 +1020,18 @@ public class HttpRequest extends HttpBase{ return this; } + /** + * 验证,简单插入Authorization头 + * + * @param content 验证内容 + * @return HttpRequest + * @since 5.4.6 + */ + public HttpRequest proxyAuth(String content) { + header(Header.PROXY_AUTHORIZATION, content, true); + return this; + } + @Override public String toString() { StringBuilder sb = StrUtil.builder(); diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpUtil.java b/hutool-http/src/main/java/cn/hutool/http/HttpUtil.java index db816cd27..1c37c31cd 100644 --- a/hutool-http/src/main/java/cn/hutool/http/HttpUtil.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpUtil.java @@ -1,5 +1,6 @@ package cn.hutool.http; +import cn.hutool.core.codec.Base64; import cn.hutool.core.convert.Convert; import cn.hutool.core.io.FastByteArrayOutputStream; import cn.hutool.core.io.FileUtil; @@ -870,4 +871,21 @@ public class HttpUtil { public static SimpleServer createServer(int port) { return new SimpleServer(port); } + + /** + * 构建简单的账号秘密验证信息,构建后类似于: + * + * Basic YWxhZGRpbjpvcGVuc2VzYW1l + *+ * + * @param username 账号 + * @param password 密码 + * @param charset 编码(如果账号或密码中有非ASCII字符适用) + * @return 密码验证信息 + * @since 5.4.6 + */ + public static String buildBasicAuth(String username, String password, Charset charset){ + final String data = username.concat(":").concat(password); + return "Basic " + Base64.encode(data, charset); + } } diff --git a/hutool-http/src/test/java/cn/hutool/http/test/HttpRequestTest.java b/hutool-http/src/test/java/cn/hutool/http/test/HttpRequestTest.java index aa1d9d93f..bf00b18ff 100644 --- a/hutool-http/src/test/java/cn/hutool/http/test/HttpRequestTest.java +++ b/hutool-http/src/test/java/cn/hutool/http/test/HttpRequestTest.java @@ -143,4 +143,5 @@ public class HttpRequestTest { HttpResponse execute = get.execute(); Console.log(execute.body()); } + } diff --git a/hutool-json/pom.xml b/hutool-json/pom.xml index b84f23bec..1fd98acf1 100644 --- a/hutool-json/pom.xml +++ b/hutool-json/pom.xml @@ -9,7 +9,7 @@cn.hutool hutool-parent -5.4.5-SNAPSHOT +5.4.6-SNAPSHOT hutool-json diff --git a/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java b/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java index c47ac3df6..98e9c3264 100644 --- a/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java +++ b/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java @@ -2,6 +2,7 @@ package cn.hutool.json; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.date.TemporalAccessorUtil; import cn.hutool.core.util.CharUtil; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; @@ -239,6 +240,9 @@ final class InternalJSONUtil { */ private static String formatDate(Object dateObj, String format) { if (StrUtil.isNotBlank(format)) { + if(dateObj instanceof TemporalAccessor){ + return TemporalAccessorUtil.format((TemporalAccessor) dateObj, format); + } //用户定义了日期格式 return JSONUtil.quote(DateUtil.format(Convert.toDate(dateObj), format)); } diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java index 0f0117c8a..3c6c15363 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java @@ -351,6 +351,18 @@ public class JSONObject implements JSON, JSONGetter, Map @Override @Deprecated public JSONObject put(String key, Object value) throws JSONException { + return set(key, value); + } + + /** + * 设置键值对到JSONObject中,在忽略null模式下,如果值为 null
,将此键移除 + * + * @param key 键 + * @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL. + * @return this. + * @throws JSONException 值是无穷数字抛出此异常 + */ + public JSONObject set(String key, Object value) throws JSONException { if (null == key) { return this; } @@ -366,19 +378,6 @@ public class JSONObject implements JSON, JSONGetter, Map return this; } - /** - * 设置键值对到JSONObject中,在忽略null模式下,如果值为 null
,将此键移除 - * - * @param key 键 - * @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL. - * @return this. - * @throws JSONException 值是无穷数字抛出此异常 - */ - public JSONObject set(String key, Object value) throws JSONException { - put(key, value); - return this; - } - /** * 一次性Put 键值对,如果key已经存在抛出异常,如果键值中有null值,忽略 * @@ -392,7 +391,7 @@ public class JSONObject implements JSON, JSONGetter, Map if (rawHashMap.containsKey(key)) { throw new JSONException("Duplicate key \"{}\"", key); } - this.put(key, value); + this.set(key, value); } return this; } @@ -407,7 +406,7 @@ public class JSONObject implements JSON, JSONGetter , Map */ public JSONObject putOpt(String key, Object value) throws JSONException { if (key != null && value != null) { - this.put(key, value); + this.set(key, value); } return this; } @@ -415,7 +414,7 @@ public class JSONObject implements JSON, JSONGetter , Map @Override public void putAll(Map extends String, ?> m) { for (Entry extends String, ?> entry : m.entrySet()) { - this.put(entry.getKey(), entry.getValue()); + this.set(entry.getKey(), entry.getValue()); } } @@ -432,7 +431,7 @@ public class JSONObject implements JSON, JSONGetter , Map InternalJSONUtil.testValidity(value); Object object = this.getObj(key); if (object == null) { - this.put(key, value instanceof JSONArray ? new JSONArray(this.config).set(value) : value); + this.set(key, value instanceof JSONArray ? new JSONArray(this.config).set(value) : value); } else if (object instanceof JSONArray) { ((JSONArray) object).set(value); } else { @@ -472,19 +471,19 @@ public class JSONObject implements JSON, JSONGetter , Map public JSONObject increment(String key) throws JSONException { Object value = this.getObj(key); if (value == null) { - this.put(key, 1); + this.set(key, 1); } else if (value instanceof BigInteger) { - this.put(key, ((BigInteger) value).add(BigInteger.ONE)); + this.set(key, ((BigInteger) value).add(BigInteger.ONE)); } else if (value instanceof BigDecimal) { - this.put(key, ((BigDecimal) value).add(BigDecimal.ONE)); + this.set(key, ((BigDecimal) value).add(BigDecimal.ONE)); } else if (value instanceof Integer) { - this.put(key, (Integer) value + 1); + this.set(key, (Integer) value + 1); } else if (value instanceof Long) { - this.put(key, (Long) value + 1); + this.set(key, (Long) value + 1); } else if (value instanceof Double) { - this.put(key, (Double) value + 1); + this.set(key, (Double) value + 1); } else if (value instanceof Float) { - this.put(key, (Float) value + 1); + this.set(key, (Float) value + 1); } else { throw new JSONException("Unable to increment [" + JSONUtil.quote(key) + "]."); } @@ -652,8 +651,11 @@ public class JSONObject implements JSON, JSONGetter , Map } else if (source instanceof Map) { // Map for (final Entry, ?> e : ((Map, ?>) source).entrySet()) { - this.put(Convert.toStr(e.getKey()), e.getValue()); + this.set(Convert.toStr(e.getKey()), e.getValue()); } + }else if (source instanceof Map.Entry) { + final Map.Entry entry = (Map.Entry) source; + this.set(Convert.toStr(entry.getKey()), entry.getValue()); } else if (source instanceof CharSequence) { // 可能为JSON字符串 init((CharSequence) source); diff --git a/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java b/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java index cc5583dad..9f7e8422a 100644 --- a/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java @@ -9,6 +9,7 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.lang.Console; +import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.test.bean.JSONBean; import cn.hutool.json.test.bean.ResultDto; @@ -27,9 +28,13 @@ import org.junit.Ignore; import org.junit.Test; import java.math.BigDecimal; +import java.sql.Timestamp; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Set; /** * JSONObject单元测试 @@ -425,6 +430,14 @@ public class JSONObjectTest { Assert.assertEquals("{\"date\":[\"2020-06-05 11:16:11\"],\"bbb\":[\"222\"],\"aaa\":[\"123\"]}", json.toString()); } + @Test + public void getTimestampTest(){ + String timeStr = "1970-01-01 00:00:00"; + final JSONObject jsonObject = JSONUtil.createObj().set("time", timeStr); + final Timestamp time = jsonObject.get("time", Timestamp.class); + Assert.assertEquals("1970-01-01 00:00:00.0", time.toString()); + } + public enum TestEnum { TYPE_A, TYPE_B } @@ -497,4 +510,14 @@ public class JSONObjectTest { return this.fieldToIgnore; } } + + @Test + public void setEntryTest(){ + final HashMap of = MapUtil.of("test", "testValue"); + final Set > entries = of.entrySet(); + final Map.Entry next = entries.iterator().next(); + + final JSONObject jsonObject = JSONUtil.parseObj(next); + Console.log(jsonObject); + } } diff --git a/hutool-log/pom.xml b/hutool-log/pom.xml index 3d15e4203..f0aa4f5e3 100644 --- a/hutool-log/pom.xml +++ b/hutool-log/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent -5.4.5-SNAPSHOT +5.4.6-SNAPSHOT hutool-log diff --git a/hutool-poi/pom.xml b/hutool-poi/pom.xml index 47dcd4ea4..9b70a7668 100644 --- a/hutool-poi/pom.xml +++ b/hutool-poi/pom.xml @@ -8,7 +8,7 @@cn.hutool hutool-parent -5.4.5-SNAPSHOT +5.4.6-SNAPSHOT hutool-poi diff --git a/hutool-script/pom.xml b/hutool-script/pom.xml index 995789f43..378cb3448 100644 --- a/hutool-script/pom.xml +++ b/hutool-script/pom.xml @@ -8,7 +8,7 @@cn.hutool hutool-parent -5.4.5-SNAPSHOT +5.4.6-SNAPSHOT hutool-script diff --git a/hutool-setting/pom.xml b/hutool-setting/pom.xml index 00e487784..ffc86415c 100644 --- a/hutool-setting/pom.xml +++ b/hutool-setting/pom.xml @@ -9,7 +9,7 @@cn.hutool hutool-parent -5.4.5-SNAPSHOT +5.4.6-SNAPSHOT hutool-setting diff --git a/hutool-socket/pom.xml b/hutool-socket/pom.xml index 459441938..bd43ba346 100644 --- a/hutool-socket/pom.xml +++ b/hutool-socket/pom.xml @@ -9,7 +9,7 @@cn.hutool hutool-parent -5.4.5-SNAPSHOT +5.4.6-SNAPSHOT hutool-socket diff --git a/hutool-system/pom.xml b/hutool-system/pom.xml index 8110b4903..b78a89ffe 100644 --- a/hutool-system/pom.xml +++ b/hutool-system/pom.xml @@ -9,7 +9,7 @@cn.hutool hutool-parent -5.4.5-SNAPSHOT +5.4.6-SNAPSHOT hutool-system diff --git a/pom.xml b/pom.xml index 6bebf3683..44246d40a 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@cn.hutool hutool-parent -5.4.5-SNAPSHOT +5.4.6-SNAPSHOT hutool Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。 https://github.com/looly/hutool