read - tipo json java




Gson: C'è un modo più semplice per serializzare una mappa (4)

Predefinito

L'implementazione Gson predefinita della serializzazione della mappa utilizza toString() sulla chiave:

Gson gson = new GsonBuilder()
        .setPrettyPrinting().create();
Map<Point, String> original = new HashMap<>();
original.put(new Point(1, 2), "a");
original.put(new Point(3, 4), "b");
System.out.println(gson.toJson(original));

Darà:

{
  "java.awt.Point[x\u003d1,y\u003d2]": "a",
  "java.awt.Point[x\u003d3,y\u003d4]": "b"
}

Utilizzo di enableComplexMapKeySerialization

Se si desidera che la chiave della mappa sia serializzata in base alle regole Gson predefinite, è possibile utilizzare enableComplexMapKeySerialization . Ciò restituirà una matrice di matrici di coppie chiave-valore:

Gson gson = new GsonBuilder().enableComplexMapKeySerialization()
        .setPrettyPrinting().create();
Map<Point, String> original = new HashMap<>();
original.put(new Point(1, 2), "a");
original.put(new Point(3, 4), "b");
System.out.println(gson.toJson(original));

Tornerà:

[
  [
    {
      "x": 1,
      "y": 2
    },
    "a"
  ],
  [
    {
      "x": 3,
      "y": 4
    },
    "b"
  ]
]

Maggiori dettagli possono essere trovati enableComplexMapKeySerialization .

This link dal progetto Gson sembra indicare che dovrei fare qualcosa di simile al seguente per serializzare una mappa tipizzata in JSON:

    public static class NumberTypeAdapter 
      implements JsonSerializer<Number>, JsonDeserializer<Number>,
InstanceCreator<Number> {

    public JsonElement serialize(Number src, Type typeOfSrc, JsonSerializationContext
context) {
      return new JsonPrimitive(src);
    }

    public Number deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
        throws JsonParseException {
      JsonPrimitive jsonPrimitive = json.getAsJsonPrimitive();
      if (jsonPrimitive.isNumber()) {
        return jsonPrimitive.getAsNumber();
      } else {
        throw new IllegalStateException("Expected a number field, but was " + json);
      }
    }

    public Number createInstance(Type type) {
      return 1L;
    }
  }

  public static void main(String[] args) {
    Map<String, Number> map = new HashMap<String, Number>();    
    map.put("int", 123);
    map.put("long", 1234567890123456789L);
    map.put("double", 1234.5678D);
    map.put("float", 1.2345F);
    Type mapType = new TypeToken<Map<String, Number>>() {}.getType();

    Gson gson = new GsonBuilder().registerTypeAdapter(Number.class, new
NumberTypeAdapter()).create();
    String json = gson.toJson(map, mapType);
    System.out.println(json);

    Map<String, Number> deserializedMap = gson.fromJson(json, mapType);
    System.out.println(deserializedMap);
  }

È bello e funziona, ma sembra un sovraccarico ( una classe di tipo Type Adapter completa ) ? Ho usato altre librerie JSON come JSONLib e ti permettono di costruire una mappa nel seguente modo:

JSONObject json = new JSONObject();
for(Entry<String,Integer> entry : map.entrySet()){
     json.put(entry.getKey(), entry.getValue());
}

O se ho una classe personalizzata qualcosa come la seguente:

JSONObject json = new JSONObject();
for(Entry<String,MyClass> entry : map.entrySet()){
 JSONObject myClassJson =  JSONObject.fromObject(entry.getValue());
     json.put(entry.getKey(), myClassJson);
}

Il processo è più manuale, ma richiede molto meno codice e non ha il sovraccarico di dover creare un adattatore di tipo personalizzato per numero o nella maggior parte dei casi per la mia classe personalizzata .

È questo l'unico modo per serializzare una mappa con Gson, o qualcuno ha trovato un modo per battere quello che Gson raccomanda nel link qui sopra.


In Gson 2.7.2 è facile come

Gson gson = new Gson();
String serialized = gson.toJson(map);

Sono abbastanza sicuro che GSON serializza / deserializza le mappe e le mappe multiple nidificate (ad esempio Map<String, Map<String, Object>> ) per impostazione predefinita. L'esempio fornito credo non sia altro che un semplice punto di partenza se devi fare qualcosa di più complesso.

Guarda la classe MapTypeAdapterFactory nella fonte GSON: http://code.google.com/p/google-gson/source/browse/trunk/gson/src/main/java/com/google/gson/internal/bind/MapTypeAdapterFactory.java

Finché i tipi di chiavi e valori possono essere serializzati in stringhe JSON (e puoi creare i tuoi serializzatori / deserializzatori per questi oggetti personalizzati) non dovresti avere problemi.


Map<String, Object> config = gson.fromJson(reader, Map.class);




gson