【问题标题】:How can Retrofit 2.0 parse nested JSON object?Retrofit 2.0 如何解析嵌套的 JSON 对象?
【发布时间】:2016-01-01 18:12:59
【问题描述】:

我们的团队决定使用Retrofit 2.0,我正在对该库进行一些初步研究。如标题所述,我想在我们的 Android 应用程序中通过 Retrofit 2.0 解析一些嵌套的 JSON 对象。

例如,here 是一个嵌套的 JSON 对象,格式为:

{
        "title": "Recent Uploads tagged android",
        "link": "https://www.flickr.com/photos/tags/android/",
        "description": "",
        "modified": "2015-10-05T05:30:01Z",
        "generator": "https://www.flickr.com/",
        "items": [
        {
            "title": ...
            "link": ...
            "media": {"m":"This is the value I want to get:)"}
            "description": ...
            "published": ...
            "author": ...
            "author_id": ...
            "tags": ...
        },
        {...},
        ...
        ]
}

我对 items 数组中的 JSON 对象感兴趣。我注意到有 some posts 关于通过 Retrofit 1.X 解析嵌套 JSON 对象,但最新的 Retrofit 2.0 API 发生了很大变化,这在适应新 API 时会令人困惑。

我想到了两种可能的解决方案:

  1. 编写我自己的 JSON 转换器工厂,扩展 Converter.Factory
  2. 以String类型返回原始响应并自行解析。但根据我最初的研究,要从 Retrofit 2.0 获得原始响应并不容易。 Retrofit 2.0 似乎坚持在将响应传递给我之前将其转换为某些内容,并且 Retrofit 不提供自己的StringConverter。 (我可能错了~)

更新:我们实际上可以通过将JSONElement设置为HTTP API接口的pojo并使用Retrofit提供的GSONConverter作为转换器来获得原始响应。

【问题讨论】:

  • items 数组中有什么?你也可以发布那部分吗?
  • @PankajKumar 更新:)
  • 我添加了一个类似于你的 JSON 的答案。试试看。
  • @PankajKumar 不错!如我更新的问题所示,我可以将 private JSONObject media 定义为我的 pojo 中的成员,而不是定义一个新的 Media 类,因为键 media 的值也是 JSON?
  • 没有。为此,您还需要一门课。

标签: android json retrofit


【解决方案1】:

假设您的完整 JSON 看起来像

{
  "title": "Recent Uploads tagged android",
  "link": "https://www.flickr.com/photos/tags/android/",
  "description": "",
  "modified": "2015-10-05T05:30:01Z",
  "generator": "https://www.flickr.com/",
  "items": [
    {
      "member1": "memeber value",
      "member2": "member value"
    },
    {
      "member1": "memeber value",
      "member2": "member value"
    }
  ]
}

所以 Pojo 类应该是

public class MainPojo {
    private String title; 
    private String description;
    private String link;
    private String generator;
    private String modified;
    private ArrayList<Items> items;

    // Getters setters
}

public class Items {
    private String member2;
    private String member1;

    // Getters setters
}

注意:这是您的 JSON 的类似解决方案。如果 JSON 有其他键,可以更改 Items.java 的成员。


将 Pojo 更新为新的 JSON

public class Items {
    private String tags;
    private String author;
    private String title;
    private String description;
    private String link;
    private String author_id;
    private String published;
    private Media media;

    // Getters and Setters
}

public class Media {
    private String m;
    // Getters and Setters
}

【讨论】:

  • 它适用于获取请求,在发布请求的情况下,我将内部对象设为空。你能解释一下吗?
  • @Spartan 我没听懂你。如果您对遇到问题的 JSON 提出一个新问题,那就更好了。此答案与 GET/POST 请求无关。
【解决方案2】:

以下代码将有助于获取嵌套的 json 对象和数组

例如:json

