Since the question was how to convert a JSON structure to an object adding another property and not how to modify an original JSON String, I would like to post an answer that actually does what the title of the question says: JSON to Java object conversion.
The code below will work only if there are no nested objects and is not efficient if the JSON structure is large (because of the String concatenation).
Also, please note that creating classes dynamically might not be such a good idea (e.g. as discussed here). However, if you need it, a possible solution is given below. In this solution, a JSON String is converted to a Map
and a new key-value pair is added. Then the source code of the target class is written and compiled, the class is loaded and a test method is called for demo purposes.
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collections;
import java.util.Map;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
public class JsonToJava
{
private static Map<String, Object> map;
private static String json = "{\"Database\":0,\"SalesForce\":0,\"Watson\":0,\"AIC\":0,\"Luise\":0}";
private static String fileName = "Test";
public static void main(String[] args) throws Exception {
// create an empty source file
File sourceFile = File.createTempFile(fileName, ".java");
sourceFile.deleteOnExit();
java.lang.reflect.Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
Gson gson = new Gson();
map = gson.fromJson(json, mapType );
addProperty( "Total", "0" );
String fields = "";
for (Map.Entry<String, Object> entry : map.entrySet())
{
fields += "\tprivate " ;
try{
Double.parseDouble( entry.getValue().toString() );
fields += "double ";
}
catch ( NumberFormatException e ){
try{
Integer.parseInt( entry.getValue().toString() );
fields += "int ";
}
catch ( NumberFormatException ex ){
fields += "String " + entry.getValue();
}
}
fields += entry.getKey() + ";\n";
}
// generate the source code
String classname = sourceFile.getName().split("\\.")[0];
String sourceCode = "public class " + classname + "{\n\n" +
fields +
"\n\tpublic void hello(){\n\t\t System.out.print(\"Hello world\");\n\t}\n}";
// write the source code into the source file
System.out.println(sourceCode);
FileWriter writer = new FileWriter(sourceFile);
writer.write(sourceCode);
writer.close();
// compile the source file
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
File parentDirectory = sourceFile.getParentFile();
fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Collections.singletonList( parentDirectory ) );
Iterable<? extends JavaFileObject> compilationUnits =
fileManager.getJavaFileObjectsFromFiles( Collections.singletonList( sourceFile ) );
compiler.getTask(null, fileManager, null, null, null, compilationUnits).call();
fileManager.close();
// load the class
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { parentDirectory.toURI().toURL() });
Class<?> helloClass = classLoader.loadClass(classname);
// call a method of the newly compiled and loaded class
Method helloMethod = helloClass.getDeclaredMethod("hello");
helloMethod.invoke(helloClass.newInstance());
}
private static void addProperty(String key, String value)
{
map.put( key, value );
}
}