Sie haben mindestens zwei Optionen: Imperativ und der Gson Weg.
In der Imperativ Option, können Sie einfach die ganze JSON Baum für den gegebenen JSON parsen mit Gson Einrichtungen Schritt für Schritt:
final Gson gson = new GsonBuilder()
// any custom Gson configuration here
.create();
final Map<Integer, List<Integer>> map = new LinkedHashMap<>();
for (final Entry<String, JsonElement> e : gson.fromJson(JSON, JsonElement.class).getAsJsonObject().entrySet()) {
// parseInt() ignores additional type adapters in Gson
final Integer key = gson.fromJson(e.getKey(), Integer.class);
final List<Integer> list = new ArrayList<>();
@SuppressWarnings({ "unchecked", "rawtypes" })
final Iterable<JsonObject> asJsonArray = (Iterable) e.getValue().getAsJsonArray();
for (final JsonObject el : asJsonArray) {
final Integer integer = gson.fromJson(el.get("id"), Integer.class);
list.add(integer);
}
map.put(key, list);
}
out.println(map);
Ein bisschen schmutzig, ist es nicht ?. Der Ausgang:
{1 = [1, 2, 3, 4], 2 = [5, 6], 3 = [3, 4]}
Eine Alternative macht eine individuelle gefälschte DTO, die eine spezielle Markierung für Gson TypeToken
s wäre, um JSON-Deserialisierung genauer zu binden. Zum Beispiel:
Dies ist eine abstrakte Klasse mit einem privaten Konstruktor, der einen Fehler verursacht, so dass er nicht extern instanziiert werden kann. Und es sollte nie sein, es ist nur ein Marker.
final class FakeIntDeserializer
implements JsonDeserializer<Integer> {
private static final JsonDeserializer<Integer> fakeIntDeserializer = new FakeIntDeserializer();
private FakeIntDeserializer() {
}
static JsonDeserializer<Integer> getFakeIntDeserializer() {
return fakeIntDeserializer;
}
@Override
public Integer deserialize(final JsonElement json, final Type type, final JsonDeserializationContext context) {
final JsonElement idElement = json.getAsJsonObject().get("id");
return context.deserialize(idElement, Integer.class);
}
}
Diese Deserialisierer sind die JSON Array-Elemente bekannt, die id
Eigenschaft aufweisen: sobald es von dem übergeordneten Objekt erhalten wird, ist die idElement
einen nachgeschalteten Parser einen delegierte Integer
Wert zu extrahieren. Obwohl es möglich ist, idElement.getAsInt()
zu verwenden, wird idElement
delegiert, um die gesamte Gson
Konfiguration zu respektieren (Sie können spezielle Regeln für die Klasse Integer
haben). Und wie die gefälschte DTO-Klasse und ihre JSON Deserializer arbeiten zusammen:
final Type integerToFakeIntListType = new TypeToken<Map<Integer, List<FakeInt>>>() {
}.getType();
final Gson gson = new GsonBuilder()
.registerTypeAdapter(FakeInt.class, getFakeIntDeserializer())
.create();
final Map<Integer, List<Integer>> map = gson.fromJson(JSON, integerToFakeIntListType);
out.println(map);
Beachten Sie, dass die Gson
Instanz mit einer Art von einem Hack oder ein Betrüger gebaut: die FakeInt
Klasse der benutzerdefinierten Deserializer gebunden ist, die nur Rückkehr Integer
Werte oder null
. Sobald die Typen und ihre Deserialisierer gebunden sind, ist die Gson
Instanz bereit zu verwenden und der angegebene JSON kann geparst werden , als ob es eine Zuordnung von ganzen Zahlen zu Listen von ganzen Zahlen wäre. Genau die gleiche Ausgabe wie folgt:
{1 = [1, 2, 3, 4], 2 = [5, 6], 3 = [3, 4]}