{  
    "similar_product":[  
        {  .....
}
    ],
    "options":{  
        "Blouse Length":[  
            {  "value_id":"696556",
               }

首先我们需要创建模型类,模型类项目名称在json项目中我们可以使用@SerializedName("for exact json name")

public class Product {

       public Options options;

    public void setOptions(Options options) {
        this.options = options;
    }

    public Options getOptions() {
        return options;
    }


    // length...

    public class Options
    {
        @SerializedName("Blouse Length")
        private ArrayList<BlouseLength> blouseLengths;


        public void setBlouseLengths(ArrayList<BlouseLength> blouseLengths) {
            this.blouseLengths = blouseLengths;
        }

        public ArrayList<BlouseLength> getBlouseLengths() {
            return blouseLengths;
        }
    }



    public class BlouseLength {
        String value_id;
        public void setValue_id(String value_id) {
            this.value_id = value_id;
        }



        public String getValue_id() {
            return value_id;
        }
    }

}

为改造创建接口以获取 url 中的 json 项

// don't need to put values of id in retrofit 

ex:: "/api-mobile_.php?method=getProductById&pid="

只需在查询中传递 url 参数它会自动获取 url

例如:

public interface Retrofit_Api {

    @FormUrlEncoded

    @GET("/api-mobile_.php?method=getProductById")
    Call<Product> responseproduct(@Query("pid") String pid);


}

在你的主课中

     String pid=editid.getText().toString();


        final Retrofit adapter = new Retrofit.Builder()
                .baseUrl(Product_url)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        //Creating an object of our api interface
        Retrofit_Api api = adapter.create(Retrofit_Api.class);


        Call<Product> call = api.responseproduct(pid);


        call.enqueue(new Callback<Product>() {
            @Override
            public void onResponse(Call<Product> call, Response<Product> response) {


               ArrayList<Product.BlouseLength> p= new ArrayList(response.body().getOptions().getBlouseLengths());

Editadapter editadapter=new Editadapter(MainActivity.this,p);

                recyclerView.setAdapter(editadapter);


            }

            @Override
            public void onFailure(Call<Product> call, Throwable t) {


                Log.d("Error", t.getMessage());
            }
        });



    }

【讨论】:

    【解决方案3】:

    为您的模型使用 Gson 轻松解析https://github.com/google/gson

    我的辅助方法:

    public String toJson(Object object) {
        return gson.toJson(object);
    }
    
    public <T> T fromJson(String json, Class<T> classOfT) {
        return gson.fromJson(json, classOfT);
    }
    
    public <T> T fromJson(JsonElement jsonElement, Class<T> classOfT) {
        return gson.fromJson(jsonElement, classOfT);
    }
    

    【讨论】:

    • 谢谢:) 你能分享一些关于如何编写Retrofit界面的知识吗?我应该在 HTTP API 中为 Call&lt;T&gt; httpApimethod(...) 的泛型类型 T 放置什么?我应该使用字段items 定义一个类吗?
    • @Hackjustu,泛型类型T 将成为json response 的pojo 类。
    • 所以,我应该定义一个 Java 类 ItemsHolder,它包含一个 List&lt;Item&gt; items。然后我可以从ItemsHolder 的字段items 中获取Item 实例。我错过了什么吗?谢谢:)
    • 您可以参考本教程tutorials.jenkov.com/java-json/gson.html了解更多。
    【解决方案4】:

    你尝试过截击吗? ...我更喜欢它而不是改造现在这是一个谷歌产品。我有工作示例,如果你不介意我可以告诉你。 http://www.androidhive.info/2014/09/android-json-parsing-using-volley/

    【讨论】:

    • 感谢您的建议:) 实际上,我们的团队决定使用 Retrofit 2.0,我正在对这个库进行一些初步研究。
    • volley 如何帮助解析 JSON 对象?
    【解决方案5】:

    我忘记为内部类对象添加@SerializedName@Expose 注释,添加这些注释后问题解决了。像这样:

    JSON:

    {"Id": 1,}
    

    和班级成员:

    @SerializedName("Id")
    @Expose
    private int id;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-30
      • 2021-02-03
      • 2015-09-12
      • 2018-05-31
      • 1970-01-01
      • 2018-07-12
      • 1970-01-01
      相关资源
      最近更新 更多