Your JSON
has one tricky element - label arrays contain one-element
JSON object
. We can unwrap it using custom deserialiser. To do that let's create simple POJO
structure which fit's JSON
payload. JSON
starts from [
so it means we need to parse it as an array. All elements have the same structure. We can define it like below:
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 +
'}';
}
}
When we want to use another name for property in Java
comparing to what we have in JSON
we use SerializedName
annotation. To inform Gson
library that we would like to handle given element in a specific way we use JsonAdapter
annotation. In case we do not know how to write custom deserialiser it is always safe to use Map<String, Object>
type for unknown or random JSON
object. In case we have list of objects we can use List<Map<String, Object>>
. Let's write simple deserialiser for labels arrays:
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();
}
}
Algorithm is quite simple: if given element is an array, iterate over it and take each object one-by-one. For each object get all keys and add corresponding values to labels
list which is our result of deserialisation process. Example usage, could look like this:
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);
}
}
Above code prints:
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]}
Read also: