简体   繁体   中英

Parsing JSON keys as field value

I have a translation JSON object that maps locales to messages and takes the following form:

{"en_US" : "English Text", "sp": "Spanish Text", "fr" : "French Text", ... }

Is there a way for me to map the JSON object as a list of the following class using gson?

class Translation {
   String locale, text;
}

I know I can parse it first as a map and then going through the map elements to create the Translation objects, but I'm not sure if there's a "gson" way of doing that.

There are two options. If you need to serialize and deserialize the data, you could write a custom TypeAdapter .

class TranslationTypeAdapter extends TypeAdapter<List<Translation>> {
    @Override
    public void write(JsonWriter out, List<Translation> list) throws IOException {
        out.beginObject();
        for(Translation t : list) {
            out.name(t.locale).value(t.text);
        }
        out.endObject();
    }

    @Override
    public List<Translation> read(JsonReader in) throws IOException {
        List<Translation> list = new ArrayList<>();
        in.beginObject();
        while(in.hasNext()) {
            list.add(new Translation(in.nextName(), in.nextString()));
        }
        in.endObject();
        return list;
    }
}

and then:

TypeToken typeToken = new TypeToken<List<Translation>>(){};
Type type = typeToken.getType();
Gson gson = new GsonBuilder().registerTypeAdapter(type, new TranslationTypeAdapter()).create();
List<Translation> list = gson.fromJson(new FileReader(new File("json")),type);

which outputs:

[Translation{locale='en_US', text='English Text'}, Translation{locale='sp', text='Spanish Text'}, Translation{locale='fr', text='French Text'}]

If, however, you only need to deserialize the data, you can just write a custom deserializer:

class TranslationDeserializer implements JsonDeserializer<List<Translation>> {
    @Override
    public List<Translation> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        List<Translation> list = new ArrayList<>();
        for(Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
            list.add(new Translation(entry.getKey(), entry.getValue().getAsString()));
        }
        return list;
    }
}

You register this deserializer with the GsonBuilder as in the first example. This yield the same output of course.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM