Десериализация карты <Object, Object> с помощью GSon - PullRequest
8 голосов
/ 22 марта 2011

У меня есть карта, содержащая смесь типов, как в этом простом примере

final Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("a", 1);
map.put("b", "a");
map.put("c", 2);
final Gson gson = new Gson();
final String string = gson.toJson(map);
final Type type = new TypeToken<LinkedHashMap<String, Object>>(){}.getType();
final Map<Object, Object> map2 = gson.fromJson(string, type);
for (final Entry<Object, Object> entry : map2.entrySet()) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
}

То, что я получаю, это просто Object с, нет Integer с, нет String с. Выход выглядит как

a : java.lang.Object@48d19bc8
b : java.lang.Object@394a8cd1
c : java.lang.Object@4d630ab9

Можно это как-нибудь исправить? Я ожидаю, что такие простые случаи будут обрабатываться по умолчанию правильно.

Я знаю, что информация о типе не всегда может быть сохранена, и, возможно, 1 и "1" означают то же самое в JSON. Однако возвращать простые объекты, не содержащие содержимого, для меня просто бессмысленно.

Обновление: Сериализованная версия (то есть string выше) выглядит нормально:

{"a":1,"b":"a","c":2}

Ответы [ 5 ]

7 голосов
/ 22 марта 2011

Гсон не такой умный.Вместо этого предоставьте ясную и статичную структуру данных во вкусе Javabean-класса, чтобы Gson понимал, к какому типу должны быть десериализованы отдельные свойства.

Например,

public class Data {
    private Integer a;
    private String b;
    private Integer c;
    // ...
}

в сочетании с

Data data1 = new Data(1, "a", 2);
String json = gson.toJson(data1);
Data data2 = gson.fromJson(json, Data.class);

Обновление : в соответствии с комментариями набор ключей, кажется, не является фиксированным (хотя впоследствии вы можете преобразовать его вручную, не зная структуры заранее).Вы можете создать пользовательский десериализатор .Вот быстрый и грязный пример.

public class ObjectDeserializer implements JsonDeserializer<Object> {

    @Override
    public Object deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException {
        String value = element.getAsString();
        try {
            return Long.valueOf(value);
        } catch (NumberFormatException e) {
            return value;
        }
    }

}

, который вы используете следующим образом:

final Gson gson = new GsonBuilder().registerTypeAdapter(Object.class, new ObjectDeserializer()).create();
// ... 
4 голосов
/ 17 марта 2012

Обновление до Гсон 2,1 .Это печатает это:

a : 1.0
b : a
c : 2.0
4 голосов
/ 19 мая 2011
Gson gson = new GsonBuilder()
    .registerTypeAdapter(Object.class, new JsonDeserializer<Object>() {
      @Override
      public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonPrimitive value = json.getAsJsonPrimitive();
        if (value.isBoolean()) {
          return value.getAsBoolean();
        } else if (value.isNumber()) {
          return value.getAsNumber();
        } else {
          return value.getAsString();
        }
      }
    }).create();
0 голосов
/ 16 марта 2012

Если вам нужна строка JSON из Map<Object, Object>, я думаю, json-simple - лучший выбор, чем Gson.

Это краткий пример из http://code.google.com/p/json-simple/wiki/EncodingExamples:

//import java.util.LinkedHashMap;
//import java.util.Map;
//import org.json.simple.JSONValue;

Map obj=new LinkedHashMap();
obj.put("name","foo");
obj.put("num",new Integer(100));
obj.put("balance",new Double(1000.21));
obj.put("is_vip",new Boolean(true));
obj.put("nickname",null);
String jsonText = JSONValue.toJSONString(obj);
System.out.print(jsonText);

Результат: {"name":"foo","num":100,"balance":1000.21,"is_vip":true,"nickname":null}

Для декодирования см. http://code.google.com/p/json-simple/wiki/DecodingExamples.

0 голосов
/ 22 марта 2011

Вы храните данные на карте. Похоже, вам нужно привести объект к нужному вам типу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...