2014-11-21 2 views
1

Say Я строй своего объекта GSON как этогоRename карта ключей в GSON по FieldNamingPolicy

new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create(); 

и теперь я хочу десериализацию следующего JSON

{ 
    "MyMap" : { 
     "Key1" : "Foo", 
     "Key2" : "Bar" 
    } 
} 

в следующий класс (который работает просто отлично)

public class MapClass { 
    Map<String,String> myMap; 
} 

, но я также хотел бы ключи, чтобы быть названным «key1» и «key2». Как я могу это сделать?

+0

Почему вы не перебирать MyMap карты после десериализации и заменить Key1 на ключом1 и Key2 с key2? – Devrim

+0

Это, очевидно, один из способов. Но я использую объект GSON во всем проекте и хотел бы иметь его автоматически. –

+0

Поле FieldNamingPolicy применяется к полям. Значения hashmap не являются fiedls, поэтому это нормально, что FieldNamingPolicy.UPPER_CAMEL_CASE применяется только к MyMap. В любом случае, вы можете написать настраиваемый TypeAdapter и управлять процессом десериализации сериализации. (переименование ключей карты было бы намного легче.) – Devrim

ответ

0

Вы можете попробовать таким образом:

try { 
      JSONObject jObj = new JSONObject("{" 
        + " \"MyMap\" : {" 
        + "  \"Key1\" : \"Foo\"," 
        + "  \"Key2\" : \"Bar\"" 
        + " }" 
        + "}"); // this parses the json 
      JSONObject jObjt = jObj.getJSONObject("MyMap"); 

      //old version with out GSON 
      Map<String, String> map = new HashMap(); 
      Iterator itr = jObjt.keys(); 
      while (itr.hasNext()) { 
       String key = (String) itr.next(); 
       String value = jObjt.getString(key); 
       map.put(key, value); 
      } 

      //desalinized one with GSON    
      Map<String, String> map1 = new Gson().fromJson(jObjt.toString(), HashMap.class); 
      for (String str : map1.keySet()) { 
       System.out.println("k:" + str + " v:" + map1.get(str)); 
      } 


     } catch (JSONException ex) { 
      //log the error 
    } 
+0

Если бы я сделал это вручную, мне не понадобилось бы использовать GSON. Кроме того, данные будут динамически структурированы. –

+0

вы можете опровергнуть его на карте как: HashMap map = new Gson(). FromJson (jObjt.toString(), HashMap.class); Я просто редактирую свой код. – Jay

0

FieldNamingPolicy применяется к полям значения JSon. Невозможно применить это к ключам карт (карте с ключами, парами значений) в json.

Простое решение: После десериализации, перейдите по карте и переименуйте имена ключей. то есть Key1 - key1 и Key2 - key2.

Другое решение:

Написать собственный TypeAdapter, который обрабатывает процесс десериализации и переименовывает ключи.

public class MapClassTypeAdapter extends TypeAdapter<MapClass> { 

    @Override 
    public MapClass read(JsonReader in) throws IOException { 
     final MapClass mapClassInstance = new MapClass(); 
     mapClassInstance.myMap = new HashMap<String, String>(); 

     in.beginObject(); 

     if("myMap".equalsIgnoreCase(in.nextName())) { 
      in.beginObject(); 
      while (in.hasNext()) { 
       String key = in.nextName(); 
       // You want keys as camel case 
       String newKey = key.substring(0,1).toLowerCase() + key.substring(1); 
       String value = in.nextString(); 

       mapClassInstance.myMap.put(newKey, value); 
      } 
      in.endObject(); 
     } 
     in.endObject(); 
     return mapClassInstance; 
    } 

    @Override 
    public void write(JsonWriter out, MapClass mapClass) throws IOException { 
     throw new RuntimeException("MapClassTypeAdapter.write method not implemented yet!"); 
    } 
} 

испытания Другое решение:

String json = "{\"myMap\":{\"Key1\":\"Foo\",\"Key2\":\"Bar\"}}"; 

final GsonBuilder gsonBuilder = new GsonBuilder(); 
gsonBuilder.registerTypeAdapter(MapClass.class, new MapClassTypeAdapter()); 
final Gson gson = gsonBuilder.create(); 

MapClass mapClass = gson.fromJson(json, MapClass.class); 
Смежные вопросы