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