0

Using Gson, I am trying to force my json objects to have an array value with one element. Although I construct the json this way, the JsonParser creates a new JsonObject in place of my array of length 1. The majority of json in my system have value with arrays greater than length 1 and parse correctly.

I discovered this while attempting a utility method for brute forcing a JsonObject to JsonArray. It's not working out as I would expect.

static JsonArray bruteForceJsonArray(JsonObject object, String key) {
    if(object.get(key).isJsonArray()) {
        return object.get(key).getAsJsonArray();
    } else {
        System.out.println("broken: " + object.toString());
        JsonObject temp = object.get(key).getAsJsonObject();
        String fixed = "{'" + key +  "':[" + temp.toString() + "]}";
        System.out.println("pre-fix: " + fixed);

        //parsing here reduces the array to an object - hot to prevent?     
        temp = new JsonParser().parse(fixed).getAsJsonObject();         
        System.out.println("fixed: " + object.toString());
        return object.get(key).getAsJsonArray();
    }
}

output:

broken: {"token":{"NER":"O","id":1.0,"word":".","CharacterOffsetEnd":765.0,"Speaker":"PER0","POS":".","lemma":".","CharacterOffsetBegin":764.0}}
pre-fix: {'token':[{"NER":"O","id":1.0,"word":".","CharacterOffsetEnd":765.0,"Speaker":"PER0","POS":".","lemma":".","CharacterOffsetBegin":764.0}]}
fixed: {"token":{"NER":"O","id":1.0,"word":".","CharacterOffsetEnd":765.0,"Speaker":"PER0","POS":".","lemma":".","CharacterOffsetBegin":764.0}}

An example of the majority json as they appear correctly in the system:

{"token":[{"Speaker":"PER0","POS":"IN","lemma":"except","CharacterOffsetBegin":742.0,"NER":"O","id":1.0,"word":"Except","CharacterOffsetEnd":748.0},{"CharacterOffsetEnd":752.0,"Speaker":"PER0","POS":"IN","lemma":"for","CharacterOffsetBegin":749.0,"NER":"O","id":2.0,"word":"for"},{"id":3.0,"word":"extra","CharacterOffsetEnd":758.0,"Speaker":"PER0","POS":"JJ","lemma":"extra","CharacterOffsetBegin":753.0,"NER":"O"},{"Speaker":"PER0","POS":"NN","lemma":"meat","CharacterOffsetBegin":759.0,"NER":"O","id":4.0,"word":"meat","CharacterOffsetEnd":763.0},{"CharacterOffsetEnd":764.0,"Speaker":"PER0","POS":".","lemma":".","CharacterOffsetBegin":763.0,"NER":"O","id":5.0,"word":"."}]}

Is there a clever way out of this problem - some way I can effectively force my objects into arrays so I can process them in stream without too much try/catch or if/else handling?

ThisClark
  • 14,352
  • 10
  • 69
  • 100
  • @Raniz Thanks. I'm not using additional classes. Only JsonArray and JsonObject. This may be the core of my problem, so I'm considering how to implement the approach you shared. I may have to write an adapter for various levels of my json where I would prefer to have a master method to rule them all. – ThisClark May 08 '15 at 04:19

1 Answers1

1
static JsonArray bruteForceJsonArray(JsonObject object, String key) {
    if (object.get(key).isJsonArray()) {
        return object.get(key).getAsJsonArray();
    } else {
        JsonArray oneElementArray = new JsonArray();
        oneElementArray.add(new JsonObject());
        return oneElementArray;
    }
}

Although, you shouldn't work with JsonObject/JsonArray directly. Make a POJO class for your data and use Gson to deserialize JSON.

Egor Neliuba
  • 14,784
  • 7
  • 59
  • 77
  • 1
    Thanks - this is really going to help me complete an academic project on time. Furthermore, I appreciate your recommendation against my approach. While searching around for a solution, I came across POJO a number of times. I also see ways I can serialize and deserialize from Java classes. It is clear I am not using Gson as effectively as I could be. – ThisClark May 08 '15 at 15:08