Преобразование Guava HashMultimap в json
Я хочу напечатать HashMultiMap как json.
HashMultimap<String,Object> multimap = HashMultimap.create();
multimap.put("a",Obj1);
multimap.put("a",Obj3);
multimap.put("b",Obj2);
к
{
"a":[Obj1,Obj3],
"b":[Obj2]
}
Obj1 и другие объекты снова должны быть в json (чтобы сохранить его в чистоте, я показал его как объекты)
Я могу перебирать отдельные ключи и преобразовывать набор объектов в json, используя библиотеки, такие как Gson.
Но чтобы получить весь снимок HashMultimap, я хочу преобразовать его в json и проверить его.
Gson не смог преобразовать всю карту, но мог делать отдельные значения (список объектов для json)
Ответы
Ответ 1
Сначала вызовите asMap()
на MultiMap. Это преобразует MultiMap в стандартную карту, где каждое значение представляет собой коллекцию.
В вашем примере тип результирующей карты Map<String, Collection<Object>>
. Gson должен иметь возможность сериализовать это правильно.
Ответ 2
Вам нужно написать JsonAdapter
или оба JsonDeserializer
и JsonSerializer
. Это довольно страшно, но я хотел попробовать.
В принципе, вы делегируете все в Map<String, Collection<V>>
.
static class MultimapAdapter implements JsonDeserializer<Multimap<String, ?>>, JsonSerializer<Multimap<String, ?>> {
@Override public Multimap<String, ?> deserialize(JsonElement json, Type type,
JsonDeserializationContext context) throws JsonParseException {
final HashMultimap<String, Object> result = HashMultimap.create();
final Map<String, Collection<?>> map = context.deserialize(json, multimapTypeToMapType(type));
for (final Map.Entry<String, ?> e : map.entrySet()) {
final Collection<?> value = (Collection<?>) e.getValue();
result.putAll(e.getKey(), value);
}
return result;
}
@Override public JsonElement serialize(Multimap<String, ?> src, Type type, JsonSerializationContext context) {
final Map<?, ?> map = src.asMap();
return context.serialize(map);
}
private <V> Type multimapTypeToMapType(Type type) {
final Type[] typeArguments = ((ParameterizedType) type).getActualTypeArguments();
assert typeArguments.length == 2;
@SuppressWarnings("unchecked")
final TypeToken<Map<String, Collection<V>>> mapTypeToken = new TypeToken<Map<String, Collection<V>>>() {}
.where(new TypeParameter<V>() {}, (TypeToken<V>) TypeToken.of(typeArguments[1]));
return mapTypeToken.getType();
}
}
Полный код, содержащий тест, можно найти здесь.