Jeremy
Jeremy

Reputation: 641

Java - Multiple GSON?

Ok i am creating an application that used JSON to save date. I used GSON as my JSON "processor".

Yes i know how to use Gson. I follow the tutorial on web. The problem is, the tutorial on web and only save "one" json data. I mean, for example,

{
    "Data1": {
      "name": "Data1",
      "info": "ABCDEFG"
    }
}

So, after user saved Data1, they want to save Data2, Data3, etc like this

{
    "Data1": {
      "name": "Data1",
      "info": "ABCDEFG"
    },
    "Data2": {
      "name": "Data2",
      "info": "ABCDEFGHIJ"
    }
}

But if user want to save 100+ data do i have to make 100 classes? Below are my code.

JSONTest.class

public class JSONTest
{
    private static Gson gson;
    private static File file;
    private static JSONTest instance;
    private static Bean bean;
    private static Map<String, String> data = new HashMap();

    public static void main(String[] args)
    {
        bean = new Bean();
        File file = new File("C://test-json.json");
        GsonBuilder builder = new GsonBuilder();
        builder.setPrettyPrinting();
        gson = builder.create();

        data.put("name", "data1");
        data.put("info", "abcde");
        bean.setData(data);


        String jsonString = gson.toJson(bean);

        try
        {
            FileWriter fw = new FileWriter(file);
            fw.write(jsonString);
            fw.close();
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
}

Bean.class

public class Bean
{
    private Map<String, String> data;

    public Map<String, String> getData()
    {
        return data;
    }

    public void setData(Map<String, String> properties)
    {
        this.data = properties;
    }
}

So the result is this

{
  "data": {
    "name": "data1",
    "info": "abcde"
  }
}

ok now i change the value(mean that i want to add new data

data.put("name", "data2");
data.put("info", "abcdef");
bean.setData(data);

the result is this

{
  "data": {
    "name": "data2",
    "info": "abcdef"
  }
}

but i want the result like this

{
    "data1": {
      "name": "data1",
      "info": "abcde"
    },
    "data2": {
      "name": "data2",
      "info": "abcdef"
    }
}

So my question is, how can i do that?If user want to save 100+ data do i have to make 100+classes or elements? And also, how to add "selectedData: "data1"" so my json loader so load 1 data only?

Upvotes: 2

Views: 3466

Answers (3)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279920

You have to understand the JSON you are using before you use a JSON parser/generator.

This

{
    "Data1": {
      "name": "Data1",
      "info": "ABCDEFG"
    }
}

is a JSON object containing a JSON object with the name Data1.

This

{
    "Data1": {
      "name": "Data1",
      "info": "ABCDEFG"
    },
    "Data2": {
      "name": "Data2",
      "info": "ABCDEFGHIJ"
    }
}

is a JSON object containing two JSON objects named Data1 and Data2.

A simple working example would be

public static void main(String[] args) throws Exception {
    String json =   "{              \"Data1\": {                  \"name\": \"Data1\",                \"info\": \"ABCDEFG\"             },              \"Data2\": {                  \"name\": \"Data2\",                \"info\": \"ABCDEFGHIJ\"              }           }";
    Gson gson = new Gson();
    Map<String, CustomBean> objects = gson.fromJson(json, new TypeToken<Map<String, CustomBean>>() {}.getType());
    System.out.println(objects);
}

where CustomBean is

public class CustomBean {

    private String name;
    private String info;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public String toString() {
        return "[name = " + name + ", info = " + info + "]";
    }

}

The above prints

{Data1=[name = Data1, info = ABCDEFG], Data2=[name = Data2, info = ABCDEFGHIJ]}

Since both nested objects are the same, you can tell Gson to deserialize them into a Map where the name of the JSON object is the key and the object itself is the value.

The JSON format has very specific types that can map to Java types. You have to use the corresponding types. For example, you would use a List for a JSON array.


Let's go back to your question now that you've edited it

So my question is, how can i do that?If user want to save 100+ data do i have to make 100+classes or elements? And also, how to add "selectedData: "data1"" so my json loader so load 1 data only?

With the example you've given, it looks to me like you misunderstand how Gson works.

Gson tries to serialize your object to a JSON object. An object of a simple class like

public class Bean {
    private String name = "some value";
    private String info = "some other value";
}

maps nicely to the following JSON object

{
    "name" : "some value",
    "info" : "some other value"
}

The java class Map is a special class that maps nicely to JSON. The key is used as the name of the JSON object and the value is used as the value of the JSON object, be it a number, String, JSON array, or another JSON object. So the Map object in the following snippet

Map<String, Bean> map = new HashMap<>();
map.put("data1", new Bean());

serialized by Gson would give the following JSON

{
    "data1": {
      "name": "some value",
      "info": "some other value"
    }
}

Because the key is the String data1 and the value is another JSON object which is serialized as I showed above.

So my question is, how can i do that?If user want to save 100+ data do i have to make 100+classes or elements?

It should be clear with the above what you need to do.

And also, how to add "selectedData: "data1"" so my json loader so load 1 data only?

Please clarify what you mean. You can't load only a subset of the JSON. Gson will load all of it, you can extract the JSON object named data1 from that.

Upvotes: 1

Tom
Tom

Reputation: 2103

As Sotirios Delimanolis has said you want a Map i.e

public class Data {

    private final String name;
    private final String info;

    public Data(String name, String info) {
        this.name = name;
        this.info = info;
    }

    public String getInfo() {
        return info;
    }

    public String getName() {
        return name;
    }
}

Then deserialize to Map. i.e.

  Gson gson = new Gson();              

  Type collectionType = new TypeToken<Map<String, Data>>(){}.getType();
  Map<String, Data> datas = gson.fromJson(json, collectionType);

  Data data1 = datas.get("data1");

Upvotes: 0

sanket
sanket

Reputation: 789

Make Data as an object.

Set its values and save it in an ArrayList.

Convert the ArrayList to JSON

Upvotes: 0

Related Questions