Search code examples
javagenson

process part of json file


I've got a json file that looks like this

{
  "races": [
    {
      "name"  : "ORC"
    },
    {
      "name"  : "HUMAN"
    },
    {
      "name"  : "ELF"
    }
  ],
  "npc": [
    {
      "race"  : "HUMAN",
      "age"   : "25",
      "name"  : "Jerome"
    },
    {
      "race"  : "ORC",
      "age"   : "26",
      "name"  : "Rz'Ul"
    }
  ]
}

I want to retrieve the data from races or npc separately on demand. I am using genson to parse JSON. I parse it like this

@SuppressWarnings("unchecked")
public static <T> List<T> readJsonList(String listName) {
    Genson genson = JsonContext.PARSER.getParser();
    List<T> result = null;
    try (InputStream is = JsonDataProcessor.class.getResourceAsStream(FILE)) {
        ObjectReader reader = genson.createReader(is);
        reader.beginObject();
        while (reader.hasNext()) {
            reader.next();

            if ("races".equals(listName) && "races".equals(reader.name())) {
                result = (List<T>) processRaceData(reader);
                break;
            }

            if ("npc".equals(listName) && "npc".equals(reader.name())) {
                result = (List<T>) processNpcData(reader);
                break;
            }

        }
        reader.endObject();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return result;
}

And for example the method to parse races looks like this

private static List<Race> processRaceData(ObjectReader reader) {
    List<Race> raceList = new ArrayList<>();
    reader.beginArray();
    while (reader.hasNext()) {
        reader.next();

        Race race = new Race();
        reader.beginObject();
        while (reader.hasNext()) {
            reader.next();

            if ("name".equals(reader.name())) { race.setName(reader.valueAsString()); }
            else { reader.skipValue(); }
        }
        reader.endObject();
        raceList.add(race);
    }
    reader.endArray();
    return raceList;
}

In debug it populates variable result just fine, but on endObject line I get exception

Exception in thread "main" com.owlike.genson.stream.JsonStreamException: Illegal character at row 11 and column 4 expected } but read ',' !
        at com.owlike.genson.stream.JsonReader.newWrongTokenException(JsonReader.java:942)
        at com.owlike.genson.stream.JsonReader.end(JsonReader.java:428)
        at com.owlike.genson.stream.JsonReader.endObject(JsonReader.java:177)
        at com.lapots.breed.platform.json.JsonDataProcessor.readJsonList(JsonDataProcessor.java:41)
        at com.lapots.breed.platform.Example.prepareDb(Example.java:18)
        at com.lapots.breed.platform.Example.main(Example.java:23)

What is the problem?


Solution

  • I played with your code and found that genson is expecting to close object and check } symbol when you call endObject. You just need to skip object with reader.skipValue(). So error is in your while block in readJsonList method. This piece of code should work good for you:

     @SuppressWarnings("unchecked")
     public static <T> List<T> readJsonList(String listName) {
     . . .
     while (reader.hasNext()) {
         reader.next();
         if ("races".equals(listName) && "races".equals(reader.name())) {
             result = result = (List<T>) processRaceData(reader);
             break;
         }
         if ("npc".equals(listName) && "npc".equals(reader.name())) {
             result = result = (List<T>) processNpcData(reader);
             break;
         }
         reader = reader.skipValue();
     }
     reader.endObject();
     . . .