如何通过全限定类名动态反序列化JSON并调用Bean的save方法?
问题解决:动态反序列化Bean并调用save方法
需求背景
- 开发者需编写包含
save()方法的Bean类,示例代码如下:
class BeanA{ int id; String appName; public void save() {} } class BeanB{ int id; String userName; public void save() {} }
- 存在
orchestration.csv文件,存储类全限定名与数据URL的映射关系:
org.example.BeanA, http://fetch/bean/a/from/this/url org.example.BeanB, http://fetch/bean/b/from/this/url org.example.BeanC, http://fetch/bean/c/from/this/url
- 平台服务需从CSV指定的URL获取JSON数据,反序列化为对应类的实例,并调用其
save()方法。
现有问题
现有伪代码中,使用Class.forName(className)反序列化时出现编译错误,且无法直接调用save()方法:
ObjectMapper objectMapper = new ObjectMapper(); for (className, URL in CSV) { String json = getObject(url); // 问题点:反序列化报错,且无法直接调用save方法 objectMapper.readValue(json, Class.forName(className)); }
解决办法
方案1:通过统一接口约束Bean类(推荐)
先定义一个包含save()方法的接口,让所有Bean类实现该接口,以此实现类型约束:
public interface Savable { void save(); }
修改Bean类实现该接口:
class BeanA implements Savable { int id; String appName; @Override public void save() { // 自定义保存逻辑 } } class BeanB implements Savable { int id; String userName; @Override public void save() { // 自定义保存逻辑 } }
之后在反序列化时,将加载的类强制转换为Savable类型,即可直接调用save()方法:
ObjectMapper objectMapper = new ObjectMapper(); // 遍历CSV每行数据(需自行实现CSV读取逻辑) for (String line : readCsvLines("orchestration.csv")) { String[] parts = line.split(","); String className = parts[0].trim(); String url = parts[1].trim(); String json = getObject(url); try { // 加载类并转换为Savable类型 Class<Savable> beanClass = (Class<Savable>) Class.forName(className); // 反序列化得到Bean实例 Savable bean = objectMapper.readValue(json, beanClass); // 调用save方法 bean.save(); } catch (ClassNotFoundException e) { // 处理类未找到异常,如日志记录 e.printStackTrace(); } catch (JsonProcessingException e) { // 处理JSON反序列化异常 e.printStackTrace(); } }
方案2:通过反射调用save方法(无需修改Bean类)
如果无法修改现有Bean类实现统一接口,可通过反射直接调用save()方法:
import java.lang.reflect.Method; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; ObjectMapper objectMapper = new ObjectMapper(); for (String line : readCsvLines("orchestration.csv")) { String[] parts = line.split(","); String className = parts[0].trim(); String url = parts[1].trim(); String json = getObject(url); try { Class<?> beanClass = Class.forName(className); // 反序列化得到Bean实例 Object bean = objectMapper.readValue(json, beanClass); // 通过反射获取并调用save方法 Method saveMethod = beanClass.getMethod("save"); saveMethod.invoke(bean); } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | JsonProcessingException e) { // 集中处理各类异常 e.printStackTrace(); } }
内容的提问来源于stack exchange,提问作者voila
相关产品推荐
相关产品推荐

