3

I am trying to parse a JSON .txt file into a JAVA object using GSON. The JSON file has the following structure:

    {
        "event0" : {
        "a" : "abc",
        "b" : "def"
        },

        "event1" : {
        "a" : "ghi",
        "b" : "jkl",
        "c" : "mno"
        }
    }

I have read the text file into a String called dataStr. I want to use the fromJson method to capture the events into the following JAVA class:

public class Event {
    private String a;
    private String b;
    private String c;

    public Event() {}

}

The problem is that the JSON might have one extra field "c" in some of the elements. I want to parse all the events into Event class objects, and for the cases where there is no "c" field, I want to make it null or zero in my object. It is not known beforehand which of the elements will have the "c" field.

Specifically, I was not able to figure out how to handle one extra field in some of the JSON elements. I want to do something along the lines of:

Gson gson = new Gson();
ArrayList<Event> events = gson.fromJson(dataStr, Event.class);

But I am stuck with first, how to iterate over the events in the Json file, and secondly, how to handle some occasional missing fields into the same Event object. I would really appreciate a kick in the right direction. Thank you all.

I am fairly new to JSON parsing, and might have missed something in the following answers:

Using Gson to convert Json into Java Object

Mapping JSON into POJO using Gson

Using gson to parse json to java object

Parse JSON into a java object

How to parse a json file into a java POJO class using GSON

Sami
  • 83
  • 2
  • 10
  • Your JSON does not look correct, can you please describe the data model you are looking for? An array of events with possible values of A,B and C? – StefanE Jul 07 '17 at 10:54
  • Fixed the JSON. Yes, an array of events, definitely with values of A and B, and possibly C. – Sami Jul 07 '17 at 11:35

4 Answers4

3

I'm not sure if I understood your question right. As per my understanding, you are trying to convert a json object with an extra field which is not available in the java class. Frankly, I don't understand why you want that or if it's possible to start with. You can have a workaround by converting the json to Map.

Map map = gson.fromJson(jsonString, Map.class);

Ashish Lohia
  • 269
  • 1
  • 12
  • 2
    The generic types can also be specified: `Map map = gson.fromJson(jsonString, new TypeToken>() {}.getType())` – SpaceBison Jul 07 '17 at 10:43
  • Agreed. This was just simpler, using TypeToken is also a feasible option. – Ashish Lohia Jul 07 '17 at 10:57
  • Thanks for the reply. It's not that the extra field isn't available in the java class. As mentioned, my java class Event has that attribute. However the JSON consists of a series of events, where some have that field and some don't. And for the ones that don't, I want the java object attribute to be set to null. I feel like it should be something as easy as @Manuel Gozzi 's answer, but I am having trouble with the code: ArrayList events = gson.fromJson(dataStr, Event.class); Wonder if this is the correct way to fill up a list from JSON. – Sami Jul 07 '17 at 11:00
  • Converting to a Map helped. I was then able to iterate over the Map and populate my Event objects. Thanks. – Sami Jul 07 '17 at 11:07
0

Gson automatically do that for you.

So, if you have a class "Alpha" with 3 fields ("a", "b" and "c") and you try to work on a json object that has 2 fields with names that match with Alpha's "a" and "b", Gson will fill "a" and "b" with json file's value and "c" will automatically set as null.

So, in your case, if you write this:

ArrayList<Event> events = gson.fromJson(dataStr, Event.class);

And in your json there are events with only 2 fields (that match with any Event's class fields) and events with all fields set, you will get a list of Events with no errors. Maybe you'll get some fields null, but the code will work.

I hope to be helpful! Ask for further informations, if you want to!

EDIT

Note that your json file has not to be .txt but .json instead!

Gozus19
  • 165
  • 19
  • Thanks for the reply. Here is the error I am getting when I try to do this: ArrayList events = gson.fromJson(dataStr, Event.class); Error: incompatible types: inference variable T has incompatible bounds equality constraints: bo.Event upper bounds: java.util.ArrayList,java.lang.Object – Sami Jul 07 '17 at 10:41
  • The file name can be whatever as long as the content is valid JSON in text format. – StefanE Jul 07 '17 at 10:44
  • Yes, agree with @StefanE as I was already able to read the .txt file, which had valid JSON in it, into a String called dataStr. So the actual file is not the problem. – Sami Jul 07 '17 at 10:56
  • I understand the error. Note that `Event` class and `ArrayList` class are two different files. So, if you write `ArrayList events = gson.fromJson(dataStr, Event.class);` Gson pretend to read a `.json` that contains an object Event, not an object `ArrayList`. Try to change your code to something like this: `ArrayList events = gson.fromJson(dataStr, ArrayList.class);`. In other words you're creating a new ArrayList, doing an assignment saying that you get an Event from json. In fact you're creating an Event and not an arrayList of Event. – Gozus19 Jul 07 '17 at 12:17
0

First I believe your JSON should look like this:

{
  "events": [
    {
      "name": "event0",
      "a": "abc",
      "b": "def"
    },
    {
      "name": "event1",
      "a": "abc",
      "b": "def",
      "c": "mno"
    }
  ]
}

This will need two classes for your model:

public List<Event> events = null;

public class Event {
public String name;
public String a;
public String b;
public String c;

}

And then then with GSON

Events events = gson.fromJson(jsonData, Events.class);

Also I recommend to always use an online validator for JSON so you are sure your JSON structure is correct before coding against it. https://jsonlint.com/ Or for formate the JSON: http://jsonprettyprint.com/

Also this website can create the Java classes for you from either a JSON Schema or by using an example file. http://www.jsonschema2pojo.org/

StefanE
  • 7,578
  • 10
  • 48
  • 75
  • Thank you for pointing out this mistake. EDITED the original post. I already validated my json files but made a typo while posting a simpler structure here. PS. How do you edit the original post? – Sami Jul 07 '17 at 11:29
  • Should be an edit option to the bottom left. I still believe you are better off creating a similar solution to what I suggested to get a more strongly typed object rather than using an map – StefanE Jul 07 '17 at 11:34
  • I agree about the structure of the JSON. However, I am just trying to quickly fetch the data from these previously generated (erroneously) JSON text files. My main application now uses a db to store data and I do not want to spend too much effort on reading from text files. Thanks – Sami Jul 07 '17 at 11:42
0

Try the below code snippet:

Gson gson = new Gson();
ArrayList<Event> events = gson.fromJson(dataStr, new TypeToken<ArrayList<Event>>(){}.getType());

In the source code of Gson has a very clear explain enter image description here

shusheng007
  • 389
  • 4
  • 5