动态解析改造响应

时间:2018-10-06 22:13:28

标签: android json networking retrofit2 android-networking

我在解析动态改造响应时遇到问题。我有这样的响应,并且“跟踪历史记录”中可以有很多对象,每个对象都有不同的名称。 我尝试在跟踪历史记录中创建对象列表,但是由于它们具有不同的名称,因此无法创建列表。我应该如何解析?

{
"TrackingHistory": {
    "0": {
        "Activity Date": "Aug 6, 2018 14:51:00 PM",
        "Status": "Delivered  SELF MALIK"
    },
    "1": {
        "Activity Date": "Aug 6, 2018 08:08:53 AM",
        "Status": "Assign to Courier"
    },
    "2": {
        "Activity Date": "Aug 6, 2018 07:30:17 AM",
        "Status": "Inter Transfer"
    },
    "3": {
        "Activity Date": "Aug 4, 2018 19:16:54 PM",
        "Status": "Inter Transfer"
    },
    "4": {
        "Activity Date": "Aug 4, 2018 17:16:57 PM",
        "Status": "Inter Transfer"
    },
    "5": {
        "Activity Date": "Aug 4, 2018 07:40:52 AM",
        "Status": "Assign to Courier"
    },
    "6": {
        "Activity Date": "Aug 4, 2018 03:36:06 AM",
        "Status": "Inter Transfer"
    },
    "7": {
        "Activity Date": "Aug 4, 2018 02:55:39 AM",
        "Status": "Arrived at Station LAHORE"
    },
    "8": {
        "Activity Date": "Aug 2, 2018 19:19:14 PM",
        "Status": "Arrived at Station ISLAMABAD"
    },
    "9": {
        "Activity Date": "Aug 4, 2018 15:48:11 PM",
        "Status": "Posted for Consignment Booking at RAWALPINDI"
    }
}

}

2 个答案:

答案 0 :(得分:4)

为此,您可以尝试使用自定义解串器,无论您将其配置为什么,它都可以处理转换。

首先,您的内部对象将需要一个类,因为它会重复很多:

class Foo { //call this whatever you like
    @SerializedName("Activity Date")  // tell gson which Json field correspond to which class field
    public String activityDate;
    @SerializedName("Status")
    public String status;
}

那么您的TrackingHistory将会是这样:

public class TrackingHistory {
    public List<Foo> history;

    public TrackingHistory(List<Foo> list) {
        history = list;
    }
}

现在您可以创建一个反序列化器类:

public class TrackingHistoryDeserializer implements JsonDeserializer<TrackingHistory> {

    private Foo parseFoo(JsonElement element) { //this function tries to convert aJsonElement to a Foo class
        if (element.isJsonObject()) {
            JsonObject obj = element.getAsJsonObject();
            return new Gson().fromJson(obj, Foo.class);

        }
        else
            return null;
    }

    @Override
    public Card deserialize(JsonElement paramJsonElement, Type paramType,
                            JsonDeserializationContext paramJsonDeserializationContext) throws JsonParseException { 
        List<Foo> history = new ArrayList<>();
        // iterate through all objects contained in the json:
        for (Map.Entry<String,JsonElement> entry : object.entrySet()) {
            Foo foo = parseFoo(entry.getValue());  // parse the value associated to the current key
            if (foo != null)
                history.add(foo);
        }
        return new TrackingHistory(history);
    }
}

最后,在构建改造服务时,您需要添加解串器:

Gson gson = new GsonBuilder().registerTypeAdapter(TrackingHistory.class, new TrackingHistoryDeserializer()).create();
YourRetrofitService service = new Retrofit.Builder().client(client)
    .baseUrl(YOURENDPOINT)
    .addConverterFactory(GsonConverterFactory.create(gson))
    .addConverterFactory(ScalarsConverterFactory.create())
    .build().create(YourRetrofitService.class);

然后它应该在您声明这样的内容时起作用:

@GET("url") // or POST or whatever needed
Call<TrackingHistory> getTrackingHistory();

答案 1 :(得分:1)

我建议您应该将其作为Json对象并通过自己进行解析。另外请注意JsonObject,因为JSONObject在这里无法解决!

@Override
        public void getDetails(final String trackingNumber, String courier, String title) {
            postDetailModel = new PostDetailModel(trackingNumber, title, courier);
            final SharedPrefs sharedPrefs = new SharedPrefs(context);

            Retrofit retrofit = NetworkClient.getRetrofit();
            final RecordDetail recordDetail = retrofit.create(RecordDetail.class);

            Call<JsonObject> call = recordDetail.postRecords(sharedPrefs.getStringValue("token", null), postDetailModel);

            call.enqueue(new Callback<JsonObject>() {
                @Override
                public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
                    Log.i("Result: Running", " ");
                    arrayList = new ArrayList<>();
                    try {
                        JsonObject trackingobj = response.body();
                        JsonObject TrackingHistory = trackingobj.getAsJsonObject("TrackingHistory");
                        Log.i(TAG, "TrackRecord "+TrackingHistory.toString());


                        for(int i=0; i < TrackingHistory.size(); i++) {
                            JsonObject SingleRecord = TrackingHistory.getAsJsonObject(Integer.toString(i));
                            String ActivityDate = SingleRecord.get("Activity Date").toString();
                            String Status = SingleRecord.get("Status").toString();
                            com.couriertrackingapp.trackstack.RecordDetails.Model.TrackingHistory trackingHistory = new TrackingHistory(ActivityDate, Status);

                            arrayList.add(trackingHistory);
                        }
                        //trackingHistory_arr 2D Array with 2 Columns. 1 Column Activity Date, 2 Column Status
                    }catch(Exception e){
                        Log.i(TAG, e.toString());
                    }

                    recordDetailView.onSuccess(arrayList);
                }

                @Override
                public void onFailure(Call<JsonObject> call, Throwable t) {
                    Log.i(TAG, "onFailure: " + t.toString());
                    recordDetailView.onError();
                }
            });


        }