手动解析Gson反序列化器旁边的一部分动态JSON对象



我想用一个动态JSON对象解析以下JSON响应

{
  "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类,但不能将它们从map中提取出来。

 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. 使用双重解析技术手动解析特定部分和Gson中的其余响应?

我想把动态对象包装成一个pojo类。

您需要两样东西。

  1. 您需要对模型类进行一些重构
  2. 您需要添加一个JsonDeserializer来处理动态解析

我会这样做:

MainObject.java

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

SalesPoints.java

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

计数器.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..方法,因为我不可能测试代码,但这是一种方法,你可以很容易地调试它。

编辑

对于改装,你需要做这样的事情:

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.

最新更新