简体   繁体   English

Jackson 通过 class 完全限定名称动态反序列化

[英]Jackson deserialize dynamically by class fully Qualified Name

I am working on the framework which has these requirements我正在研究具有这些要求的框架

Developers develop their classes ( Beans ) like below开发人员开发他们的类(Beans)如下

class BeanA{
  
    int id;
    String appName;

   public void save() 
}

class BeanB{
  
    int id;
    String userName;

   public void save() 
}

There is orchestratoon.csv is also defined like this where developer makes the entry of their class orchestratoon.csv也是这样定义的,开发人员在其中输入他们的 class

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

After this, I have to write a platform service, which will fetch the Beans data from the url given in the orchestration.csv file and render then in the class provided by their fully qualified name在此之后,我必须编写一个平台服务,它将从orchestration.csv文件中给出的url中获取 Beans 数据,然后在由其fully qualified name提供的 class 中呈现

My problem is, how can I deserialize the json fetched into the class given by its name and call a save method of that bean.我的问题是,我怎样才能将 json 反序列化为由其名称给出的 class 并调用该 bean 的save方法。

Below is the psuedo code.下面是伪代码。

ObjectMapper objectMapper = new ObjectMapper();

for className, URL in CSV
  
   String json = getObject(url)

   // Here is the problem, how do I deserialize it using ObjectMapper 
   
     objectMapper.readValue(json, Class.forName(className));   ---> It does not work , compile time error because of Class.forName and how do I call a save on it

Any help would任何帮助都会

Assuming that you managed to read the JSON string that represents particular class from your URL and you know the class name.假设您设法从 URL 中读取了代表特定 class 的 881569990078588 字符串,并且您知道 class 名称。 So you can use ObjectMapper class and its method <T> T readValue(String content, Class<T> valueType) .因此,您可以使用ObjectMapper class 及其方法<T> T readValue(String content, Class<T> valueType) Place your json string as a content and as for class use将您的 json 字符串作为内容并作为 class 使用
public static Class<?> forName(String className) throws ClassNotFoundException . public static Class<?> forName(String className) throws ClassNotFoundException See ObjectMapper javadoc here .在此处查看 ObjectMapper javadoc。 Also, if you want it even simpler I wrote my own JsonUtil where you don't even have to instantiate ObjectMapper.另外,如果你想要它更简单,我写了我自己的 JsonUtil,你甚至不必实例化 ObjectMapper。 Your code would look like this:您的代码如下所示:

 try {
    BeanB beanB = JsonUtils.readObjectFromJsonString(jsonStr, Class.forName(classNameStr));
} catch (IOException ioe) {
    ...
}

In this example class JsonUtils comes with Open Source MgntUtils library written and maintained by me.在此示例中,class JsonUtils附带由我编写和维护的开源 MgntUtils 库。 See the Javadoc for JsonUtils class .请参阅JsonUtils class 的 Javadoc The MgntUtils library can be obtained from Maven Central as Maven artifact or from Github along with Source code and Javadoc MgntUtils 库可以作为 Maven 工件从Maven Central获得,或者连同源代码和 Javadoc 从 Github 获得

Extract the save() method in an interface or abstract class, depending on your exact scenario.根据您的具体情况,提取接口或抽象 class 中的save()方法。 In most cases interface is better choice:在大多数情况下,接口是更好的选择:

public interface MyInterface {

  void save();
}

Have BeanA , BeanB , etc. implement it. BeanABeanB等实现它。 Cast the deserialization result to MyInterface and invoke save() .将反序列化结果转换为MyInterface并调用save()

Object object;
try {
  object = objectMapper.readValue(json, Class.forName("bean.class.full.name"));
} catch (JsonProcessingException exc) {
  throw new RuntimeException("invalid json", exc);
}
if (object instanceof MyInterface myInterface) {
  myInterface.save();
} else {
  throw new RuntimeException("appropriate message here");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM