1

I'm working on parsing a list of cards using GSon for a game I'm making, but I seemed to have hit a wall. The json I'm trying to parse is:

{
"name": "Core Set 2019",
"code": "M19",
"releaseDate": "2018-07-13",
"border": "black",
"type": "core",
"booster": [
  [
    "rare",
    "mythic rare"
  ],
  "uncommon",
  "uncommon",
  "uncommon",
  "common",
  "common",
  "common",
  "common",
  "common",
  "common",
  "common",
  "common",
  "common",
  "common",
  "land",
  "marketing"
]
}

The issue arises in the booster section. The error message netbeans gives is

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException:Expected a string but was BEGIN_ARRAY at line 9 column 8 path $.M19.booster[0]

The code I have so far is:

public class Set
{
    public String name;
    public String code;
    public String releaseDate;
    public String border;
    public String type;
    public List<String> booster;
    public Translation translations;
    public List<Card> cards;
}

and in main I have

Gson g = new GsonBuilder().create();
Set sets = g.fromJson(new FileReader(JSONNAME), Set.class);

How do I parse the nameless array in an array objects? The nameless array is not always going to be there and I cant change the json because it's being downloaded from a site I do not have access to.

3 Answers3

1

Change your class Set to this one :

public class JsonResponse
{
    private String name;
    private String code;
    private String releaseDate;
    private String border;
    private String type;
    ArrayList< Object > booster = new ArrayList < Object > ();


    public String getName() {
        return name;
    }

    public String getCode() {
        return code;
    }

    public String getReleaseDate() {
        return releaseDate;
    }

    public String getBorder() {
        return border;
    }

    public String getType() {
        return type;
    }


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

    public void setCode(String code) {
        this.code = code;
    }

    public void setReleaseDate(String releaseDate) {
        this.releaseDate = releaseDate;
    }

    public void setBorder(String border) {
        this.border = border;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return "JsonResponse{" +
                "name='" + name + '\'' +
                ", code='" + code + '\'' +
                ", releaseDate='" + releaseDate + '\'' +
                ", border='" + border + '\'' +
                ", type='" + type + '\'' +
                ", booster=" + booster +
                '}';
    }
}

In my case I put it on /resources/jsonexample.json so I did it like this :

Gson gson = new Gson();
        try {
            JsonResponse jsonResponse = gson.fromJson(new FileReader(new File("resources/jsonexample.json")), JsonResponse.class);
            System.out.println(jsonResponse.toString());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

And the output is

JsonResponse{name='Core Set 2019', code='M19', releaseDate='2018-07-13', border='black', type='core', booster=[[rare, mythic rare], uncommon, uncommon, uncommon, common, common, common, common, common, common, common, common, common, common, land, marketing]}

I've created a repository to how to do it on Github

Skizo-ozᴉʞS ツ
  • 19,464
  • 18
  • 81
  • 148
1

Using an Object will work:

public class Set {
    public String name;
    public String code;
    public String releaseDate;
    public String border;
    public String type;
    public List<Object> booster;
}

public static void main(String[] args) {
    Gson gson = new Gson();
    Set set = gson.fromJson("{\n" +
            "\"name\": \"Core Set 2019\",\n" +
            "\"code\": \"M19\",\n" +
            "\"releaseDate\": \"2018-07-13\",\n" +
            "\"border\": \"black\",\n" +
            "\"type\": \"core\",\n" +
            "\"booster\": [\n" +
            "  [\n" +
            "    \"rare\",\n" +
            "    \"mythic rare\"\n" +
            "  ],\n" +
            "  \"uncommon\",\n" +
            "  \"uncommon\",\n" +
            "  \"uncommon\",\n" +
            "  \"common\",\n" +
            "  \"common\",\n" +
            "  \"common\",\n" +
            "  \"common\",\n" +
            "  \"common\",\n" +
            "  \"common\",\n" +
            "  \"common\",\n" +
            "  \"common\",\n" +
            "  \"common\",\n" +
            "  \"common\",\n" +
            "  \"land\",\n" +
            "  \"marketing\"\n" +
            "]\n" +
            "}", Set.class);

    for (Object o : set.booster) {
        System.out.println(o.getClass() + " " + o);
    }
}

Output:

class java.util.ArrayList [rare, mythic rare]
class java.lang.String uncommon
class java.lang.String uncommon
class java.lang.String uncommon
class java.lang.String common
class java.lang.String common
class java.lang.String common
class java.lang.String common
class java.lang.String common
class java.lang.String common
class java.lang.String common
class java.lang.String common
class java.lang.String common
class java.lang.String common
class java.lang.String land
class java.lang.String marketing
Denis Zavedeev
  • 7,627
  • 4
  • 32
  • 53
0

The cause of exception is in booster :

"booster": [
  [
    "rare",
    "mythic rare"
  ],
...

You start an array in booster but it does not expect object, it expects string:

public class Set
{
    public String name;
    public String code;
    public String releaseDate;
    public String border;
    public String type;
    public List<String> booster; // here it expects list of string
...

Change your booster type from List<String> to List<Object> and it deserializes your json.

Emre Savcı
  • 3,034
  • 2
  • 16
  • 25