Skip to content

Commit

Permalink
improved LocalDateTime format support, for issue #2093
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Dec 23, 2023
1 parent 4710721 commit df6f605
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 7 deletions.
6 changes: 6 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/JSONWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.alibaba.fastjson2.util.TypeUtils;
import com.alibaba.fastjson2.writer.FieldWriter;
import com.alibaba.fastjson2.writer.ObjectWriter;
import com.alibaba.fastjson2.writer.ObjectWriterImplMap;
import com.alibaba.fastjson2.writer.ObjectWriterProvider;

import java.io.*;
Expand Down Expand Up @@ -496,6 +497,11 @@ public final ObjectWriter getObjectWriter(Class objectClass) {
return context.provider.getObjectWriter(objectClass, objectClass, fieldBased);
}

public final ObjectWriter getObjectWriter(Class objectClass, String format) {
boolean fieldBased = (context.features & FieldBased.mask) != 0;
return context.provider.getObjectWriter(objectClass, objectClass, format, fieldBased);
}

public final ObjectWriter getObjectWriter(Type objectType, Class objectClass) {
boolean fieldBased = (context.features & FieldBased.mask) != 0;
return context.provider.getObjectWriter(objectType, objectClass, fieldBased);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ static ObjectWriter getObjectWriter(
) {
if (Map.class.isAssignableFrom(valueClass)) {
if (fieldClass.isAssignableFrom(valueClass)) {
return ObjectWriterImplMap.of(fieldType, valueClass);
return ObjectWriterImplMap.of(fieldType, format, valueClass);
} else {
return ObjectWriterImplMap.of(valueClass);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ final class ObjectWriterImplLocalDateTime
implements ObjectWriter {
static final ObjectWriterImplLocalDateTime INSTANCE = new ObjectWriterImplLocalDateTime(null, null);

static ObjectWriterImplLocalDateTime of(String format, Locale locale) {
return new ObjectWriterImplLocalDateTime(format, locale);
}

public ObjectWriterImplLocalDateTime(String format, Locale locale) {
super(format, locale);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public final class ObjectWriterImplMap

final Type keyType;
final Type valueType;
final String format;
final boolean valueTypeRefDetect;
volatile ObjectWriter keyWriter;
volatile ObjectWriter valueWriter;
Expand All @@ -58,8 +59,13 @@ public ObjectWriterImplMap(Class objectClass, long features) {
}

public ObjectWriterImplMap(Type keyType, Type valueType, Class objectClass, Type objectType, long features) {
this(keyType, valueType, null, objectClass, objectType, features);
}

public ObjectWriterImplMap(Type keyType, Type valueType, String format, Class objectClass, Type objectType, long features) {
this.keyType = keyType;
this.valueType = valueType;
this.format = format;
this.objectClass = objectClass;
this.objectType = objectType;
this.features = features;
Expand Down Expand Up @@ -109,6 +115,10 @@ public static ObjectWriterImplMap of(Type type) {
}

public static ObjectWriterImplMap of(Type type, Class defineClass) {
return of(type, null, defineClass);
}

public static ObjectWriterImplMap of(Type type, String format, Class defineClass) {
Type keyType = null, valueType = null;

if (type instanceof ParameterizedType) {
Expand All @@ -121,7 +131,7 @@ public static ObjectWriterImplMap of(Type type, Class defineClass) {
}
}

return new ObjectWriterImplMap(keyType, valueType, defineClass, type, 0);
return new ObjectWriterImplMap(keyType, valueType, format, defineClass, type, 0);
}

@Override
Expand Down Expand Up @@ -508,7 +518,9 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f
if (this.valueWriter != null) {
valueWriter = this.valueWriter;
} else {
valueWriter = this.valueWriter = jsonWriter.getObjectWriter(valueClass);
valueWriter = this.valueWriter = format != null
? jsonWriter.getObjectWriter(valueClass, format)
: jsonWriter.getObjectWriter(valueClass);
}
isPrimitiveOrEnum = ObjectWriterProvider.isPrimitiveOrEnum(value.getClass());
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,16 @@ public ObjectWriter getObjectWriterFromCache(Type objectType, Class objectClass,
: cache.get(objectType);
}

public ObjectWriter getObjectWriter(Type objectType, Class objectClass, String format, boolean fieldBased) {
ObjectWriter objectWriter = getObjectWriter(objectType, objectClass, fieldBased);
if (format != null) {
if (objectType == LocalDateTime.class && objectWriter == ObjectWriterImplLocalDateTime.INSTANCE) {
return ObjectWriterImplLocalDateTime.of(format, null);
}
}
return objectWriter;
}

public ObjectWriter getObjectWriter(Type objectType, Class objectClass, boolean fieldBased) {
ObjectWriter objectWriter = fieldBased
? cacheFieldBased.get(objectType)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.alibaba.fastjson2.issues_2000;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Issue2093 {
@Test
public void test() {
LocalDateTime ldt = LocalDateTime.of(2017, 7, 6, 12, 13, 14);
Bean bean = new Bean();
bean.times = new ArrayList<>();
bean.times.add(ldt);
bean.timeMap = new HashMap<>();
bean.timeMap.put("time", ldt);

String str = JSON.toJSONString(bean);
assertEquals("{\"timeMap\":{\"time\":\"12:13:14\"},\"times\":[\"12:13:14\"]}", str);
}

@Data
public static class Bean {
@JSONField(format = "HH:mm:ss")
private List<LocalDateTime> times;

@JSONField(format = "HH:mm:ss")
private Map<String, LocalDateTime> timeMap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,38 @@
import lombok.Data;
import org.junit.jupiter.api.Test;

import java.util.Map;
import java.util.SortedMap;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Issue2094 {
@Test
public void test() {
String str = "{\"items\":{1:{\"id\":123}}}";
String str = "{\"items\":{1:{\"config\":{2:{\"id\":123}}}}}";
Bean bean = JSON.parseObject(str, Bean.class);
assertEquals(1, bean.items.size());
assertEquals(123, bean.items.get(1).id);
assertEquals(123, bean.items.get(1).getConfig().get(2).id);
}

@Data
public static class Bean {
private SortedMap<Integer, Item> items;
private Map<Integer, XXXConfig> items;
}

public static class Item {
public static class XXXConfig {
private SortedMap<Integer, AckSampleConfig> config;

public SortedMap<Integer, AckSampleConfig> getConfig() {
return config;
}

public void setConfig(SortedMap<Integer, AckSampleConfig> config) {
this.config = config;
}
}

public static class AckSampleConfig {
public int id;
}
}

0 comments on commit df6f605

Please sign in to comment.