У меня есть объект перевода JSON, который отображает локали в сообщения и принимает следующий вид:
{"en_US" : "English Text", "sp": "Spanish Text", "fr" : "French Text", ... }
Есть ли способ сопоставить объект JSON как список следующего класса с помощью gson?
class Translation {
String locale, text;
}
Я знаю, что я могу сначала разобрать его как карту, а затем пройти через элементы карты, чтобы создать объекты перевода, но я не уверен, есть ли способ "gson" сделать это.
Есть два варианта. Если вам нужно сериализовать и десериализовать данные, вы можете написать собственный 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;
}
}
а потом:
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);
который выводит:
[Translation{locale='en_US', text='English Text'}, Translation{locale='sp', text='Spanish Text'}, Translation{locale='fr', text='French Text'}]
Если, однако, вам нужно только десериализовать данные, вы можете просто написать собственный десериализатор:
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;
}
}
Вы регистрируете этот десериализатор с помощью GsonBuilder
как в первом примере. Конечно, это дает тот же результат.