Java中JSON字符串反序列化(动态泛型)
作者:废物大师兄
文章讨论了在定时任务中使用反射调用目标对象时处理动态参数的问题,通过将方法参数存储为JSON字符串并进行反序列化,可以实现动态调用,然而,这种方式容易导致内存溢出(OOM),这篇文章主要介绍了JSON字符串反序列化 动态泛型,需要的朋友可以参考下
需求:定时任务扫描,反射调用目标对象,但是,方法的传参不是固定的。
方案一:将方法参数存成JSON字符串,然后JSON反序列化成对象,然后反射调用
目标方法时这样的:
CommandResp sendXXX(BaseCommandApiDTO<XXX> baseCommandApiDTO);
方式一:FastJson
Class mainBody = Class.forName(entity.getMainBodyType()); ParameterizedTypeImpl parameterizedType = new ParameterizedTypeImpl(new Type[]{mainBody}, null, BaseCommandApiDTO.class); Object obj = JSON.parseObject(entity.getMsgText(), parameterizedType); CommandResp resp = ReflectUtil.invoke(serviceObj, methodName, obj);
方式二:Jackson
public class ObjectMapperHolder { private static final ObjectMapper objectMapper = new ObjectMapper(); public static ObjectMapper getObjectMapper() { objectMapper.registerModule(new Jdk8Module()); objectMapper.registerModule(new JavaTimeModule()); return objectMapper; } } ObjectMapper mapper = ObjectMapperHolder.getObjectMapper(); JavaType javaType = mapper.getTypeFactory().constructParametricType(BaseCommandApiDTO.class, mainBody); Object obj = mapper.readValue(entity.getMsgText(), javaType); CommandResp resp = ReflectUtil.invoke(serviceObj, methodName, obj);
实践中发现,这两种方式容易导致OOM
方案二:直接将参数对象存到数据库中
数据库对应字段设置BLOB类型(这里设置的是MEDIUMBLOB) ,对应的java字段类型是byte[]
// 写入对象 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(baseCommandApiDTO); oos.flush(); byte[] data = bos.toByteArray(); // 读取对象 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(entity.getMsgObj())); Object obj = ois.readObject();
最后的最后,优化建议:
1、尽量不要在数据库中存json字符串,如果非要存,建议字段类型设置为json,这样可以节省空间。因为你无法控制json字符串的长度,所以长度设置是个问题,另外json反序列化比较占内存。
2、长度很大的字段(比如blob类型的)建议单独存一张关联表
到此这篇关于JSON字符串反序列化 动态泛型的文章就介绍到这了,更多相关JSON字符串反序列化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!