mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
add TemporalAccessorSerializer
This commit is contained in:
parent
10f65045e3
commit
4b56b545e7
@ -2,12 +2,13 @@
|
|||||||
# 🚀Changelog
|
# 🚀Changelog
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
# 5.7.22 (2022-02-16)
|
# 5.7.22 (2022-02-17)
|
||||||
|
|
||||||
### 🐣新特性
|
### 🐣新特性
|
||||||
* 【poi 】 ExcelUtil.readBySax增加对POI-5.2.0的兼容性(issue#I4TJF4@gitee)
|
* 【poi 】 ExcelUtil.readBySax增加对POI-5.2.0的兼容性(issue#I4TJF4@gitee)
|
||||||
* 【extra 】 Ftp增加构造(issue#I4TKXP@gitee)
|
* 【extra 】 Ftp增加构造(issue#I4TKXP@gitee)
|
||||||
* 【core 】 GenericBuilder支持Map构建(pr#540@Github)
|
* 【core 】 GenericBuilder支持Map构建(pr#540@Github)
|
||||||
|
* 【json 】 新增TemporalAccessorSerializer
|
||||||
|
|
||||||
### 🐞Bug修复
|
### 🐞Bug修复
|
||||||
* 【cache 】 修复ReentrantCache.toString方法线程不安全问题(issue#2140@Github)
|
* 【cache 】 修复ReentrantCache.toString方法线程不安全问题(issue#2140@Github)
|
||||||
|
@ -3,6 +3,7 @@ package cn.hutool.core.lang;
|
|||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -192,7 +193,7 @@ public class Assert {
|
|||||||
* @since 5.4.5
|
* @since 5.4.5
|
||||||
*/
|
*/
|
||||||
public static <T, X extends Throwable> T notNull(T object, Supplier<X> errorSupplier) throws X {
|
public static <T, X extends Throwable> T notNull(T object, Supplier<X> errorSupplier) throws X {
|
||||||
if (null == object) {
|
if (ObjectUtil.isNull(object)) {
|
||||||
throw errorSupplier.get();
|
throw errorSupplier.get();
|
||||||
}
|
}
|
||||||
return object;
|
return object;
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package cn.hutool.json.serialize;
|
package cn.hutool.json.serialize;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSON;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import cn.hutool.json.JSON;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局的序列化和反序列化器映射<br>
|
* 全局的序列化和反序列化器映射<br>
|
||||||
* 在JSON和Java对象转换过程中,优先使用注册于此处的自定义转换
|
* 在JSON和Java对象转换过程中,优先使用注册于此处的自定义转换
|
||||||
@ -18,6 +21,23 @@ public class GlobalSerializeMapping {
|
|||||||
private static Map<Type, JSONSerializer<? extends JSON, ?>> serializerMap;
|
private static Map<Type, JSONSerializer<? extends JSON, ?>> serializerMap;
|
||||||
private static Map<Type, JSONDeserializer<?>> deserializerMap;
|
private static Map<Type, JSONDeserializer<?>> deserializerMap;
|
||||||
|
|
||||||
|
static {
|
||||||
|
serializerMap = new ConcurrentHashMap<>();
|
||||||
|
deserializerMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
final TemporalAccessorSerializer localDateSerializer = new TemporalAccessorSerializer(LocalDate.class);
|
||||||
|
serializerMap.put(LocalDate.class, localDateSerializer);
|
||||||
|
deserializerMap.put(LocalDate.class, localDateSerializer);
|
||||||
|
|
||||||
|
final TemporalAccessorSerializer localDateTimeSerializer = new TemporalAccessorSerializer(LocalDateTime.class);
|
||||||
|
serializerMap.put(LocalDateTime.class, localDateTimeSerializer);
|
||||||
|
deserializerMap.put(LocalDateTime.class, localDateTimeSerializer);
|
||||||
|
|
||||||
|
final TemporalAccessorSerializer localTimeSerializer = new TemporalAccessorSerializer(LocalTime.class);
|
||||||
|
serializerMap.put(LocalTime.class, localTimeSerializer);
|
||||||
|
deserializerMap.put(LocalTime.class, localTimeSerializer);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加入自定义的序列化器
|
* 加入自定义的序列化器
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
package cn.hutool.json.serialize;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSON;
|
||||||
|
import cn.hutool.json.JSONException;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.time.temporal.TemporalAccessor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link TemporalAccessor}的JSON自定义序列化实现
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
* @since 5.7.22
|
||||||
|
*/
|
||||||
|
public class TemporalAccessorSerializer implements JSONObjectSerializer<TemporalAccessor>, JSONDeserializer<TemporalAccessor> {
|
||||||
|
|
||||||
|
private static final String YEAR_KEY = "year";
|
||||||
|
private static final String MONTH_KEY = "month";
|
||||||
|
private static final String DAY_KEY = "day";
|
||||||
|
private static final String HOUR_KEY = "hour";
|
||||||
|
private static final String MINUTE_KEY = "minute";
|
||||||
|
private static final String SECOND_KEY = "second";
|
||||||
|
private static final String NANO_KEY = "nano";
|
||||||
|
|
||||||
|
private final Class<? extends TemporalAccessor> temporalAccessorClass;
|
||||||
|
|
||||||
|
public TemporalAccessorSerializer(Class<? extends TemporalAccessor> temporalAccessorClass) {
|
||||||
|
this.temporalAccessorClass = temporalAccessorClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(JSONObject json, TemporalAccessor bean) {
|
||||||
|
if (bean instanceof LocalDate) {
|
||||||
|
final LocalDate localDate = (LocalDate) bean;
|
||||||
|
json.set(YEAR_KEY, localDate.getYear());
|
||||||
|
json.set(MONTH_KEY, localDate.getMonthValue());
|
||||||
|
json.set(DAY_KEY, localDate.getDayOfMonth());
|
||||||
|
} else if (bean instanceof LocalDateTime) {
|
||||||
|
final LocalDateTime localDateTime = (LocalDateTime) bean;
|
||||||
|
json.set(YEAR_KEY, localDateTime.getYear());
|
||||||
|
json.set(MONTH_KEY, localDateTime.getMonthValue());
|
||||||
|
json.set(DAY_KEY, localDateTime.getDayOfMonth());
|
||||||
|
json.set(HOUR_KEY, localDateTime.getHour());
|
||||||
|
json.set(MINUTE_KEY, localDateTime.getMinute());
|
||||||
|
json.set(SECOND_KEY, localDateTime.getSecond());
|
||||||
|
json.set(NANO_KEY, localDateTime.getNano());
|
||||||
|
} else if (bean instanceof LocalTime) {
|
||||||
|
final LocalTime localTime = (LocalTime) bean;
|
||||||
|
json.set(HOUR_KEY, localTime.getHour());
|
||||||
|
json.set(MINUTE_KEY, localTime.getMinute());
|
||||||
|
json.set(SECOND_KEY, localTime.getSecond());
|
||||||
|
json.set(NANO_KEY, localTime.getNano());
|
||||||
|
} else {
|
||||||
|
throw new JSONException("Unsupported type to JSON: {}", bean.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TemporalAccessor deserialize(JSON json) {
|
||||||
|
final JSONObject jsonObject = (JSONObject) json;
|
||||||
|
if (LocalDate.class.equals(this.temporalAccessorClass)) {
|
||||||
|
return LocalDate.of(jsonObject.getInt(YEAR_KEY), jsonObject.getInt(MONTH_KEY), jsonObject.getInt(DAY_KEY));
|
||||||
|
} else if (LocalDateTime.class.equals(this.temporalAccessorClass)) {
|
||||||
|
return LocalDateTime.of(jsonObject.getInt(YEAR_KEY), jsonObject.getInt(MONTH_KEY), jsonObject.getInt(DAY_KEY),
|
||||||
|
jsonObject.getInt(HOUR_KEY), jsonObject.getInt(MINUTE_KEY), jsonObject.getInt(SECOND_KEY), jsonObject.getInt(NANO_KEY));
|
||||||
|
} else if (LocalTime.class.equals(this.temporalAccessorClass)) {
|
||||||
|
return LocalTime.of(jsonObject.getInt(HOUR_KEY), jsonObject.getInt(MINUTE_KEY), jsonObject.getInt(SECOND_KEY), jsonObject.getInt(NANO_KEY));
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new JSONException("Unsupported type from JSON: {}", this.temporalAccessorClass);
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,8 @@ import org.junit.Assert;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
import java.time.Month;
|
import java.time.Month;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,6 +31,30 @@ public class Issue2090Test {
|
|||||||
Assert.assertNotNull(jsonObject.toString());
|
Assert.assertNotNull(jsonObject.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toBeanLocalDateTest(){
|
||||||
|
LocalDate d = LocalDate.now();
|
||||||
|
final JSONObject obj = JSONUtil.parseObj(d);
|
||||||
|
LocalDate d2 = obj.toBean(LocalDate.class);
|
||||||
|
Assert.assertEquals(d, d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toBeanLocalDateTimeTest(){
|
||||||
|
LocalDateTime d = LocalDateTime.now();
|
||||||
|
final JSONObject obj = JSONUtil.parseObj(d);
|
||||||
|
LocalDateTime d2 = obj.toBean(LocalDateTime.class);
|
||||||
|
Assert.assertEquals(d, d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toBeanLocalTimeTest(){
|
||||||
|
LocalTime d = LocalTime.now();
|
||||||
|
final JSONObject obj = JSONUtil.parseObj(d);
|
||||||
|
LocalTime d2 = obj.toBean(LocalTime.class);
|
||||||
|
Assert.assertEquals(d, d2);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void monthTest(){
|
public void monthTest(){
|
||||||
final JSONObject jsonObject = new JSONObject();
|
final JSONObject jsonObject = new JSONObject();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user