I'm trying to read a json file into java using Gson. So for that I used this line:
data = gson.fromJson(json.toString(), MainData.class);
I assumed It worked as I can access a field named version inside MainData:
System.out.println(data.version);//<-- this works
But as soon as I try to retrieve data from the inner objects I get a nullPointerException:
System.out.println(data.elemental.Water.a);//<-- this doens't work
I looked at a lot of questions that looked like they were the same. But from what I could tell I was doing excactly the same. So my guess is that there is a syntax error somewhere but I just cannot find it. Wich is not that unthinkable as this is my first try to work with json and gson.
Here is my json file:
{
"version": "1.1.0",
"values": {
"game": {
},
"elemental": {
"Air": {
},
"Void": {
},
"Earth": {
},
"Water": {
"a": "10"
},
"Fire": {
"tickTime": "10"
}
}
}
}
And here my java file:
By the way I also noticed that not all of the constructors are called.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import org.bukkit.craftbukkit.libs.com.google.gson.Gson;
public class JSONReader {
private static MainData data;
protected static final void readFile() throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File(Elementals.DataBase, "advanced.json"))));
StringBuffer json = new StringBuffer();
String line;
while((line = reader.readLine()) != null){
json.append(line);
}
System.out.println(json.toString());
reader.close();
Gson gson = new Gson();
data = gson.fromJson(json.toString(), MainData.class);
System.out.println(data.version);//works
System.out.println(data.elemental.Water.a);//doesn't work
System.out.println(data.elemental.Fire.tickTime);//doesn't work
}
private class MainData{
MainData(){//is called
System.out.println("main");
}
private String version;
private GameData values;
private ElementalData elemental;
public class GameData{
GameData(){//is not called
System.out.println("gamedata");
}
}
private class ElementalData{
ElementalData(){//is not called
System.out.println("elemental");
}
private AirData Air;
private EarthData Earth;
private WaterData Water;;
private FireData Fire;
private VoidData Void;
private class AirData{
}
private class EarthData{
}
private class WaterData{
WaterData(){//is not called
System.out.println("Water");
}
private int a;
}
private class FireData{
private int tickTime;
}
private class VoidData{
}
}
}
}
I hope this was informative enough and I'm looking forward to an answer.
In your JSON, your elemental is nested directly within values, not within the root object. Your POJOs need to reflect that. Your class should be like this
public class GameData {
GameData() {// is not called
System.out.println("gamedata");
}
private ElementalData elemental; // instead of in MainData
}
and then
System.out.println(data.values.elemental.Water.a);
Related
I have a simple class in java like below:
class Simple {
private String name;
private String email;
}
I want to have behaviour of java.util.List<Simple> and Simple both according to input data that my program receives.
i.e.
Case 1::
if my program receives below kind of json-array input
{"simple" : [ {"name":"a", "email" : "a#z.com"}, {"name":"b", "email" : "b#z.com"} ]}
I need to parse it using List<Simple>
Case 2::
if my program receives below kind of json-object input
{"simple" : {"name":"c", "email" : "c#z.com"} }
I need to parse it using Simple
Note: I have tried using JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, but the problem is it is basically converting single value also into json-array at the time of writing json.
I need to persist json as it is, is there any other way to achieve this?
To avoid any Jackson customisation I would create wrapper class with an Object simple property. We can add two extra checking methods and two extra casting methods. It will allow Jackson to do it's logic and in runtime we can check what actually we have:
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Collections;
import java.util.List;
public class DateApp {
private final static JsonMapper JSON_MAPPER = JsonMapper.builder().enable(SerializationFeature.INDENT_OUTPUT).build();
public static void main(String[] args) throws Exception {
Simple object = new Simple("John", "john#doe.com");
SimpleWrapper wrapper = new SimpleWrapper();
wrapper.setSimple(object);
serializeAndDeserialize(wrapper);
wrapper.setSimple(Collections.singletonList(object));
serializeAndDeserialize(wrapper);
}
private static void serializeAndDeserialize(SimpleWrapper wrapper) throws JsonProcessingException {
String json = JSON_MAPPER.writeValueAsString(wrapper);
System.out.println("JSON:");
System.out.println(json);
wrapper = JSON_MAPPER.readValue(json, SimpleWrapper.class);
System.out.println("Wrapper:");
System.out.println(wrapper);
}
}
#Data
class SimpleWrapper {
private Object simple;
#JsonIgnore
public boolean isSimpleObject() {
return simple instanceof Simple;
}
#JsonIgnore
public boolean isSimpleList() {
return simple instanceof List;
}
#JsonIgnore
public Simple getSimpleAsObject() {
return (Simple) simple;
}
#JsonIgnore
public List<Simple> getSimpleAsList() {
return (List<Simple>) simple;
}
}
#Data
#NoArgsConstructor
#AllArgsConstructor
class Simple {
private String name;
private String email;
}
Above code prints:
JSON:
{
"simple" : {
"name" : "John",
"email" : "john#doe.com"
}
}
Wrapper:
SimpleWrapper(simple={name=John, email=john#doe.com})
JSON:
{
"simple" : [ {
"name" : "John",
"email" : "john#doe.com"
} ]
}
Wrapper:
SimpleWrapper(simple=[{name=John, email=john#doe.com}])
You can use JsonNode.isArray() (or JsonNode.isObject()) to perform this check.
Then you can parse the node into a list with ObjectReader.readValue() or into a POJO using ObjectMapper.treeToValue().
String myJson = """
{"simple" : {"name":"c", "email" : "c#z.com"} }
""";
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(myJson);
if (node.isArray()) {
ObjectReader reader = mapper.readerFor(new TypeReference<List<Simple>>() {});
List<Simple> list = reader.readValue(node);
// do something with a list
} else {
Simple pojo = mapper.treeToValue(node, Simple.class);
// do something else with a single object
}
Jackson is able to parse any json into a map where value is any object. you can then inquire on the type of the map value
Map<String, Object> map = new ObjectMapper().readValue(jsonInput, Map.class);
Object value = map.get("simple");
if (value instanceof Collection) { // will return false for null
Collection<Simple> simples = (Collection<Simple>)value;
}
else if (value instanceof Simple) {
Simple simple = (Simple)value;
}
else {
System.err.println("unrecognized");
}
You only need to read the first node, simple and check if it is an array - using isArray() method.
public class Main{
public static void main(String args[]) {
//String inputString = [your input];
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(inputString);
JsonNode simpleNode = root.findPath("simple");
if(simpleNode.isArray()) {
//you have an array
} else {
// you have an element
}
}
}
Here is the code I want to create with my Java code. I'm not doing anything elaborate. Just trying to refresh myself with parsing json from java.
[{"county":"Jefferson",
"houses":\[
{"squareFeet":1100,
"bedrooms":2,
"bathrooms":2,
"internet":"y",
"location":"Country"
},
{"squareFeet":750,
"bedrooms":1,
"bathrooms":1,
"internet":"n",
"location":"Town"
}
\]
}]
At the moment my Java code looks like this.
With this code below I am close to having it, with the exception of the first Object, and also the title to the array of houses.
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
public class HousesToJSON {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JSONArray houses = new JSONArray();
House houseOne = createHouseObjectOne();
House houseTwo = createHouseObjectTwo();
houses.add(houseOne);
houses.add(houseTwo);
try (FileWriter writer = new FileWriter("houses.json")) {
gson.toJson(houses, writer);
} catch (IOException e) {
e.printStackTrace();
}
}
private static House createHouseObjectOne() {
House house = new House();
house.setSquareFeet(1100);
house.setBedrooms(2);
house.setBathrooms(2);
house.setInternet('y');
house.setLocation("Country");
return house;
}
private static House createHouseObjectTwo() {
House house = new House();
house.setSquareFeet(750);
house.setBedrooms(2);
house.setBathrooms(1);
house.setInternet('y');
house.setLocation("Town");
return house;
}
}
This create the file below.
[
{
"squareFeet": 1100,
"bedrooms": 2,
"bathrooms": 2,
"internet": "y",
"location": "Country"
},
{
"squareFeet": 750,
"bedrooms": 2,
"bathrooms": 1,
"internet": "y",
"location": "Town"
}
]
I am still pretty new at this, and any help would be much appreciated.
Something along the lines of this should provide you with the neccesary objects for your JSON example:
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class CountyContainer {
#SerializedName("county")
#Expose
private String county;
#SerializedName("houses")
#Expose
private List<House> houses = null;
public String getCounty() {
return county;
}
public void setCounty(String county) {
this.county = county;
}
public List<House> getHouses() {
return houses;
}
public void setHouses(List<House> houses) {
this.houses = houses;
}
}
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class House {
#SerializedName("squareFeet")
#Expose
private Integer squareFeet;
#SerializedName("bedrooms")
#Expose
private Integer bedrooms;
#SerializedName("bathrooms")
#Expose
private Integer bathrooms;
#SerializedName("internet")
#Expose
private String internet;
#SerializedName("location")
#Expose
private String location;
public Integer getSquareFeet() {
return squareFeet;
}
public void setSquareFeet(Integer squareFeet) {
this.squareFeet = squareFeet;
}
public Integer getBedrooms() {
return bedrooms;
}
public void setBedrooms(Integer bedrooms) {
this.bedrooms = bedrooms;
}
public Integer getBathrooms() {
return bathrooms;
}
public void setBathrooms(Integer bathrooms) {
this.bathrooms = bathrooms;
}
public String getInternet() {
return internet;
}
public void setInternet(String internet) {
this.internet = internet;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
You can generate these yourself using this online service and selecting the GSON annotation style:
http://www.jsonschema2pojo.org/
When you've created your objects, you can write those objects to a JSON file using:
final Gson gson = new Gson();
try (final FileWriter writer = new FileWriter("houses.json")) {
gson.toJson(houses, writer); // houses refers to your object containing the List of House objects and the country
} catch (final IOException e) {
// Handle exceptions here
}
Alternatively, you can also use place the JSON data into a String:
String json = gson.toJson(houses);
For more information regarding GSON functionality, please take a look at the official documentation:
https://www.javadoc.io/doc/com.google.code.gson/gson/latest/com.google.gson/module-summary.html
There is no House class provided, but I guess we can skip it. You are moving in the right direction. Just add another class:
public class County {
private String county;
private List<House> houses;
// getters, setters, whatever :)
}
And create instance of this class. Set name (county field) and houses and serialize to JSON :)
I would probably rename json array to JSONArray counties = new JSONArray(); and what you need to add to this array is some county with name "Jefferson" and list of houses that you have now.
County county = new County();
county.setCounty("Jefferson");
List<House> houses = new ArrayList<>();
houses.add(houseOne);
houses.add(houseTwo);
county.setHouses(houses);
counties.add(county);
This might not be 100% working code, but hope the idea is clear :)
Given the following JSON source
{
"database": "Accounts",
"groups": {
"databaseDictionary": {
"folder": "C:\\Development\\Work\\Ac\\Data\\DataDictionary"
},
"sqlCreateDatabase": {
"name": "Sleaford",
"user": "JBarrow",
"useWindowsAuthentication": "true"
},
"defaultData": {
"folder": "C:\\Development\\Work\\Ac\\Data\\Configuration"
}
}
}
I was hoping that the following class structure would successfully populate the object.
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
public class JsonNestedHashMapConcise {
private Configuration data;
private class Configuration {
private String database;
private HashMap<String, Group> groups;
private class Group {
private HashMap<String, String> settings;
}
}
public JsonNestedHashMapConcise (String fn) {
try (Reader jsonFile = new BufferedReader(new FileReader(new File(fn)))) {
Gson jsonParser = new Gson();
this.data = jsonParser.fromJson(jsonFile, Configuration.class);
}
catch (JsonSyntaxException | IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
JsonNestedHashMapConcise myConfiguration;
myConfiguration = new JsonNestedHashMapConcise("C:\\StackOverflow\\Concise.json");
System.out.println("Completed reading database configuration for " + myConfiguration);
}
}
However, while the Configuration.groups HashMap is populated, the nested groups.settings HashMap is null.
I have searched around and found possible solutions around techniques such as JsonDeserializer, registerTypeAdapter & TypeToken but I can’t comprehend how they fit into solving my problem.
As a bit of background, I have a starting point (source and sample JSON listed below) that provides a workaround but requires a more verbose JSON syntax. It was while writing the supporting methods I spotted that if I make the Configuration.groups field a HashMap, it would lead to more efficient queries. I have also read that inner classes were supported in Gson and this starting point appears to support that statement.
JSON source for verbose structure
{
"database": "Accounts",
"groups": [
{
"name": "databaseDictionary",
"settings": {
"folder": "C:\\Development\\Work\\Ac\\Data\\DataDictionary"
}
},{
"name": "sqlCreateDatabase",
"settings": {
"name": "Sleaford",
"user": "JBarrow",
"useWindowsAuthentication": "true"
}
},{
"name": "defaultData",
"settings": {
"folder": "C:\\Development\\Work\\Ac\\Data\\Configuration"
}
}
]
}
works with the following class structure
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
public class JsonNestedHashMapVerbose {
private Configuration data;
private class Configuration {
private String database;
private ArrayList<Group> groups;
private class Group {
private String name;
private HashMap<String, String> settings;
}
}
public JsonNestedHashMapVerbose (String fn) {
try (Reader jsonFile = new BufferedReader(new FileReader(new File(fn)))) {
Gson jsonParser = new Gson();
this.data = jsonParser.fromJson(jsonFile, Configuration.class);
}
catch (JsonSyntaxException | IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
JsonNestedHashMapVerbose myConfiguration;
myConfiguration = new JsonNestedHashMapVerbose("C:\\StackOverflow\\Concise.json");
System.out.println("Completed reading database configuration for " + myConfiguration);
}
}
The only difference I can spot between the two designs is that the starting structure has an explicit ‘settings’ element defined within the JSON which may be needed for the parser to be able to deserialize that part of the structure.
Am I pushing the Gson deserializer too far or is there some additional code I can add to help Gson complete the task?
Feedback on suggested duplicate question
The solution detailed in the suggested related question, using a parser provided by creates a very verbose class structure which I have detailed below (edited for clarity).
This automated parser method doesn't recognise that these related elements (databaseDictionary, sqlCreateDatabase & defaultData) can all be stored in a HashMap structure, and I would have been very impressed if the parser could have detected that. Instead, we end up with a class for each and every element.
public class DatabaseDictionary {
public String folder;
}
public class DefaultData {
public String folder;
}
public class Example {
public String database;
public Groups groups;
}
public class Groups {
public DatabaseDictionary databaseDictionary;
public SqlCreateDatabase sqlCreateDatabase;
public DefaultData defaultData;
}
public class SqlCreateDatabase {
public String name;
public String user;
public String useWindowsAuthentication;
}
The JSON source detailed at the start of this question is a subset of the number of elements existing within the groups element and these will be expanded (and later searched on).
Using the class structure detailed using would require that I create a new class to support each and every element (and I expect there to be 10s or 100s of these elements within the source). Using this structure would have also meant that it was very hard to locate a specified group element within the groups element to extract its attributes.
I can parse the JSON source using the primitive methodology of JsonToken to populate the java class
private class Configuration {
private String database;
private HashMap<String, Group> groups;
private class Group {
private HashMap<String, String> settings;
}
}
but, given that the GSON parser clearly can detect and populate HashMap elements as illustrated in the second example, I had hoped that a two tier HashMap would be detected in the same manner to avoid the repeated use of JsonToken as I have other similar JSON structures that would benefit from the use of HashMap.
I don't know whether the GSON parser detected the class type in the supplied java class or it detected that there were multiple element names at the same level in order to populate a single HashMap as I don't have a knowledge of the internal workings of GSON.
I was hoping that there was a supporting GSON abstract method that I could use to educate the parser into populating the hierarchical HashMap class.
In case anyone is interested
If anyone else wants to model a similar structure, I found that using the JsonReader class led to quite a readable solution even though it would be nice if the toJson method would have just worked as minimalist code to write. I have provided my source below, although as I am still a bit of a novice, I am sure that there may be more elegant ways to write some of the methods.
import com.google.gson.JsonSyntaxException;
import com.google.gson.stream.JsonReader;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
public class DatabaseConfiguration {
private String database;
private HashMap<String, Group> groups;
private class Group {
private HashMap<String, String> settings;
}
private Group ReadGroup(JsonReader jsonReader) throws IOException {
Group result = null;
// Iterate over the the list of group attributes
jsonReader.beginObject();
while (jsonReader.hasNext()) {
String name = jsonReader.nextName();
if (result == null) {
result = new Group();
result.settings = new HashMap<>();
}
result.settings.put(name, jsonReader.nextString());
}
jsonReader.endObject();
return result;
}
private HashMap<String, Group> ReadGroups (JsonReader jsonReader) throws IOException {
HashMap<String, Group> result = null;
// Iterate over the the list of groups
jsonReader.beginObject();
while (jsonReader.hasNext()) {
String name = jsonReader.nextName();
Group myGroup;
myGroup = ReadGroup(jsonReader);
if (result == null) {
result = new HashMap<>();
}
result.put(name, myGroup);
}
jsonReader.endObject();
return result;
}
public DatabaseConfiguration (String fn) {
try (Reader jsonFile = new BufferedReader(new FileReader(new File(fn)));
JsonReader jsonReader = new JsonReader(jsonFile)) {
// Root node (database + groups)
jsonReader.beginObject();
while (jsonReader.hasNext()) {
String name = jsonReader.nextName();
switch (name) {
case "database":
this.database = jsonReader.nextString();
break;
case "groups":
this.groups = ReadGroups(jsonReader);
break;
default:
throw new JsonSyntaxException("Unexpected name " + name + "in outer element of " + fn);
}
}
jsonReader.endObject();
}
catch (JsonSyntaxException | IOException e) {
System.out.println(e);
}
}
public static void main(String[] args) {
DatabaseConfiguration myConfiguration;
myConfiguration = new DatabaseConfiguration("C:\\StackOverflow\\Concise.json");
System.out.println("Completed reading database configuration for " + myConfiguration);
}
}
An aside as my first time posting here
My original question was originally marked as a duplicate and so was automatically closed. I then, as advised, edited my question to detail why the suggested solution in the duplicate question was not related to my question. I then expected the question to be re-opened (as it had been edited) but this never happened. I didn't want to cut-and-paste my edited question to re-issue it as I felt that would be abusing the principles behind Stack Overflow and so I leave confused as to what the correct methodology is to successfully retract a question incorrectly marked as a duplicate.
Since I commented above, I have now discovered (by accident) that I can ask the originator of the 'duplicate' marker to review their decision by 'pinging' them in a comment so I will now try that!
It would be nice if there was an obvious option after narrating why the original question isn't a duplicate on the form but as I am a new user, I can't post any feedback in the general forum until I have 5 credits!
I'm working on a RESTful API project and I'm using JAVA to accomplish the endpoints creation, because the environment where I'm working is an IBM Domino database. I'm using the org.json jar to create the objects and provide all the responses, but now I would modify the project, working directly with Java classes, because it's becoming bigger and bigger... By the way I have problems with nested Java objects.
Basically I have the classes LabelValue, Content and ResultsBlock instantiated in another class that set all the required fields and the generate a JSONObject calling its constructor plus the new object. When I'm doing this I have a Null pointer exception so the system doesn't provide any response.
I think that the problem is with the declaration, in the class Resultblock, of the nested Content object. But I don't know how can I manage this kind of situation. Can you help me?
When I'm working with easier classes where the attributes are the generical data types and when I create the ArrayList of type Content I've no problem and everything works well.
Thanks in advance!
p.s. I can't use gson library because it creates a java policy problem with IBM Domino server.
public class LabelValue implements java.io.Serializable{
private String label;
private String value;
public void setLabel(String label) {
this.label = label;
}
public void setValue(String value) {
this.value = value;
};
}
public class Content implements java.io.Serializable{
private String title;
private String description;
private ArrayList <LabelValue> totals;
public void setTotals(ArrayList<LabelValue> totals) {
this.totals = totals;
}
public void setTitle(String title) {
this.title = title;
}
public void setDescription(String description) {
this.description = description;
}}
public class ResultsBlock implements java.io.Serializable{
private String type;
private Content content;
public void setType(String type) {
this.type = type;
}
public void setContent(Content content) {
this.content = content;
}}
in the main :
{
Content content = new Content();
content.setTitle("title");
content.setDescription("description");
content.setTotals(label);
ResultsBlock result = new ResultsBlock ();
result.setContent(content);
result.setType("result");
return new JSONObject(result);}
this is the expected output of the blockResult class:
"blocks":
{
"type": "result",
"content": {
"title": "title",
"description": "description",
"totals": [
{
"label": "label",
"value": value
}
]
}
}
If I understand correctly what you need, I would suggest you to use Jackson if you can't use GSON.
I tried to make a test with the code you provided and, after adding all get methods to your POJO classes, I implemented this example:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class MainClass {
public static void main(String[] args) throws JsonProcessingException {
Content content = new Content();
content.setTitle("title");
content.setDescription("description");
ResultsBlock result = new ResultsBlock ();
result.setContent(content);
result.setType("result");
// JSONObject(result);
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(result);
System.out.println(jsonString);
}
}
It prints out the following:
{
"type": "result",
"content": {
"title": "title",
"description": "description",
"totals": null
}
}
Now you can access your JSON as you like.
Of course I've not considered all fields for simplicity.
Hope this helps.
I have the following json
{ "file": {"file": "foo.c", "owner": "user123"}
"methods": [{"name": "proc1", "value":"val"}, {"name":"proc2","value":"val2"}]
etc...
}
I know that I can do something like
class file{
public String file
public String owner
}
class methods{
public String name
public String value
}
and I can either call
File file= gson.fromJson(jsonInString, File.class);
methods[] array = gson.fromJson(jsonInString, methods[].class);
but what do I do if I need to handle a complex json that contains many objects all togther
I cannot specify gson.fromJson(jsonInString, ListOfClasses)
I normally follow this approach to get any complex classes converted from json to object. This approach works for almost everything like list, map etc. The idea is simple create holders for the complex classes and then create the classes. Give as much depth as much required. The trick is to match name in Json and your holders (and subclasses).
File Config:
class FileConfig{
public String file;
public String owner;
//define toString, getters and setters
}
Method Class:
class Method{
public String name;
public String value;
//define toString, getters and setters
}
Method Config:
class MethodConfig{
List<Method> methods = null;
//define toString, getters and setters
}
Holding the Config:
public class HolderConfig {
private FileConfig file = null;
private MethodConfig methods = null;
public FileConfig getFile() {
return file;
}
public void setFile(FileConfig file) {
this.file = file;
}
public MethodConfig getMethods() {
return file;
}
public void setMethods(MethodConfig methods) {
this.methods = methods;
}
}
Building the config:
public class HolderConfigBuilder {
public static HolderConfig build(JsonObject holderConfigJson) {
HolderConfig configHolderInstance = null;
Gson gsonInstance = null;
gsonInstance = new GsonBuilder().create();
configHolderInstance = gsonInstance.fromJson(holderConfigJson,HolderConfig.class);
return configHolderInstance;
}
}
Demo class:
public class App
{
public static void main( String[] args )
{
HolderConfig configHolderInstance = null;
FileConfig file = null;
configHolderInstance = HolderConfigBuilder.build(<Input Json>);
file = configHolderInstance.getFile();
System.out.println("The fileConfig is : "+file.toString());
}
}
Input Json:
{ "file": {"file": "foo.c", "owner": "user123"}
"methods": [
{"name": "proc1", "value":"val"},
{"name":"proc2","value":"val2"}
]
}
Note: Write the code to get Input JSON in your test code.
In this way whenever you add more elements to your JSON you have to create a separate class for that element and just add the element name same as in your json into the HolderConfig. You need not change rest of the code.
Hope it helps.