Как десериализовать многопрофильный JSON ответ с помощью GSON и Retrofit2? - PullRequest
2 голосов
/ 26 января 2020

У меня есть restApi, его ответ может быть примерно таким (если есть только один объект для возврата):

{
    "keys":
    {
        "id":0,
        "name":"john",
        "pItems":12
    }
}

или таким, если есть еще:

{
    "keys":
    [
        {
            "id":0,
            "name":"john",
            "pItems":12
        },
        {
            "id":0,
            "name":"john",
            "pItems":12
        }
    ]
}

Когда я использую список для объекта Model, первый случай не работает. Как я могу десериализовать его с помощью Gson и Retrofit2?

Ответы [ 2 ]

1 голос
/ 27 января 2020

Вы можете проверить, является ли элемент keys массивом или нет, и затем соответственно десериализовать.

Предполагается, что класс вашей модели - 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;
    }

}

Пользователь. java - это класс, соответствующий каждому элементу 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()));

    }

}
1 голос
/ 27 января 2020

Хорошо, вы не можете изменить дизайн ответа, но уверены, что можете получать только эти ответы? Если это так, может быть, вы можете создать что-то вроде этого:

class Response{
    public Object keys
}

class UserResponse{
    public int id;
    public String name;
    public int pItems; 
}

Таким образом, у вас будет два случая:

  1. вы можете получить объект UserResponse
  2. Вы можете получить список объектов UserResponse

Затем, чтобы проверить, является ли список UserResponse, может быть что-то вроде этого:

if (keys instanceof List<?>){
    // then keys is a list 
}else{
    // then keys is a single object UserResponse
}
...