Skip to content

Commit

Permalink
fix: 修复jsonCodec无法解析多层嵌套泛型问题
Browse files Browse the repository at this point in the history
  • Loading branch information
zhou-hao committed Dec 19, 2024
1 parent 1499eda commit 3bd056c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.ByteBufferBackedInputStream;
import lombok.Setter;
import lombok.SneakyThrows;
Expand Down Expand Up @@ -34,9 +35,9 @@ public class JsonValueCodec implements ValueCodec<Object, Object> {

static {
defaultMapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL)
.setTimeZone(TimeZone.getDefault());
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL)
.setTimeZone(TimeZone.getDefault());
}

private final JavaType jacksonType;
Expand All @@ -51,48 +52,44 @@ public static JsonValueCodec of(Class<?> targetType) {
}

public static JsonValueCodec ofCollection(Class<? extends Collection> targetType
, Class<?> elementType) {
, Class<?> elementType) {
return new JsonValueCodec(targetType, defaultMapper
.getTypeFactory()
.constructCollectionType(targetType, elementType));
.getTypeFactory()
.constructCollectionType(targetType, elementType));
}

public static JsonValueCodec ofMap(Class<? extends Map> targetType, Class<?> keyType, Class<?> valueType) {
return new JsonValueCodec(targetType, defaultMapper.getTypeFactory()
.constructMapType(targetType, keyType, valueType));
}

@SuppressWarnings("all")
public static JsonValueCodec ofField(Field field) {
Class type = field.getType();
Class targetType = type;
Type genericType = field.getGenericType();
JavaType jacksonType = null;

if (type == Mono.class || type == Flux.class) {
targetType = (Class) ((ParameterizedType) genericType).getActualTypeArguments()[0];
targetType = (Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[0];
}
TypeFactory factory = defaultMapper.getTypeFactory();
if (Map.class.isAssignableFrom(targetType)) {
if (genericType instanceof ParameterizedType) {
Type[] types = ((ParameterizedType) genericType).getActualTypeArguments();
jacksonType = defaultMapper
.getTypeFactory()
.constructMapType(targetType, (Class) types[0], (Class) types[1]);
jacksonType = factory.constructMapType(targetType, factory.constructType(types[0]), factory.constructType(types[1]));
}

} else if (Collection.class.isAssignableFrom(targetType)) {
if (genericType instanceof ParameterizedType) {
Type[] types = ((ParameterizedType) genericType).getActualTypeArguments();
jacksonType = defaultMapper
.getTypeFactory()
.constructCollectionType(targetType, (Class) types[0]);
jacksonType = factory.constructCollectionType(targetType, factory.constructType(types[0]));
}
} else if (targetType.isArray()) {
jacksonType = defaultMapper
.getTypeFactory()
.constructArrayType(targetType.getComponentType());
jacksonType = factory.constructArrayType(targetType.getComponentType());
}
if (jacksonType == null) {
jacksonType = defaultMapper.getTypeFactory().constructType(targetType);
jacksonType = factory.constructType(targetType);
}

return new JsonValueCodec(type, jacksonType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void testList() {

Assert.assertTrue(arr instanceof List);

Assert.assertEquals(((List) arr).size(), 2);
Assert.assertEquals(2, ((List) arr).size());

}

Expand All @@ -44,7 +44,7 @@ public void testByteBuffer() {

Assert.assertTrue(arr instanceof Set);

Assert.assertEquals(((Set) arr).size(), 2);
Assert.assertEquals(2, ((Set) arr).size());

}

Expand Down Expand Up @@ -76,6 +76,23 @@ public void testMap() {
Assert.assertEquals(val.get("b"), Integer.valueOf(2));
}

@Test
@SneakyThrows
public void testMapField() {
JsonValueCodec codec = JsonValueCodec.ofField(JsonCodecEntity.class.getDeclaredField("nestMap"));

Object arr = codec.decode("{\"name\":{ \"key\":\"1\" }}");
System.out.println(arr);
Assert.assertTrue(arr instanceof Map);
Map<String, Map<String,Integer>> val = ((Map) arr);

Map<String,Integer> vls = val.get("name");
assertNotNull(vls);

assertEquals((Object) 1, vls.get("key"));

}

@Test
public void testEntity() {
JsonValueCodec codec = JsonValueCodec.of(JsonCodecEntity.class);
Expand Down Expand Up @@ -226,6 +243,8 @@ public static class JsonCodecEntity {

private Flux<JsonCodecEntity> flux;

private Map<String, Map<String, Integer>> nestMap;

}

}

0 comments on commit 3bd056c

Please sign in to comment.