Ваш JSON
имеет один хитрый элемент - массивы меток содержат one-element
JSON object
.Мы можем развернуть его, используя специальный десериализатор.Для этого давайте создадим простую POJO
структуру, которая соответствует JSON
полезной нагрузке.JSON
начинается с [
, поэтому это означает, что мы должны проанализировать его как массив.Все элементы имеют одинаковую структуру.Мы можем определить его следующим образом:
class Phrase {
private String label;
private String domain;
@JsonAdapter(StringWrapperJsonDeserializer.class)
@SerializedName("synonymlabels")
private List<String> synonymLabels;
@JsonAdapter(StringWrapperJsonDeserializer.class)
@SerializedName("childrenlabels")
private List<String> childrenLabels;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
public List<String> getSynonymLabels() {
return synonymLabels;
}
public void setSynonymLabels(List<String> synonymLabels) {
this.synonymLabels = synonymLabels;
}
public List<String> getChildrenLabels() {
return childrenLabels;
}
public void setChildrenLabels(List<String> childrenLabels) {
this.childrenLabels = childrenLabels;
}
@Override
public String toString() {
return "Phrase{" +
"label='" + label + '\'' +
", domain='" + domain + '\'' +
", synonymLabels=" + synonymLabels +
", childrenLabels=" + childrenLabels +
'}';
}
}
Когда мы хотим использовать другое имя для свойства в Java
по сравнению с тем, что мы имеем в JSON
, мы используем SerializedName
аннотацию.Чтобы сообщить библиотеке Gson
, что мы хотим обрабатывать данный элемент определенным образом, мы используем аннотацию JsonAdapter
.В случае, если мы не знаем, как написать собственный десериализатор, всегда безопасно использовать тип Map<String, Object>
для неизвестного или случайного объекта JSON
.Если у нас есть список объектов, мы можем использовать List<Map<String, Object>>
.Давайте напишем простой десериализатор для массивов меток:
class StringWrapperJsonDeserializer implements JsonDeserializer<List<String>> {
@Override
public List<String> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json.isJsonArray()) {
final JsonArray array = (JsonArray) json;
final int size = array.size();
if (size == 0) {
return Collections.emptyList();
}
List<String> labels = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
JsonObject jsonElement = (JsonObject) array.get(i);
Set<String> keys = jsonElement.keySet();
for (String key : keys) {
labels.add(jsonElement.getAsJsonPrimitive(key).getAsString());
}
}
return labels;
}
return Collections.emptyList();
}
}
Алгоритм довольно прост: если данный элемент является массивом, выполните итерацию по нему и возьмите каждый объект один за другим.Для каждого объекта получите все ключи и добавьте соответствующие значения в список labels
, который является нашим результатом процесса десериализации.Пример использования, может выглядеть следующим образом:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
public class GsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
Phrase[] phrases = gson.fromJson(new FileReader(jsonFile), Phrase[].class);
Stream.of(phrases).forEach(System.out::println);
}
}
Надпечатки кода выше:
Phrase{label='Hospital', domain='Health_Care', synonymLabels=[SHCO, HCO], childrenLabels=[Childern_Hospital, Mental_Hospital, Heart_Hospital, Orthopadic_Hospital, General_Hospital, Gynac_Hospital, Cancer_Hospital, Burn_Hospital, Trauma_Care_Hospital]}
Phrase{label='Doctor', domain='Health_Care', synonymLabels=[Clinician, Physician, Medical_Practitioner], childrenLabels=[Cardiaologist, Allergist, Nurologist, Gynacologist, General_Physician, Anesthetist, Physiotherapist, Urologist, Oncologist, Homeopath, Dentist]}
Читайте также: