mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
add TemporalAccessorSerializer
This commit is contained in:
@@ -125,17 +125,17 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
|
||||
}
|
||||
final Comparator<String> keyComparator = config.getKeyComparator();
|
||||
if (config.isIgnoreCase()) {
|
||||
if(null != keyComparator){
|
||||
if (null != keyComparator) {
|
||||
// 比较器存在情况下,isOrder无效
|
||||
this.rawHashMap = new CaseInsensitiveTreeMap<>(keyComparator);
|
||||
}else{
|
||||
} else {
|
||||
this.rawHashMap = config.isOrder() ? new CaseInsensitiveLinkedMap<>(capacity) : new CaseInsensitiveMap<>(capacity);
|
||||
}
|
||||
} else {
|
||||
if(null != keyComparator){
|
||||
if (null != keyComparator) {
|
||||
// 比较器存在情况下,isOrder无效
|
||||
this.rawHashMap = new TreeMap<>(keyComparator);
|
||||
}else{
|
||||
} else {
|
||||
this.rawHashMap = MapUtil.newHashMap(capacity, config.isOrder());
|
||||
}
|
||||
}
|
||||
@@ -607,7 +607,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
|
||||
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
|
||||
.beginObj();
|
||||
this.forEach((key, value) -> {
|
||||
if (null != filter){
|
||||
if (null != filter) {
|
||||
final MutablePair<String, Object> pair = new MutablePair<>(key, value);
|
||||
if (filter.accept(pair)) {
|
||||
// 使用修改后的键值对
|
||||
|
@@ -1,36 +1,56 @@
|
||||
package cn.hutool.json.serialize;
|
||||
|
||||
import cn.hutool.json.JSON;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import cn.hutool.json.JSON;
|
||||
|
||||
/**
|
||||
* 全局的序列化和反序列化器映射<br>
|
||||
* 在JSON和Java对象转换过程中,优先使用注册于此处的自定义转换
|
||||
*
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public class GlobalSerializeMapping {
|
||||
|
||||
|
||||
private static Map<Type, JSONSerializer<? extends JSON, ?>> serializerMap;
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加入自定义的序列化器
|
||||
*
|
||||
*
|
||||
* @param type 对象类型
|
||||
* @param serializer 序列化器实现
|
||||
*/
|
||||
public static void put(Type type, JSONArraySerializer<?> serializer) {
|
||||
putInternal(type, serializer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 加入自定义的序列化器
|
||||
*
|
||||
*
|
||||
* @param type 对象类型
|
||||
* @param serializer 序列化器实现
|
||||
*/
|
||||
@@ -40,7 +60,7 @@ public class GlobalSerializeMapping {
|
||||
|
||||
/**
|
||||
* 加入自定义的序列化器
|
||||
*
|
||||
*
|
||||
* @param type 对象类型
|
||||
* @param serializer 序列化器实现
|
||||
*/
|
||||
@@ -50,10 +70,10 @@ public class GlobalSerializeMapping {
|
||||
}
|
||||
serializerMap.put(type, serializer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 加入自定义的反序列化器
|
||||
*
|
||||
*
|
||||
* @param type 对象类型
|
||||
* @param deserializer 反序列化器实现
|
||||
*/
|
||||
@@ -63,7 +83,7 @@ public class GlobalSerializeMapping {
|
||||
}
|
||||
deserializerMap.put(type, deserializer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取自定义的序列化器,如果未定义返回{@code null}
|
||||
* @param type 类型
|
||||
@@ -75,7 +95,7 @@ public class GlobalSerializeMapping {
|
||||
}
|
||||
return serializerMap.get(type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取自定义的反序列化器,如果未定义返回{@code null}
|
||||
* @param type 类型
|
||||
|
@@ -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 java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.Month;
|
||||
|
||||
/**
|
||||
@@ -29,6 +31,30 @@ public class Issue2090Test {
|
||||
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
|
||||
public void monthTest(){
|
||||
final JSONObject jsonObject = new JSONObject();
|
||||
|
Reference in New Issue
Block a user