2

I would like to use this kind of Objects with json:

class Message{
    int code;
    String user;
    Map<List<String>, List<String>> profile;
}

it seems json can't handle Object keys as array, so I would need to tranfer them like that:

{
"code": 1,
"user": "John",
"profile": {
    "type,1": ["tester"],
    "lang,2": ["fr", "it", "en", "sp"],
    "rate,4": ["10", "1000"],
    "date,5": ["134118329", "1341973211"]

    }
}

or

{
"code": 1,
"user": "John",
"profile": {
    "type": [1,"tester"],
    "lang": [2,"fr", "it", "en", "sp"],
    "rate": [4,"10", "1000"],
    "date": [5,"134118329", "1341973211"]

    }
}

the first json is probably simpler, even if it relies on a hard string separator,

So with the first one it seems I have to write this huge adapter:

private static class MyAdapter implements JsonSerializer<Map<List<String>, List<String>>>,
        JsonDeserializer<Map<List<String>, List<String>>> {

    @Override   
    public JsonElement serialize(Map<List<String>, List<String>> m,
            Type type, JsonSerializationContext context) {

        JsonObject j = new JsonObject();
        for (Entry<List<String>, List<String>> e : m.entrySet() ){
            JsonArray jj=new JsonArray();
            for (String s : e.getValue()){
                jj.add(new JsonPrimitive(s));
            }
            j.add(e.getKey().get(0)+","+e.getKey().get(1), jj);
        }
        return j;
    }

    @Override
    public Map<List<String>, List<String>> deserialize(JsonElement json, Type type,
            JsonDeserializationContext arg2) throws JsonParseException {

        Map<List<String>, List<String>> m = new HashMap<List<String>, List<String>>();

        JsonObject jObject = json.getAsJsonObject();
        for (Entry<String, JsonElement> e : jObject.entrySet() ){
            List<String> key = new ArrayList<String>();
            List<String> value = new ArrayList<String>();
            for (String s : e.getKey().split(",") ){
                key.add(s);
            }
            for (JsonElement jj : e.getValue().getAsJsonArray() ){
                value.add(jj.getAsString());
            }
            m.put(key, value);
        }
        return m;
    }
}

...

GsonBuilder g = new GsonBuilder();
    g.registerTypeAdapter(Map.class, new MyAdapter());
    Gson gson = g.create();

Is there faster ways? I guess yes, the idea is just to split the key into a Map composite key, because each part of the key has an important meaning

thx, and sry for the edit

2 Answers2

1

This will not work.

Object declaration syntax according specification:

An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).

This:

{
    ["type", 1]: "tester",
    ["lang", 2]: ["fr", "it", "en", "sp"],
    ["rate", 4]: ["10", "1000"],
    ["date", 5]: ["134118329", "1341973211"]

}

is invalid, and therefore you can't read with Gson causing the following exception: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING

the name in front of json: aRequest = is invalid too.

Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
  • how could I do composite keys in Json? –  Jul 13 '12 at 20:09
  • 1
    {"key":["a","b"],"value":12} wouldn't be enough? – Francisco Spaeth Jul 13 '12 at 20:10
  • and with more than one it gives an Array? possible to deserialize it it in a Map? ["a", "b"] as key –  Jul 13 '12 at 20:17
  • no, the key property would be mapped to the Map key as list... just in the representation would be presented as a property named key – Francisco Spaeth Jul 13 '12 at 20:18
  • I don't understand, the idea is to have {"key":["a","b"],"value":12}, {"key":["a","c"],"value":14}, ... How would you put them in a KeyValue Map, to me you just can use arrays with that, BTw thx, I edited almost completely the question could you have a look again sry –  Jul 14 '12 at 12:10
1

For profile values, I don't know if there is better than Object unfortunately

It looks like a List<String> or String[] would be a natural fit, with special handling for the single value entry that is not in a list format.

Unfortunately, the issue of deserializing a JSON structure that is sometimes a list and sometimes an object has come up repeatedly on SO. Fortunately, so have solutions.

Community
  • 1
  • 1
Programmer Bruce
  • 64,977
  • 7
  • 99
  • 97
  • The question of this post was quite a moving target, with three different (changing) JSON structures. Is there still an open question? – Programmer Bruce Jul 23 '12 at 22:51
  • yes right the Q changed too much, now I'm just facing how to best manage a (a,b) composite key in Json which is not supported, it could be a new Q, thx your answer was helpful –  Jul 24 '12 at 20:11