【问题标题】:Parsing a Json with JsonArray as a root using Retrofit使用 Retrofit 解析以 JsonArray 为根的 Json
【发布时间】:2016-03-28 10:24:12
【问题描述】:

这是我的 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 { 私有 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();

我可以使用任何帮助。

【问题讨论】:

  • 我已经接受了下面的答案。抱歉耽搁了。我是一个偶尔的用户。现在我开始在工作中更频繁地使用 SO。

标签: android json gson retrofit


【解决方案1】:

据我所知,一切看起来都不错,只是你的Speaker 模型中遗漏了一些东西。因此,当您设置改造实例时,您正在使用gson 转换器。默认情况下,gson 通过查看 json 中的键并尝试将 java 对象的属性设置为同名来对 json 进行序列化和反序列化。

在您的情况下,它会尝试在您的 Speaker 模型中查找属性 first_name,而您没有该属性,因为它是 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&lt;Speaker&gt;。

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

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

【讨论】:

  • 谢谢。我是一个偶尔的 SO 用户,所以我花了一段时间才接受这个答案,但我记得这正是问题所在。谢谢你的回答人:)
猜你喜欢
  • 1970-01-01
  • 2019-01-19
  • 2012-04-18
  • 2020-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-08
  • 1970-01-01
相关资源
最近更新 更多