一、问题描述
最近开发业务中遇到一个有趣的问题,我本来是想提取一个公共的抽象类,完成从redis缓存中获取到json后进行反序列化成继承类的泛型对象,这个泛型类是List,在反序列化时,list类型是正常的,但是list里的对象却不正确。
原本实现:
@Test
public void run1(){
var userService = new UserService();
var json = """
[
{"name":"张三","age":12},
{"name":"李四","age":17}
]
""";
List<User> users = userService.json2Pojo(json);
User user = users.get(0); // 这里会报错,因为类型不匹配,集合中的对象类型是LinkedHashMap
System.out.println(users);
}
//实现类
class UserService extends AbstractService<List<User>>{
}
//抽象类
abstract class AbstractService<T>{
public final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
public T json2Pojo(String json){
try {
return OBJECT_MAPPER.readValue(json, new TypeReference<T>() {
});
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
//对象
@Data
static class User{
private String name;
private Integer age;
}
测试代码中的反序列化集合users返回结构是:
注意这里的类型原本应该是User,但是却变为了LinkedHashMap
这里我使用的json工具是jackson,以为是因为这个框架不支持导致的泛型丢失,然后尝试使用Gson,结果也是一样的。
二、解决方案
1、json反序列化交给实现类完成
这是下下策,因为已经提取抽象类了,我们就是要减少实现类的开发,虽然这样没有太多的开发代码,但是总归感觉别扭,不建议这样实现
2、通过spring工具获取泛型类型,然后反序列化
abstract class AbstractService<T>{
public final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
// 通过spring工具获取泛型类型
private final JavaType JAVA_TYPE = TypeFactory
.defaultInstance()
.constructType(ResolvableType.forClass(this.getClass()).getSuperType().getGeneric(0).getType());
public T json2Pojo(String json){
try {
Object o = OBJECT_MAPPER.readValue(json, JAVA_TYPE);
return (T) o;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
这里users集合中的对象已经是User对象了
版权声明:本文为weixin_33613947原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。