2016-07-19 4 views
0

я хочу разобрать следующий ответ JSON с динамическим объектом JSON,вручную разобрать часть динамического объекта JSON наряду с Gson десериализатор

{ 
    "id": 1, 
    "last_login": "2016-07-16T12:46:29.621996Z", 
    "point_of_sales": [ 
    { 
     "Counter 4": { 
     "type": "retail", 
     "id": 6 
     } 
    }, 
    { 
     "Counter 5": { 
     "type": "retail", 
     "id": 7 
     } 
    }, 
    { 
     "Counter 6": { 
     "type": "retail", 
     "id": 8 
     } 
    } 
    ] 
} 

Здесь имя объектов внутри «point_of_sales» массив динамичны, что делает его трудно разобрать с помощью Gson. Вот что я пытался до сих пор,

@SerializedName("id") 
@Expose 
private Integer id; 
@SerializedName("last_login") 
@Expose 
private String lastLogin; 
@SerializedName("point_of_sales") 
@Expose 
private List<Map<String, Counter>> pointOfSales = new ArrayList<Map<String, Counter>>(); 

....... 

getter & setters 

Счетчик класса,

@SerializedName("type") 
@Expose 
private String type; 
@SerializedName("id") 
@Expose 
private Integer id; 

....... 

getter & setters 

Следуя этой процедуре, можно преобразовать объекты, но не может извлечь их из карты к классам Pojo.

for (Map<String, Counter> objectMap : response.getPointOfSales()) 
{ 
// How to extract the Counter pojo data from map list? 
} 

Я также попробовал этот путь, но ничего не работает,

ArrayList<Counter> pojos = new ArrayList<Counter>(); 
        try { 
         for (Map<String, Counter> objectMap : result.getPointOfSales()) { 
          Counter pojo = new Counter(); 
          for (Map.Entry<String, Counter> property : objectMap.entrySet()) { 
           Method setter = Counter.class.getMethod("set" + property.getKey().substring(0, 1).toUpperCase() + property.getKey().substring(1), property.getValue().getClass()); 
           setter.invoke(pojo, property.getValue()); 
          } 
          pojos.add(pojo); 
         } 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 

        for (Counter pojo : pojos) { 
         Log.e("result", "" + pojo.getId() + " " + pojo.getType()); 
        } 

Есть ли способ, чтобы разобрать конкретный массив, используя,

  1. Gson

  2. Использование duel parsing для синтаксического анализа конкретной части вручную и остальной части ответа в Gson?

Я хочу, чтобы динамические объекты были обернуты в класс pojo.

+1

вам нужен JsonDeserializer для этого. Если я правильно понимаю, чего вы хотите достичь – Blackbelt

+0

Я просто хочу сделать динамические объекты, завернутые в класс pojo, так что данные поля «id», «type» могут быть получены легко. –

+0

, тогда я думаю, что пользовательский [JsonDeserializer] (https://google.github.io/gson/apidocs/com/google/gson/JsonDeserializer.html) - это то, что вам нужно. – Blackbelt

ответ

1

Вам нужны две вещи.

  1. Вам нужно сделать немного рефакторинга на ваших классах моделей.
  2. Вам нужно будет добавить JsonDeserializer для обработки этого динамического разбора.

Вот как я бы это сделать:

MainObject.java

..... 
@SerializedName("point_of_sales") 
SalesPoints mSales Points 
..... 

SalesPoints.java

private List<Counter>mCounters; 
//getter & setters. 

Counter.java

SerializedName("type") 
private String type; 
@SerializedName("id") 
private int id; // use primitives instead of boxed primitives 
private String mCounterString; // maybe you need it. 

Теперь, когда вы будете запускать разборе вам придется сделать что-то вроде этого:

MainObject object = new GsonBuilder().registerTypeAdapter(SalesPoints.class, new JsonDeserializer<SalesPoints>() { 
     @Override 
     public SalesPoints deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
      SalesPoints sales = new SalesPoints(); 
      ArrayList<Counter>counters = new ArrayList<Counter>(); 
      JsonArray salesJson = json.getAsJsonArray(); 
      for(JsonElement object : json.getAsJsonArray()) { 
        Iterator<Map.Entry<String,JsonElement>> iterator = object.getAsJsonObject().entrySet().iterator(); 
        while (iterator.hasNext())){ 
          Map.Entry<String,JsonElement> entry = iterator.next(); 
          String counterString = entry.getKey(); 
          JsonElement counterObject = 
                entry.getValue(); 
          Counter counter = context.deserialize(counterObject, Counter.class); 
          counter.setCounterString(counterString); 
          counters.add(counter); 
         }   
      } 
      sales.setCounters(counters); 
      return sales; 
     } 
    }).create().fromJson(theJson); 

Теперь, когда MainObject обрабатывается он будет содержать SalesPoints, который содержит все счетчики.

ПРИМЕЧАНИЕ: Я мог бы написать некоторые слова, или я мог бы забыть добавить некоторые методы getAs.., потому что у меня не было возможности проверить код, но это путь, и вы можете легко отладить его.

EDIT

Для дооснащения вам нужно сделать что-то вроде этого:

Gson gson = new GsonBuilder().registerTypeAdapter(SalesPoints.class, new JsonDeserializer<SalesPoints>() { 
     @Override 
     public SalesPoints deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
      SalesPoints sales = new SalesPoints(); 
      ArrayList<Counter>counters = new ArrayList<Counter>(); 
      JsonArray salesJson = json.getAsJsonArray(); 
      for(JsonElement object : json.getAsJsonArray()) { 
        Iterator<Map.Entry<String,JsonElement>> iterator = object.getAsJsonObject().entrySet().iterator(); 
        while (iterator.hasNext())){ 
          Map.Entry<String,JsonElement> entry = iterator.next(); 
          String counterString = entry.getKey(); 
          JsonElement counterObject = 
                entry.getValue(); 
          Counter counter = context.deserialize(counterObject, Counter.class); 
          counter.setCounterString(counterString); 
          counters.add(counter); 
         }   
      } 
      sales.setCounters(counters); 
      return sales; 
     } 
    }).create(); 


new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create(gson))//set remaining things fro your retrofit builder. 
+0

Что такое «theJson» и «entry»? Фактически я использую Retrofit 2, чтобы выполнить процесс разбора и api callback. Я немного смущен тем, где и как использовать JsonDeserializer с Retrofit. –

+0

@FallingIntoInfinity Пожалуйста, проверьте мой отредактированный ответ. – danypata

Смежные вопросы