Android Retrofit 数组列表中的嵌套 JSON 对象

Posted

技术标签:

【中文标题】Android Retrofit 数组列表中的嵌套 JSON 对象【英文标题】:Android Retrofit nested JSON objects in arraylist 【发布时间】:2021-11-12 22:56:12 【问题描述】:

我正在使用 PokeApi 创建一个安卓应用。我正在使用 Retrofit 库来解析数据。 我的 API 如下所示:


  "abilities": [2 items],
  "base_experience": 64,
  "forms": [1 item],
  "game_indices": [20 items],
  "height": 7,
  "held_items": [],
  "id": 1,
  "is_default": true,
  "location_area_encounters": "https://pokeapi.co/api/v2/pokemon/1/encounters",
  "moves": [78 items],
  "name": "bulbasaur",
  "order": 1,
  "past_types": [], 
  "species": 2 items,
  "sprites": 10 items,
  "weight": 69,
  "stats": [
    
    "base_stat": 45,
    "effort": 0,
    "stat": 
       "name": "hp",
       "url": "https://pokeapi.co/api/v2/stat/1/"
     
   ,
   
   "base_stat": 49,
   "effort": 0,
   "stat": 
     "name": "attack",
     "url": "https://pokeapi.co/api/v2/stat/2/"
    
   ,
   .
   ....


我能够记录 nameweightheight 等值,但无法将项目作为数组获取,该数组位于值 stats 内。我还需要嵌套在stats 中的statnameurl)。 这就是我所做的。 这些是我的模型类。

public class PokeDetail 

    private String name;
    private String height;
    private String weight;

    @SerializedName("stats")
    @Expose
    private List<PokeStats> stats = null;

    public List<PokeStats> getStats() 
        return stats;
    

    public void setStats(List<PokeStats> stats) 
        this.stats = stats;
    

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public String getHeight() 
        return height;
    

    public void setHeight(String height) 
        this.height = height;
    

    public String getWeight() 
        return weight;
    

    public void setWeight(String weight) 
        this.weight = weight;
    



public class PokeStats 

    private String effort;

    public String getEffort() 
        return effort;
    

    public void setEffort(String effort) 
        this.effort = effort;
    


这是我的 MainActivity 的样子:

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://pokeapi.co/api/v2/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        PokeApiService pokeApiService = retrofit.create(PokeApiService.class);

        Call<PokeDetail> call = pokeApiService.getPokeDetails(pokeNum);

        call.enqueue(new Callback<PokeDetail>() 
            @Override
            public void onResponse(Call<PokeDetail> call, Response<PokeDetail> response) 
                if(!response.isSuccessful())
                    Log.i("ERROR", "onResponse: " + response.code());
                

                PokeDetail pokeDetails = response.body();
                Log.i("NAME", pokeDetails.getName());
                Log.i("Height", pokeDetails.getHeight());
                Log.i("Weight", pokeDetails.getWeight());
                List<PokeStats> p = pokeDetails.getStats();
                Log.i("ListDATA", p.toString());

            

            @Override
            public void onFailure(Call<PokeDetail> call, Throwable t) 
                Log.i("ERROR", t.getMessage());
            
        );

这是我的输出:

【问题讨论】:

【参考方案1】:

记录不正确的问题

您看到的是默认版本的toString,如果您想以自己的方式登录然后覆盖它。请参阅下面的示例类。

我需要嵌套在 stat 中的 stat(名称和 url)

您的PokeStats 类中需要有stat 键。

例子:

public class PokeStats 

    @SerializedName("base_stat")
    @Expose
    private Integer baseStat;
    @SerializedName("effort")
    @Expose
    private Integer effort;
    @SerializedName("stat")
    @Expose
    private Stat stat;

    public Integer getBaseStat() 
        return baseStat;
    

    public void setBaseStat(Integer baseStat) 
        this.baseStat = baseStat;
    

    public Integer getEffort() 
        return effort;
    

    public void setEffort(Integer effort) 
        this.effort = effort;
    

    public Stat getStat() 
        return stat;
    

    public void setStat(Stat stat) 
        this.stat = stat;
    


    @Override
    public String toString() 
        return "PokeStats" +
                "baseStat=" + baseStat +
                ", effort=" + effort +
                ", stat=" + stat.toString() +
                '';
    

& 嵌套的Stat 类:

public class Stat 

    @SerializedName("name")
    @Expose
    private String name;
    @SerializedName("url")
    @Expose
    private String url;

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public String getUrl() 
        return url;
    

    public void setUrl(String url) 
        this.url = url;
    

    @Override
    public String toString() 
        return "Stat" +
                "name='" + name + '\'' +
                ", url='" + url + '\'' +
                '';
    

建议:

如果您需要为此类错误响应创建课程,您可以使用这样的在线工具:https://www.jsonschema2pojo.org/

输入您的回复并选择JSONGSON 相应选项并生成类。

【讨论】:

以上是关于Android Retrofit 数组列表中的嵌套 JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章

Android Retrofit嵌套请求-RxJava 3

Android Retrofit嵌套请求-RxJava 3

Android Retrofit嵌套请求-RxJava 3

如何使用 Retrofit 和 Jackson 读取嵌套的 JSON 数组?

使用 Moshi/Retrofit2 访问深度嵌套的 JSON 数组

Android:使用 Retrofit 获取不同的对象列表数据