2015-10-05 128 views
21

我们的团队决定使用Retrofit 2.0,我正在对此库进行一些初步研究。正如标题所述,我想通过我们的Android应用程序中的Retrofit 2.0解析一些嵌套的JSON对象。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对象。我注意到有关于通过Retrofit 1.X解析嵌套JSON对象的some posts,但是最新的Retrofit 2.0 API已经发生了很大的变化,这在将它们适配到新的API时令人困惑。

两个可能的解决方案进入我的脑海:

  1. 写我自己的JSON转换器厂延伸Converter.Factory
  2. 返回String类型的原始响应并自行解析。根据我的初步研究,从Retrofit 2.0获得原始响应并不容易。 Retrofit 2.0似乎坚持在将响应转换为某种东西之前将其传递给我,并且Retrofit不提供它自己的StringConverter。 (我可能是错的〜)

更新:事实上,我们可以得到通过设置JSONElement作为POJO的HTTP API接口,并使用GSONConverter被改造为转换器提供的原始响应。

如果有人能就这个问题分享一些想法,那将是非常好的。

谢谢:)

+1

西港岛线是什么项目阵列?你可以发布那部分吗? –

+1

@PankajKumar更新:) – hackjutsu

+1

我添加了一个类似于您的JSON的答案。尝试一下。 –

回答

21

假设你完整的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 
} 
+1

@IgorGanapolsky查看更新部分。这是一个示例代码。 –

+2

它正在为获取请求工作,在发布请求的情况下,我正在将内部对象作为null。你能解释一下吗? – Spartan

+0

@Spartan我没有得到你。更好的是,如果您使用您正在面临问题的JSON提出新问题。这个答案与GET/POST请求没有关系。 –

4

使用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); 
} 
+0

谢谢:)你可以分享一下如何编写Retrofit界面?我应该在HTTP API中为'调用 httpApimethod(...)'提供通用类型'T'?我应该用字段“items”来定义一个类吗? – hackjutsu

+0

@Hackjustu,泛型类型'T'将成为'json response'的pojo类。 – Tauqir

+0

所以,我应该定义一个Java类'ItemsHolder',它包含一个'List items'。然后我可以从'ItemsHolder'的字段'items'中获得'Item'实例。我想念什么?感谢:) – hackjutsu

5

下面的代码将有助于获得例如嵌套的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; 
     } 
    } 

} 

创造更新接口中的网址,获取JSON项目

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

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

只是通过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()); 
      } 
     }); 



    } 
0

萨拉姆。 我忘了为内部Class对象添加@SerializedName@Expose注解,并在添加这些注解问题后解决。 像这样:

JSON:

{"Id": 1,} 

和类成员:

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