缘起:如何避免在Jackson的反序列化语句中显式使用new TypeReference语句
在Jackson对字符串的反序列化测试中,发现传入的参数new TypeReference<Map<String, Integer>>() {}
使得反序列化得到的map泛型的到了保障
JsonMap<Object> dummy = JsonUtils.createJsonMap(Collections.singletonMap("0", "1"));
String s = dummy.toJSONString();
Map<String, Integer> integerMap = mapper.readValue(s, new TypeReference<Map<String, Integer>>() {
});
// 这里输出的integerMap 是 {"0":1}而不是{"0":"1"}
不难发现,上面这个式子将“1”解析为1,也就是说泛型限制起了作用,jackson底层在反序列化时接受到了在new TypeReference过程中传递的信息。
但是这个过程我们总是要new一个匿名类出来,这无疑增加了许多的代码工作量,于是有了这样的尝试:
public static <T> JsonMap<T> createJsonMap(String jsonStr) throws JsonProcessingException {
return createJsonMap(mapper.readValue(jsonStr, new TypeReference<Map<String, T>>() {
}));
}
public static <T> JsonMap<T> createJsonMap(String jsonStr, Class<T> tClass) throws JsonProcessingException {
return createJsonMap(mapper.readValue(jsonStr, new TypeReference<Map<String, T>>() {
}));
}
不论是试图通过返回值来传T
的信息,还是试图通过传Class<T>
来传递信息,最终这两个实现里T
都会当Object
使用,泛型信息在方法内部丢失,这是擦除导致的。
jackson的 objectmapper的readValue
这个方法里头根本得不到泛型限制信息。同样的问题也存在于自定义序列化器的过程中:
package com.fidt.fate.utils;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
public class JsonMapDeserializer<T> extends JsonDeserializer<JsonMap<T>> {
public static final JsonMapDeserializer INSTANCE = new JsonMapDeserializer();
public JsonMapDeserializer() {
}
@Override
public <T> JsonMap<T> deserialize(JsonParser jsonParser,