使用Retrofit以JsonArray为根解析Json

时间:2016-03-28 10:24:13

标签: android json gson retrofit

这是我的Json。它的问题是它有一个数组作为节点。我对Retrofit不是那么流利,所以我在尝试理解发生了什么以及如何解决它时遇到了一些问题。

[
{
    "first_name":"Jakub",
    "nickname":"",
    "last_name":"Machalek",
    "description":"description1",
    "speaker_id":0,
    "image_path":""
},
    {
    "first_name":"Krzysztof",
    "nickname":"",
    "last_name":"Opasik",
    "description":"Description2",
    "speaker_id":1,
    "image_path":""
},
...etc...

我该怎么解析它?我目前的尝试是这样的

的POJO

public class Speaker implements ParentListItem{
private String mFirstName;
private String mNickname;
private String mLastName;
private String mDescription;
private String mImageUrl;

private ArrayList<Speaker> mChildrenList;

public Speaker(String mFirstName, String mNickname, String mLastName, String mDescription, String mImageUrl) {
    this.mFirstName = mFirstName;
    this.mNickname = mNickname;
    this.mLastName = mLastName;
    this.mDescription = mDescription;
    this.mImageUrl = mImageUrl;
    mChildrenList = new ArrayList<>();
    mChildrenList.add(this);
}

public String getFirstName() {
    return mFirstName;
}

public void setFirstName(String mFirstName) {
    this.mFirstName = mFirstName;
}

public String getNickname() {
    return mNickname;
}

public void setNickname(String mNickname) {
    this.mNickname = mNickname;
}

public String getLastName() {
    return mLastName;
}

public void setLastName(String mLastName) {
    this.mLastName = mLastName;
}

public String getDescription() {
    return mDescription;
}

public void setDescription(String mDescription) {
    this.mDescription = mDescription;
}

public String getImageUrl() {
    return mImageUrl;
}

public void setImageUrl(String mImageUrl) {
    this.mImageUrl = mImageUrl;
}

@Override
public List<?> getChildItemList() {
    return mChildrenList;
}

@Override
public boolean isInitiallyExpanded() {
    return false;
}

public class SpeakerList {

List<Speaker> speakerList;


public List<Speaker> getSpeakerList() {
    return speakerList;
}

public void add(Speaker nataCenterItem){
    if(speakerList == null){
        speakerList = new LinkedList<>();
    }
    speakerList.add(nataCenterItem);
}

改造     公共类SessionInfoService {     private SessionInfoApi sessionInfoApi;

public SessionInfoService(){
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("...")
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    sessionInfoApi = retrofit.create(SessionInfoApi.class);
}

public void getLectureList(Callback callback) throws IOException {
    sessionInfoApi.getLectureList().enqueue(callback);
}

public void getSpeakerList(Callback callback) throws IOException {
    sessionInfoApi.getSpeakerList().enqueue(callback);
}

接口

@GET("...")
Call<List<Speaker>> getSpeakerList();

我可以使用任何帮助。

1 个答案:

答案 0 :(得分:0)

从我所能说的一切看起来都不错,除非你错过了Speaker模型中的某些内容。因此,在设置改造实例时,您正在使用gson转换器。默认情况下,gson通过查看json中的键并尝试使用相同的名称设置java对象的属性来序列化和反序列化jsons。

在您的情况下,它会尝试查找first_name模型中属性Speaker的示例,但您没有该属性,因为它是mFirstName。因此,如果没有任何进一步的帮助,gson实际上无法知道您的模型中要设置哪个字段。

解决此问题的一种明显方法是为您的字段first_name命名。但是,这不是在Java中命名字段的最常用或最常用的方法,因此gson为您提供SerializedName注释。它基本上告诉json中哪个字段与Java对象中的字段相关。因此,如果您将Speaker模型编写为:

public class Speaker implements ParentListItem{
  @SerializedName("first_name")
  private String mFirstName;
  @SerializedName("nickname")
  private String mNickname;
  @SerializedName("last_name")
  private String mLastName;
  // ...
}

然后gson知道要设置哪些字段并用于反序列化和序列化json。 Retrofit电话看起来不错。我想你可以忽略SpeakerList模型,并像你一样使用List<Speaker>

您可以考虑使用Expose Annotation。这不是绝对必要的,但可能需要。来自文档:

  

除非使用GsonBuilder构建Gson并调用GsonBuilder.excludeFieldsWithoutExposeAnnotation()方法,否则此注释无效。