少なくとも2つのオプションがあります。命令型とGson型です。
不可欠オプションでは、あなたは、単にステップでGson施設のステップを使用して、指定されたJSONのための全体JSONツリー解析することができます:
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);
少し汚れが、そうではありません?。出力:
{1 = [1、2、3、4] 2 = [5、6]、3 = [3,4]}
代替カスタムを作っていますJSONのデシリアライズをより正確にバインドするために、Gson TypeToken
の特別なマーカーになる擬似DTO。例:
abstract class FakeInt {
private FakeInt() {
throw new AssertionError("Not meant to be instantiated");
}
}
これは、プライベートコンストラクタがエラーをスローする抽象クラスであるため、外部でインスタンス化することはできません。そしてそれは決してあってはならない、ただのマーカだ。
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);
}
}
このデシリアライザはid
特性を有するJSON配列要素を認識している:それは親オブジェクトから取得だ後、idElement
はInteger
値を抽出するために下流パーサに委任されています。 idElement.getAsInt()
を使用することは可能ですが、Gson
構成全体を尊重するためにidElement
が委任されています(Integer
クラスの特別なルールがあります)。そして、どのように偽のDTOクラスとそのJSONデシリアライザの仕事を一緒:
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);
注Gson
インスタンスがハックやチートの一種で構築されていること:FakeInt
クラスができる唯一のリターンカスタムデシリアライザにバインドされていますInteger
値またはnull
です。型とそのデシリアライザがバインドされると、Gson
インスタンスが使用可能になり、指定されたJSONは、整数のリストのマップであるかのように、のように解析できます。次のように正確に同じ出力である:
{1 = [1、2、3、4] 2 = [5、6]、3 = [3,4]}