如何使用 GSON 和 Retrofit2 反序列化多形状 JSON 响应?
How to deserialize a multi-shape JSON response with GSON and Retrofit2?
我有一个 restApi,它的响应可以是这样的(如果 return 只有一个对象):
{
"keys":
{
"id":0,
"name":"john",
"pItems":12
}
}
如果还有的话像这样:
{
"keys":
[
{
"id":0,
"name":"john",
"pItems":12
},
{
"id":0,
"name":"john",
"pItems":12
}
]
}
当我为模型对象使用列表时,第一种情况不起作用。
我如何使用 Gson 和 Retrofit2 反序列化它?
好的,您不能更改响应的设计,但您确定只能收到那些响应吗?如果是这样,也许你可以创建这样的东西:
class Response{
public Object keys
}
class UserResponse{
public int id;
public String name;
public int pItems;
}
所以你会有两种情况:
- 您可以收到一个 UserResponse 对象
- 您可以收到一个 UserResponse 对象列表
然后验证是否是 UserResponse 列表,可以是这样的:
if (keys instanceof List<?>){
// then keys is a list
}else{
// then keys is a single object UserResponse
}
您可以检查 keys
元素是否为数组,然后相应地反序列化。
假设,您的模型 class 是 UserWrapper.java
import java.util.List;
public class UserWrapper {
private List<User> keys;
public List<User> getKeys() {
return keys;
}
public void setKeys(List<User> keys) {
this.keys = keys;
}
}
User.java是class对应keys
属性的每个元素。
public class User {
private int id;
private String name;
private int pitems;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPitems() {
return pitems;
}
public void setPitems(int pitems) {
this.pitems = pitems;
}
}
根据 keys
的类型进行反序列化的代码
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
public class GsonMain{
private static String json = "YOUR JSON";
public static void main(String[] args) {
Gson gson = new GsonBuilder().create();
JsonElement jsonElement = gson.fromJson(json, JsonElement.class);
JsonElement keyselement = jsonElement.getAsJsonObject().get("keys");
UserWrapper userWrapper = new UserWrapper();
if (keyselement.isJsonObject()) {
userWrapper.setKeys(new ArrayList<User>());
User user = gson.fromJson(keyselement, User.class);
userWrapper.getKeys().add(user);
} else if (keyselement.isJsonArray()) {
List<User> users = gson.fromJson(keyselement, new TypeToken<List<User>>() {
}.getType());
userWrapper.setKeys(users);
}
userWrapper.getKeys().forEach(user -> System.out.println(user.getName()));
}
}
我有一个 restApi,它的响应可以是这样的(如果 return 只有一个对象):
{
"keys":
{
"id":0,
"name":"john",
"pItems":12
}
}
如果还有的话像这样:
{
"keys":
[
{
"id":0,
"name":"john",
"pItems":12
},
{
"id":0,
"name":"john",
"pItems":12
}
]
}
当我为模型对象使用列表时,第一种情况不起作用。 我如何使用 Gson 和 Retrofit2 反序列化它?
好的,您不能更改响应的设计,但您确定只能收到那些响应吗?如果是这样,也许你可以创建这样的东西:
class Response{
public Object keys
}
class UserResponse{
public int id;
public String name;
public int pItems;
}
所以你会有两种情况:
- 您可以收到一个 UserResponse 对象
- 您可以收到一个 UserResponse 对象列表
然后验证是否是 UserResponse 列表,可以是这样的:
if (keys instanceof List<?>){
// then keys is a list
}else{
// then keys is a single object UserResponse
}
您可以检查 keys
元素是否为数组,然后相应地反序列化。
假设,您的模型 class 是 UserWrapper.java
import java.util.List;
public class UserWrapper {
private List<User> keys;
public List<User> getKeys() {
return keys;
}
public void setKeys(List<User> keys) {
this.keys = keys;
}
}
User.java是class对应keys
属性的每个元素。
public class User {
private int id;
private String name;
private int pitems;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPitems() {
return pitems;
}
public void setPitems(int pitems) {
this.pitems = pitems;
}
}
根据 keys
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
public class GsonMain{
private static String json = "YOUR JSON";
public static void main(String[] args) {
Gson gson = new GsonBuilder().create();
JsonElement jsonElement = gson.fromJson(json, JsonElement.class);
JsonElement keyselement = jsonElement.getAsJsonObject().get("keys");
UserWrapper userWrapper = new UserWrapper();
if (keyselement.isJsonObject()) {
userWrapper.setKeys(new ArrayList<User>());
User user = gson.fromJson(keyselement, User.class);
userWrapper.getKeys().add(user);
} else if (keyselement.isJsonArray()) {
List<User> users = gson.fromJson(keyselement, new TypeToken<List<User>>() {
}.getType());
userWrapper.setKeys(users);
}
userWrapper.getKeys().forEach(user -> System.out.println(user.getName()));
}
}