写点什么

JSON 字符串反序列化 动态泛型

作者:EquatorCoco
  • 2024-12-30
    福建
  • 本文字数:1015 字

    阅读完需:约 3 分钟

需求:定时任务扫描,反射调用目标对象,但是,方法的传参不是固定的。


方案一:将方法参数存成 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 类型的)建议单独存一张关联表


文章转载自:废物大师兄

原文链接:https://www.cnblogs.com/cjsblog/p/18460884

体验地址:http://www.jnpfsoft.com/?from=infoq

用户头像

EquatorCoco

关注

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
JSON字符串反序列化 动态泛型_json_EquatorCoco_InfoQ写作社区