Browse Source

add alias

Looly 6 years ago
parent
commit
377cd55a3c

+ 4 - 0
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修复
 
 -------------------------------------------------------------------------------------------------------------

+ 20 - 0
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();
+}

+ 13 - 17
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;
-
 /**
  * 注解工具类<br>
  * 快速获取注解对象、注解值等工具封装
@@ -116,19 +115,16 @@ public class AnnotationUtil {
 			return null;
 		}
 
-		final Method[] methods = ReflectUtil.getMethods(annotationType, new Filter<Method>() {
-			@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<String, Object> result = new HashMap<>(methods.length, 1);

+ 11 - 0
hutool-core/src/main/java/cn/hutool/core/convert/Convert.java

@@ -137,6 +137,17 @@ public class Convert {
 	}
 
 	/**
+	 * 转换为Byte数组
+	 *
+	 * @param value 被转换的值
+	 * @return Byte数组
+	 * @since 5.1.1
+	 */
+	public static byte[] toPrimitiveByteArray(Object value) {
+		return convert(byte[].class, value);
+	}
+
+	/**
 	 * 转换为Short<br>
 	 * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
 	 * 转换失败不会报错

+ 5 - 5
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;
 	}

+ 10 - 5
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<Object> {
 			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);

+ 4 - 0
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<T> extends AbstractConverter<T> {
 
 			//限定被转换对象类型
 			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;
 	}

+ 31 - 12
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);
+	}
+
+	/**
+	 * 判定在指定检查时间是否过期。
+	 *
+	 * <p>
+	 * 以商品为例,startDate即生产日期,endDate即保质期的截止日期,checkDate表示在何时检查是否过期(一般为当前时间)<br>
+	 * endDate和startDate的差值即为保质期(按照毫秒计),checkDate和startDate的差值即为实际经过的时长,实际时长大于保质期表示超时。
+	 * </p>
+	 *
+	 * @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
+
 	/**
 	 * 获得指定日期年份和季节<br>
 	 * 格式:[20131]表示2013年第一季度

+ 10 - 11
hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java

@@ -1,5 +1,15 @@
 package cn.hutool.core.util;
 
+import cn.hutool.core.convert.BasicType;
+import cn.hutool.core.exceptions.UtilException;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IORuntimeException;
+import cn.hutool.core.io.resource.ResourceUtil;
+import cn.hutool.core.lang.Assert;
+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;
@@ -8,7 +18,6 @@ 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;
@@ -17,16 +26,6 @@ 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;
-import cn.hutool.core.io.IORuntimeException;
-import cn.hutool.core.io.resource.ResourceUtil;
-import cn.hutool.core.lang.Assert;
-import cn.hutool.core.lang.ClassScanner;
-import cn.hutool.core.lang.Filter;
-import cn.hutool.core.lang.Singleton;
-
 /**
  * 类工具类 <br>
  *

+ 13 - 11
hutool-core/src/main/java/cn/hutool/core/util/ObjectUtil.java

@@ -377,10 +377,17 @@ public class ObjectUtil {
 	 * @param <T>   对象类型
 	 * @param bytes 反序列化的字节码
 	 * @return 反序列化后的对象
-	 * @see #unserialize(byte[])
 	 */
+	@SuppressWarnings("unchecked")
 	public static <T> 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 <T>   对象类型
 	 * @param bytes 反序列化的字节码
 	 * @return 反序列化后的对象
+	 * @see #deserialize(byte[])
+	 * @deprecated 请使用 {@link #deserialize(byte[])}
 	 */
-	@SuppressWarnings("unchecked")
+	@Deprecated
 	public static <T> 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);
 	}
 
 	/**

+ 28 - 3
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;
+	}
 }

+ 0 - 1
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;
 

+ 1 - 0
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;