I am working on the framework which has these requirements
Developers develop their classes ( Beans ) like below
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
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
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.
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
CodePudding user response:
Extract the save()
method in an interface or abstract class, depending on your exact scenario. In most cases interface is better choice:
public interface MyInterface {
void save();
}
Have BeanA
, BeanB
, etc. implement it. Cast the deserialization result to MyInterface
and invoke 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");
}
CodePudding user response:
Assuming that you managed to read the JSON string that represents particular class from your URL and you know the class name. So you can use ObjectMapper
class and its method <T> T readValue(String content, Class<T> valueType)
. Place your json string as a content and as for class use public static Class<?> forName(String className) throws ClassNotFoundException
. See ObjectMapper javadoc here.
Also, if you want it even simpler I wrote my own JsonUtil where you don't even have to instantiate 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. See the Javadoc for JsonUtils class. The MgntUtils library can be obtained from Maven Central as Maven artifact or from Github along with Source code and Javadoc