我正在使用Retrofit2和Gson来检索和解析从一个安静的Web服务到一个Android客户端的JSON字符串。
我有类似于以下模拟类的东西:
public class User {
String name;
String email;
String gender;
String phone;
String type;
//getters and setters.
}
2个子类(未来可能更多):
ShopOwner:
public class ShopOwner extends User {
String shopName;
String shopDescription;
Country shopCountry;
//getters and setters.
}
买方:
public class Buyer extends User {
float availableCredit;
long lastPurchase;
/getters and setters.
}
当我触发登录请求并成功登录时,我会收到以下JSON响应之一:
此:
{
"name": "John Doe",
"email": "john@doe.com",
"gender": "male",
"phone": "1234567890",
"type": "shop owner",
"shop_owner": {
"shop_name": "Flower Market",
"shop_description": "Fresh Flowers Everyday",
"shop_country": {
"name": "United Stated of America",
"short_name": "US"
}
}
}
或者这个:
{
"name": "John Doe",
"email": "john@doe.com",
"gender": "male",
"phone": "1234567890",
"type": "buyer",
"buyer": {
"available_credit": 200,
"last_purchase": 1527915600
}
}
所以我的问题是:
1)我收到的回复结构是否被认为是最佳实践"?或者后端的人应该重组响应,将超类和子类中的键组合成一个对象?这样我就可以简单地检查type属性,并相应地将对象解析为2个子类中的任何一个。
2)如果我收到的回复实际上是根据最佳实践构建的,我该如何有效地解析它? TypeAdapter似乎是一个荒谬的答案,因为,严重的是,我必须将所有值存储在等待来自流的类型键的变量中,这听起来不太好听!另一种方法是在User类中创建子类组合,我真的不喜欢这个解决方案,因为一个或另一个将始终为null,我相信继承是为了在这些情况下使用而创建的。
非常感谢您的帮助!
修改
换句话说,我认为必须使用TypeAdapter来处理这样的结构化JSON字符串是荒谬的,因为我认为JSON应该以适合继承概念的另一种方式构建。下面是我的示例中提供的简单模拟类的TypeAdapter读取方法的示例:
public User read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return null;
}
boolean isShopOwner = true;
User user = new User();
HashMap<String, String> values = new HashMap<>();
Country country = new Country();
reader.beginObject();
while (reader.hasNext()) {
String key = reader.nextName();
switch (key) {
case "shop_owner":
case "buyer":
if (key.equals("buyer"))
isShopOwner = false;
reader.beginObject();
while (reader.hasNext()) {
String key2 = reader.nextName();
if (key2.equals("country")) {
reader.beginObject();
while (reader.hasNext()) {
switch (reader.nextName()) {
case "name":
country.setName(reader.nextString());
break;
case "short_name":
country.setShortName(reader.nextString());
break;
}
}
reader.endObject();
}
else
values.put(key2, reader.nextString());
}
reader.endObject();
break;
default:
values.put(key, reader.nextString());
}
}
user.setName(values.get("name"));
user.setEmail(values.get("email"));
user.setGender(values.get("gender"));
user.setPhone(values.get("phone"));
user.setType(values.get("type"));
if (isShopOwner) {
ShopOwner shopOwner = user;
shopOwner.setShopName(values.get("shop_name"));
shopOwner.setShopDescription(values.get("shop_description"));
shopOwner.setCountry(country);
return shopOwner;
}
else {
Buyer buyer = user;
buyer.setAvailableCredit(values.get("available_credit"));
buyer.setLastPurchase(values.get("last_purchase"));
return buyer;
}
}
我的实际类更复杂,并且它们嵌入了许多对象,除了我必须检查我从read方法返回的实例这一事实,因为我真的不知道它是否会返回ShopOwner或Buyer对象。我相信必须有一个更清洁的方法!