From 377cd55a3ca5a6c1311401105ce5839d4bf37ddb Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 26 Dec 2019 08:01:57 +0800 Subject: [PATCH] add alias --- CHANGELOG.md | 4 ++ .../java/cn/hutool/core/annotation/Alias.java | 20 +++++++++ .../core/annotation/AnnotationUtil.java | 30 ++++++------- .../java/cn/hutool/core/convert/Convert.java | 11 +++++ .../core/convert/ConverterRegistry.java | 10 ++--- .../core/convert/impl/ArrayConverter.java | 15 ++++--- .../core/convert/impl/BeanConverter.java | 4 ++ .../java/cn/hutool/core/date/DateUtil.java | 43 +++++++++++++------ .../java/cn/hutool/core/util/ClassUtil.java | 33 +++++++------- .../java/cn/hutool/core/util/ObjectUtil.java | 24 ++++++----- .../cn/hutool/core/convert/ConvertTest.java | 31 +++++++++++-- .../cn/hutool/core/date/DateUtilTest.java | 1 - .../cn/hutool/poi/excel/sax/ExcelSaxUtil.java | 1 + 13 files changed, 156 insertions(+), 71 deletions(-) create mode 100644 hutool-core/src/main/java/cn/hutool/core/annotation/Alias.java diff --git a/CHANGELOG.md b/CHANGELOG.md index df45b8fe4..81c7e26d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ ### 新特性 * 【core 】 ClassUtil.isSimpleValueType增加TemporalAccessor支持(issue#I170HK@Gitee) +* 【core 】 增加Convert.toPrimitiveByteArray方法,Convert支持对象序列化和反序列化 +* 【core 】 DateUtil增加isExpired(Date startDate, Date endDate, Date checkDate)(issue#687@Github) +* 【core 】 增加Alias注解 + ### Bug修复 ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/Alias.java b/hutool-core/src/main/java/cn/hutool/core/annotation/Alias.java new file mode 100644 index 000000000..9c98d8efa --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/Alias.java @@ -0,0 +1,20 @@ +package cn.hutool.core.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 别名注解,使用此注解的字段、方法、参数等会有一个别名,用于Bean拷贝、Bean转Map等 + * + * @author Looly + * @since 5.1.1 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) +public @interface Alias { + String value(); +} diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java index dc6903d1f..71b7b17b9 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java @@ -1,5 +1,9 @@ package cn.hutool.core.annotation; +import cn.hutool.core.exceptions.UtilException; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.ReflectUtil; + import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -13,11 +17,6 @@ import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; -import cn.hutool.core.exceptions.UtilException; -import cn.hutool.core.lang.Filter; -import cn.hutool.core.util.ArrayUtil; -import cn.hutool.core.util.ReflectUtil; - /** * 注解工具类
* 快速获取注解对象、注解值等工具封装 @@ -116,19 +115,16 @@ public class AnnotationUtil { return null; } - final Method[] methods = ReflectUtil.getMethods(annotationType, new Filter() { - @Override - public boolean accept(Method t) { - if (ArrayUtil.isEmpty(t.getParameterTypes())) { - // 只读取无参方法 - final String name = t.getName(); - // 跳过自有的几个方法 - return (false == "hashCode".equals(name)) // - && (false == "toString".equals(name)) // - && (false == "annotationType".equals(name)); - } - return false; + final Method[] methods = ReflectUtil.getMethods(annotationType, t -> { + if (ArrayUtil.isEmpty(t.getParameterTypes())) { + // 只读取无参方法 + final String name = t.getName(); + // 跳过自有的几个方法 + return (false == "hashCode".equals(name)) // + && (false == "toString".equals(name)) // + && (false == "annotationType".equals(name)); } + return false; }); final HashMap result = new HashMap<>(methods.length, 1); diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java b/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java index c13a2b4d2..53e8e0e13 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java @@ -136,6 +136,17 @@ public class Convert { return convert(Byte[].class, value); } + /** + * 转换为Byte数组 + * + * @param value 被转换的值 + * @return Byte数组 + * @since 5.1.1 + */ + public static byte[] toPrimitiveByteArray(Object value) { + return convert(byte[].class, value); + } + /** * 转换为Short
* 如果给定的值为null,或者转换失败,返回默认值
diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java b/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java index ced7c3198..7869a3741 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java @@ -317,6 +317,11 @@ public class ConverterRegistry implements Serializable{ return (T) value; } + // 枚举转换 + if (rowType.isEnum()) { + return (T) new EnumConverter(rowType).convert(value, defaultValue); + } + // 数组转换 if (rowType.isArray()) { final ArrayConverter arrayConverter = new ArrayConverter(rowType); @@ -327,11 +332,6 @@ public class ConverterRegistry implements Serializable{ } } - // 枚举转换 - if (rowType.isEnum()) { - return (T) new EnumConverter(rowType).convert(value, defaultValue); - } - // 表示非需要特殊转换的对象 return null; } diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/ArrayConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/ArrayConverter.java index 8ba476359..533b95bb9 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/ArrayConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/ArrayConverter.java @@ -1,16 +1,18 @@ package cn.hutool.core.convert.impl; -import java.lang.reflect.Array; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - import cn.hutool.core.collection.IterUtil; import cn.hutool.core.convert.AbstractConverter; import cn.hutool.core.convert.ConverterRegistry; import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import java.io.Serializable; +import java.lang.reflect.Array; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + /** * 数组转换器,包括原始类型数组 * @@ -129,6 +131,9 @@ public class ArrayConverter extends AbstractConverter { for (int i = 0; i < list.size(); i++) { Array.set(result, i, converter.convert(targetComponentType, list.get(i))); } + }else if (value instanceof Serializable && byte.class == targetComponentType) { + // 用户可能想序列化指定对象 + result = ObjectUtil.serialize(value); } else { // everything else: result = convertToSingleElementArray(value); diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/BeanConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/BeanConverter.java index 8e1179866..cb78ec6e4 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/BeanConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/BeanConverter.java @@ -6,6 +6,7 @@ import cn.hutool.core.bean.copier.CopyOptions; import cn.hutool.core.bean.copier.ValueProvider; import cn.hutool.core.convert.AbstractConverter; import cn.hutool.core.map.MapProxy; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.TypeUtil; @@ -72,6 +73,9 @@ public class BeanConverter extends AbstractConverter { //限定被转换对象类型 return BeanCopier.create(value, ReflectUtil.newInstanceIfPossible(this.beanClass), this.beanType, this.copyOptions).copy(); + } else if(value instanceof byte[]){ + // 尝试反序列化 + return ObjectUtil.deserialize((byte[])value); } return null; } 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 3146d3bf1..f9a907083 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java @@ -527,9 +527,9 @@ public class DateUtil { } final SimpleDateFormat sdf = new SimpleDateFormat(format); - if(date instanceof DateTime){ + if (date instanceof DateTime) { final TimeZone timeZone = ((DateTime) date).getTimeZone(); - if(null != timeZone) { + if (null != timeZone) { sdf.setTimeZone(timeZone); } } @@ -1774,16 +1774,34 @@ public class DateUtil { /** * 判定给定开始时间经过某段时间后是否过期 * - * @param startDate 开始时间 - * @param dateField 时间单位 - * @param timeLength 时长 - * @param checkedDate 被比较的时间,即有效期的截止时间。如果经过时长后的时间晚于被检查的时间,就表示过期 + * @param startDate 开始时间 + * @param dateField 时间单位 + * @param timeLength 经过时长 + * @param endDate 被比较的时间,即有效期的截止时间。如果经过时长后的时间晚于截止时间,就表示过期 * @return 是否过期 * @since 3.1.1 */ - public static boolean isExpired(Date startDate, DateField dateField, int timeLength, Date checkedDate) { - final Date endDate = offset(startDate, dateField, timeLength); - return endDate.after(checkedDate); + public static boolean isExpired(Date startDate, DateField dateField, int timeLength, Date endDate) { + final Date offsetDate = offset(startDate, dateField, timeLength); + return offsetDate.after(endDate); + } + + /** + * 判定在指定检查时间是否过期。 + * + *

+ * 以商品为例,startDate即生产日期,endDate即保质期的截止日期,checkDate表示在何时检查是否过期(一般为当前时间)
+ * endDate和startDate的差值即为保质期(按照毫秒计),checkDate和startDate的差值即为实际经过的时长,实际时长大于保质期表示超时。 + *

+ * + * @param startDate 开始时间 + * @param endDate 被比较的时间,即有效期的截止时间。如果经过时长后的时间晚于被检查的时间,就表示过期 + * @param checkDate 检查时间,可以是当前时间,既 + * @return 是否过期 + * @since 5.1.1 + */ + public static boolean isExpired(Date startDate, Date endDate, Date checkDate) { + return betweenMs(startDate, checkDate) > betweenMs(startDate, checkDate); } /** @@ -2034,7 +2052,7 @@ public class DateUtil { * @return {@link LocalDateTime} * @since 5.0.5 */ - public static LocalDateTime toLocalDateTime(Instant instant){ + public static LocalDateTime toLocalDateTime(Instant instant) { return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); } @@ -2045,7 +2063,7 @@ public class DateUtil { * @return {@link LocalDateTime} * @since 5.0.5 */ - public static LocalDateTime toLocalDateTime(Calendar calendar){ + public static LocalDateTime toLocalDateTime(Calendar calendar) { return LocalDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId()); } @@ -2056,12 +2074,13 @@ public class DateUtil { * @return {@link LocalDateTime} * @since 5.0.5 */ - public static LocalDateTime toLocalDateTime(Date date){ + public static LocalDateTime toLocalDateTime(Date date) { final DateTime dateTime = date(date); return LocalDateTime.ofInstant(dateTime.toInstant(), dateTime.getZoneId()); } // ------------------------------------------------------------------------ Private method start + /** * 获得指定日期年份和季节
* 格式:[20131]表示2013年第一季度 diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java index 24b9ed729..44033780b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java @@ -1,22 +1,5 @@ package cn.hutool.core.util; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.Type; -import java.net.URI; -import java.net.URL; -import java.time.LocalDateTime; -import java.time.temporal.TemporalAccessor; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; - import cn.hutool.core.convert.BasicType; import cn.hutool.core.exceptions.UtilException; import cn.hutool.core.io.FileUtil; @@ -27,6 +10,22 @@ import cn.hutool.core.lang.ClassScanner; import cn.hutool.core.lang.Filter; import cn.hutool.core.lang.Singleton; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; +import java.net.URI; +import java.net.URL; +import java.time.temporal.TemporalAccessor; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; + /** * 类工具类
* diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ObjectUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ObjectUtil.java index aafd0b7a5..71edcedb9 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/ObjectUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ObjectUtil.java @@ -377,10 +377,17 @@ public class ObjectUtil { * @param 对象类型 * @param bytes 反序列化的字节码 * @return 反序列化后的对象 - * @see #unserialize(byte[]) */ + @SuppressWarnings("unchecked") public static T deserialize(byte[] bytes) { - return unserialize(bytes); + ObjectInputStream ois; + try { + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + ois = new ObjectInputStream(bais); + return (T) ois.readObject(); + } catch (Exception e) { + throw new UtilException(e); + } } /** @@ -390,17 +397,12 @@ public class ObjectUtil { * @param 对象类型 * @param bytes 反序列化的字节码 * @return 反序列化后的对象 + * @see #deserialize(byte[]) + * @deprecated 请使用 {@link #deserialize(byte[])} */ - @SuppressWarnings("unchecked") + @Deprecated public static T unserialize(byte[] bytes) { - ObjectInputStream ois; - try { - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - ois = new ObjectInputStream(bais); - return (T) ois.readObject(); - } catch (Exception e) { - throw new UtilException(e); - } + return deserialize(bytes); } /** 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 23f8edb8f..52d063af0 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 @@ -1,15 +1,18 @@ package cn.hutool.core.convert; +import lombok.AllArgsConstructor; +import lombok.Data; import org.junit.Assert; import org.junit.Test; +import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * 类型转换工具单元测试 - * + * * @author Looly * */ @@ -25,7 +28,7 @@ public class ConvertTest { public void toStrTest() { int a = 1; long[] b = { 1, 2, 3, 4, 5 }; - + Assert.assertEquals("[1, 2, 3, 4, 5]", Convert.convert(String.class, b)); String aStr = Convert.toStr(a); @@ -33,7 +36,7 @@ public class ConvertTest { String bStr = Convert.toStr(b); Assert.assertEquals("[1, 2, 3, 4, 5]", Convert.toStr(bStr)); } - + @Test public void toStrTest2() { String result = Convert.convert(String.class, "aaaa"); @@ -206,4 +209,26 @@ public class ConvertTest { Assert.assertEquals(1, list3.get(0).intValue()); Assert.assertEquals(2, list3.get(1).intValue()); } + + @Test + public void toByteArrayTest(){ + // 测试Serializable转换为bytes,调用序列化转换 + final byte[] bytes = Convert.toPrimitiveByteArray(new Product("zhangsan", "张三", "5.1.1")); + Assert.assertNotNull(bytes); + + final Product product = Convert.convert(Product.class, bytes); + Assert.assertEquals("zhangsan", product.getName()); + Assert.assertEquals("张三", product.getCName()); + Assert.assertEquals("5.1.1", product.getVersion()); + } + + @Data + @AllArgsConstructor + public static class Product implements Serializable { + private static final long serialVersionUID = 1L; + + private String name; + private String cName; + private String version; + } } 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 34f2d2cfc..d3cfe146e 100644 --- a/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java @@ -2,7 +2,6 @@ package cn.hutool.core.date; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.BetweenFormater.Level; -import cn.hutool.core.lang.Console; import org.junit.Assert; import org.junit.Test; diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxUtil.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxUtil.java index 5c4a40e05..fa47acac7 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxUtil.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxUtil.java @@ -56,6 +56,7 @@ public class ExcelSaxUtil { case SSTINDEX: try { final int index = Integer.parseInt(value); + //noinspection deprecation result = new XSSFRichTextString(sharedStringsTable.getEntryAt(index)).getString(); } catch (NumberFormatException e) { result = value;