【问题标题】:Retrofit conversion issue - how to correctly create POJO class for concrete JSON:改造转换问题 - 如何为具体 JSON 正确创建 POJO 类:
【发布时间】:2019-06-09 15:56:57
【问题描述】:

我是 android 新手,正在构建一个使用 Retrofit 库从 REST API 加载数据的应用程序。我以前设法让它工作,但现在当我向我的 POJO 类添加更多变量时,Retrofit 似乎有转换问题。它转到“OnFailure”,错误不是 IOException 类型。我认为 Lecture 对象列表可能有问题。

这是源 JSON 的示例:

[  
   {  
      "id":1603,
      "date":"2018-09-11T22:12:59",
      "date_gmt":"2018-09-11T20:12:59",
      "guid":{  
         "rendered":"https:\/\/get-splashed.cz\/?p=1603"
      },
      "modified":"2018-09-11T22:22:01",
      "modified_gmt":"2018-09-11T20:22:01",
      "slug":"stein-and-meredith",
      "status":"publish",
      "type":"post",
      "link":"https:\/\/get-splashed.cz\/speakers\/stein-and-meredith",
      "title":{  
         "rendered":"Stein and Meredith"
      },
      "content":{  
         "rendered":"Animation and Games. Whatever your experience",
         "protected":false
      },
      "excerpt":{  
         "rendered":"Head of Compositing",
         "protected":false
      },
      "author":1,
      "featured_media":1606,
      "comment_status":"open",
      "ping_status":"open",
      "sticky":false,
      "template":"",
      "format":"standard",
      "meta":[  

      ],
      "categories":[  
         2
      ],
      "tags":[  

      ],
      "acf":{  
         "role":"",
         "job":"<b>Escape Studios<\/b>",
         "social":false,
         "speaker_slider_shortcode":"[rev_slider alias=\"escape\"]",
         "o_prednasce":[  
            {  
               "nazev_prednasky":"Creating a killer showreel: advice & tips for VFX, Animation & Games",
               "den_prednasky":"nedele",
               "cas_prednasky":"17:30",
               "typ":"P\u0159edn\u00e1\u0161ka",
               "misto_konani":"Main Hall",
               "doba_trvani":"60",
               "prave_probiha":""
            }
         ]
      }
   },
   {  
      "id":1452,
      "date":"2018-08-13T22:41:19",
      "date_gmt":"2018-08-13T20:41:19",
      "guid":{  
         "rendered":"https:\/\/get-splashed.cz\/?p=1452"
      },
      "modified":"2018-08-14T11:27:11",
      "modified_gmt":"2018-08-14T09:27:11",
      "slug":"jan-jinda",
      "status":"publish",
      "type":"post",
      "link":"https:\/\/get-splashed.cz\/speakers\/jan-jinda",
      "title":{  
         "rendered":"Jan Jinda"
      },
      "content":{  
         "rendered":"<p>Czech born London based 3D Generalist",
         "protected":false
      },
      "excerpt":{  
         "rendered":"Czech born London based",
         "protected":false
      },
      "author":1,
      "featured_media":1453,
      "comment_status":"open",
      "ping_status":"open",
      "sticky":false,
      "template":"",
      "format":"standard",
      "meta":[  

      ],
      "categories":[  
         2
      ],
      "tags":[  

      ],
      "acf":{  
         "role":"Senior Build TD",
         "job":"<b>Dneg<\/b>",
         "social":[  
            {  
               "odkaz":"https:\/\/www.facebook.com\/jan.jinda",
               "socialni_sit":"facebook"
            },
            {  
               "odkaz":"https:\/\/www.linkedin.com\/in\/janjinda\/",
               "socialni_sit":"linkedin"
            }
         ],
         "speaker_slider_shortcode":"[rev_slider alias=\"jinda\"]",
         "o_prednasce":[  
            {  
               "nazev_prednasky":"Building massive Jaegers for PR2",
               "den_prednasky":"sobota",
               "cas_prednasky":"15:00",
               "typ":"P\u0159edn\u00e1\u0161ka",
               "misto_konani":"Main Hall",
               "doba_trvani":"60",
               "prave_probiha":""
            }
         ]
      }
   }
]

还有我的 POJO 课:

import com.google.gson.annotations.SerializedName;

import java.util.List;

public class Speaker {

    @SerializedName("id")
    private int mId;

    @SerializedName("title")
    private Title mTitle;

    @SerializedName("acf")
    private Acf mAcf;

    @SerializedName("featured_media")
    private int mMediaId;

    @SerializedName("content")
    private Content mContent;

    String mImageUrl = "";

    // indicator if the speaker is fake - zig-zag layout
    private boolean mFakeSpeaker = false;

    public Speaker(int id, Title title, Acf acf, int mediaId, String imageUrl, boolean fakeSpeaker) {
        mId = id;
        mTitle = title;
        mAcf = acf;
        mImageUrl = imageUrl;
        mMediaId = mediaId;
        mFakeSpeaker = fakeSpeaker;
    }

    public int getId() {
        return mId;
    }

    public Title getTitle() {
        return mTitle;
    }

    public Acf getAcf() {
        return mAcf;
    }

    public int getMediaId() {
        return mMediaId;
    }

    public String getImageUrl() {
        return mImageUrl;
    }

    public void setImageUrl(String imageUrl) {
        mImageUrl = imageUrl;
    }

    public boolean getIsFakeSpeaker() {
        return mFakeSpeaker;
    }

    public void setIsFakeSpeaker(boolean isFakeSpeaker) {
        mFakeSpeaker = isFakeSpeaker;
    }

    public Content getContent() {
        return mContent;
    }

    public class Title {

        @SerializedName("rendered")
        private String mName;

        public Title(String name) {
            mName = name;
        }

        public String getName() {
            return mName;
        }
    }

    public class Acf {
        @SerializedName("role")
        private String mRole;

        @SerializedName("job")
        private String mCompany;

        @SerializedName("o_prednasce")
        private List<Lecture> mLectures;


        public Acf(String role, String company, List<Lecture> lectures) {
            mRole = role;
            mCompany = company;
            mLectures = lectures;
        }

        public String getRole() {
            return mRole;
        }

        public String getCompany() {
            return mCompany;
        }

        public List<Lecture> getLectures() {
            return mLectures;
        }

        public class Lecture {

            @SerializedName("nazev_prednasky")
            private String mLectureName;

            @SerializedName("den_prednasky")
            private String mLectureDay;

            @SerializedName("cas_prednasky")
            private String mLectureTime;

            public Lecture(String lectureName, String lectureDay, String lectureTime) {
                mLectureName = lectureName;
                mLectureDay = lectureDay;
                mLectureTime = lectureTime;
            }

            public String getLectureName() {
                return mLectureName;
            }

            public String getLectureDay() {
                return mLectureDay;
            }

            public String getLectureTime() {
                return mLectureTime;
            }
        }
    }

    public class Content {

        @SerializedName("rendered")
        private String mDescription;

        public Content(String description) {
            mDescription = description;
        }

        public String getDescription() {
            return mDescription;
        }
    }
}

在我添加 Lecture 类之前,代码一直有效。现在我无法弄清楚这里可能存在什么问题。

编辑:在 Retrofit 的 onFailure 方法中记录错误类型后:

            public void onFailure(Call<List<Speaker>> call, Throwable t) {

                if (t instanceof IOException) {
                    Log.v("RetrofitSplash", "No internet connection");
                } else {
                    Log.v("RetrofitSplash", "conversion issue! " + t.getMessage());
                }
            }

我发现有一个问题:“应为 BEGIN_ARRAY,但在第 1 行第 46857 列路径 $[10].acf.o_prednasce 为 BOOLEAN”

然后我再次查看 JSON,发现有一个字段“acf.o_prednasce”在一种情况下不是数组,而是“假”,即布尔值。

查看更大的 JSON 示例:

[  
   {  
      "id":1603,
      "date":"2018-09-11T22:12:59",
      "date_gmt":"2018-09-11T20:12:59",
      "guid":{  
         "rendered":"https:\/\/get-splashed.cz\/?p=1603"
      },
      "modified":"2018-09-11T22:22:01",
      "modified_gmt":"2018-09-11T20:22:01",
      "slug":"stein-and-meredith",
      "status":"publish",
      "type":"post",
      "link":"https:\/\/get-splashed.cz\/speakers\/stein-and-meredith",
      "title":{  
         "rendered":"Stein and Meredith"
      },
      "content":{  
         "rendered":"Animation and Games. Whatever your experience",
         "protected":false
      },
      "excerpt":{  
         "rendered":"Head of Compositing",
         "protected":false
      },
      "author":1,
      "featured_media":1606,
      "comment_status":"open",
      "ping_status":"open",
      "sticky":false,
      "template":"",
      "format":"standard",
      "meta":[  

      ],
      "categories":[  
         2
      ],
      "tags":[  

      ],
      "acf":{  
         "role":"",
         "job":"<b>Escape Studios<\/b>",
         "social":false,
         "speaker_slider_shortcode":"[rev_slider alias=\"escape\"]",
         "o_prednasce":[  
            {  
               "nazev_prednasky":"Creating a killer showreel: advice & tips for VFX, Animation & Games",
               "den_prednasky":"nedele",
               "cas_prednasky":"17:30",
               "typ":"P\u0159edn\u00e1\u0161ka",
               "misto_konani":"Main Hall",
               "doba_trvani":"60",
               "prave_probiha":""
            }
         ]
      }
   },
   {  
      "id":1452,
      "date":"2018-08-13T22:41:19",
      "date_gmt":"2018-08-13T20:41:19",
      "guid":{  
         "rendered":"https:\/\/get-splashed.cz\/?p=1452"
      },
      "modified":"2018-08-14T11:27:11",
      "modified_gmt":"2018-08-14T09:27:11",
      "slug":"jan-jinda",
      "status":"publish",
      "type":"post",
      "link":"https:\/\/get-splashed.cz\/speakers\/jan-jinda",
      "title":{  
         "rendered":"Jan Jinda"
      },
      "content":{  
         "rendered":"<p>Czech born London based 3D Generalist",
         "protected":false
      },
      "excerpt":{  
         "rendered":"Czech born London based",
         "protected":false
      },
      "author":1,
      "featured_media":1453,
      "comment_status":"open",
      "ping_status":"open",
      "sticky":false,
      "template":"",
      "format":"standard",
      "meta":[  

      ],
      "categories":[  
         2
      ],
      "tags":[  

      ],
      "acf":{  
         "role":"Senior Build TD",
         "job":"<b>Dneg<\/b>",
         "social":[  
            {  
               "odkaz":"https:\/\/www.facebook.com\/jan.jinda",
               "socialni_sit":"facebook"
            },
            {  
               "odkaz":"https:\/\/www.linkedin.com\/in\/janjinda\/",
               "socialni_sit":"linkedin"
            }
         ],
         "speaker_slider_shortcode":"[rev_slider alias=\"jinda\"]",
         "o_prednasce":[  
            {  
               "nazev_prednasky":"Building massive Jaegers for PR2",
               "den_prednasky":"sobota",
               "cas_prednasky":"15:00",
               "typ":"P\u0159edn\u00e1\u0161ka",
               "misto_konani":"Main Hall",
               "doba_trvani":"60",
               "prave_probiha":""
            }
         ]
      }
   },
  {  
      "id":855,
      "date":"2018-05-02T23:21:11",
      "date_gmt":"2018-05-02T21:21:11",
      "guid":{  
         "rendered":"http:\/\/get-splashed.cz\/?p=855"
      },
      "modified":"2018-09-14T22:15:38",
      "modified_gmt":"2018-09-14T20:15:38",
      "slug":"talk-info-will-be-soon",
      "status":"publish",
      "type":"post",
      "link":"https:\/\/get-splashed.cz\/nezarazene\/talk-info-will-be-soon",
      "title":{  
         "rendered":"Speaker soon"
      },
      "content":{  
         "rendered":"",
         "protected":false
      },
      "excerpt":{  
         "rendered":"",
         "protected":false
      },
      "author":1,
      "featured_media":863,
      "comment_status":"open",
      "ping_status":"open",
      "sticky":false,
      "template":"",
      "format":"standard",
      "meta":[  

      ],
      "categories":[  
         1
      ],
      "tags":[  

      ],
      "acf":{  
         "role":"",
         "job":"",
         "social":false,
         "speaker_slider_shortcode":"",
         "o_prednasce":false
      }
   }
]

【问题讨论】:

    标签: java android retrofit2 pojo


    【解决方案1】:

    最后我自己找到了解决方案:由于 JSON 中的字段“acf.o_prednasce”在一种情况下是布尔值,而在其他情况下是一个数组,我通过字段“类别”过滤 API 响应以获得一个在一个响应中输入此字段的类型。

    【讨论】:

      【解决方案2】:

      不需要默认构造函数;就像那些 @Expose 不需要注解一样。

      尝试使用ArrayList&lt;Lecture&gt; 而不是List&lt;Lecture&gt;

      【讨论】:

      • 不,将 List 更改为 ArrayList 没有帮助,问题仍然存在。但是感谢您查看代码。
      【解决方案3】:

      序列化程序通常要求对象具有默认构造函数。

      为 Lecture 添加一个默认构造函数,看看会发生什么。

      【讨论】:

      • 不,即使向 Lecture 类添加默认构造函数也无济于事:(
      【解决方案4】:

      试试这个 www.jsonschema2pojo.org

      -----------------------------------com.example.Acf.java-----------------------------------
      
      package com.example;
      
      import java.util.List;
      import com.google.gson.annotations.Expose;
      import com.google.gson.annotations.SerializedName;
      
      public class Acf {
      
      @SerializedName("role")
      @Expose
      private String role;
      @SerializedName("job")
      @Expose
      private String job;
      @SerializedName("social")
      @Expose
      private List<Social> social = null;
      @SerializedName("speaker_slider_shortcode")
      @Expose
      private String speakerSliderShortcode;
      @SerializedName("o_prednasce")
      @Expose
      private List<OPrednasce> oPrednasce = null;
      
      public String getRole() {
      return role;
      }
      
      public void setRole(String role) {
      this.role = role;
      }
      
      public String getJob() {
      return job;
      }
      
      public void setJob(String job) {
      this.job = job;
      }
      
      public List<Social> getSocial() {
      return social;
      }
      
      public void setSocial(List<Social> social) {
      this.social = social;
      }
      
      public String getSpeakerSliderShortcode() {
      return speakerSliderShortcode;
      }
      
      public void setSpeakerSliderShortcode(String speakerSliderShortcode) {
      this.speakerSliderShortcode = speakerSliderShortcode;
      }
      
      public List<OPrednasce> getOPrednasce() {
      return oPrednasce;
      }
      
      public void setOPrednasce(List<OPrednasce> oPrednasce) {
      this.oPrednasce = oPrednasce;
      }
      
      }
      -----------------------------------com.example.Content.java-----------------------------------
      
      package com.example;
      
      import com.google.gson.annotations.Expose;
      import com.google.gson.annotations.SerializedName;
      
      public class Content {
      
      @SerializedName("rendered")
      @Expose
      private String rendered;
      @SerializedName("protected")
      @Expose
      private Boolean _protected;
      
      public String getRendered() {
      return rendered;
      }
      
      public void setRendered(String rendered) {
      this.rendered = rendered;
      }
      
      public Boolean getProtected() {
      return _protected;
      }
      
      public void setProtected(Boolean _protected) {
      this._protected = _protected;
      }
      
      }
      -----------------------------------com.example.Example.java-----------------------------------
      
      package com.example;
      
      import java.util.List;
      import com.google.gson.annotations.Expose;
      import com.google.gson.annotations.SerializedName;
      
      public class Example {
      
      @SerializedName("id")
      @Expose
      private Integer id;
      @SerializedName("date")
      @Expose
      private String date;
      @SerializedName("date_gmt")
      @Expose
      private String dateGmt;
      @SerializedName("guid")
      @Expose
      private Guid guid;
      @SerializedName("modified")
      @Expose
      private String modified;
      @SerializedName("modified_gmt")
      @Expose
      private String modifiedGmt;
      @SerializedName("slug")
      @Expose
      private String slug;
      @SerializedName("status")
      @Expose
      private String status;
      @SerializedName("type")
      @Expose
      private String type;
      @SerializedName("link")
      @Expose
      private String link;
      @SerializedName("title")
      @Expose
      private Title title;
      @SerializedName("content")
      @Expose
      private Content content;
      @SerializedName("excerpt")
      @Expose
      private Excerpt excerpt;
      @SerializedName("author")
      @Expose
      private Integer author;
      @SerializedName("featured_media")
      @Expose
      private Integer featuredMedia;
      @SerializedName("comment_status")
      @Expose
      private String commentStatus;
      @SerializedName("ping_status")
      @Expose
      private String pingStatus;
      @SerializedName("sticky")
      @Expose
      private Boolean sticky;
      @SerializedName("template")
      @Expose
      private String template;
      @SerializedName("format")
      @Expose
      private String format;
      @SerializedName("meta")
      @Expose
      private List<Object> meta = null;
      @SerializedName("categories")
      @Expose
      private List<Integer> categories = null;
      @SerializedName("tags")
      @Expose
      private List<Object> tags = null;
      @SerializedName("acf")
      @Expose
      private Acf acf;
      
      public Integer getId() {
      return id;
      }
      
      public void setId(Integer id) {
      this.id = id;
      }
      
      public String getDate() {
      return date;
      }
      
      public void setDate(String date) {
      this.date = date;
      }
      
      public String getDateGmt() {
      return dateGmt;
      }
      
      public void setDateGmt(String dateGmt) {
      this.dateGmt = dateGmt;
      }
      
      public Guid getGuid() {
      return guid;
      }
      
      public void setGuid(Guid guid) {
      this.guid = guid;
      }
      
      public String getModified() {
      return modified;
      }
      
      public void setModified(String modified) {
      this.modified = modified;
      }
      
      public String getModifiedGmt() {
      return modifiedGmt;
      }
      
      public void setModifiedGmt(String modifiedGmt) {
      this.modifiedGmt = modifiedGmt;
      }
      
      public String getSlug() {
      return slug;
      }
      
      public void setSlug(String slug) {
      this.slug = slug;
      }
      
      public String getStatus() {
      return status;
      }
      
      public void setStatus(String status) {
      this.status = status;
      }
      
      public String getType() {
      return type;
      }
      
      public void setType(String type) {
      this.type = type;
      }
      
      public String getLink() {
      return link;
      }
      
      public void setLink(String link) {
      this.link = link;
      }
      
      public Title getTitle() {
      return title;
      }
      
      public void setTitle(Title title) {
      this.title = title;
      }
      
      public Content getContent() {
      return content;
      }
      
      public void setContent(Content content) {
      this.content = content;
      }
      
      public Excerpt getExcerpt() {
      return excerpt;
      }
      
      public void setExcerpt(Excerpt excerpt) {
      this.excerpt = excerpt;
      }
      
      public Integer getAuthor() {
      return author;
      }
      
      public void setAuthor(Integer author) {
      this.author = author;
      }
      
      public Integer getFeaturedMedia() {
      return featuredMedia;
      }
      
      public void setFeaturedMedia(Integer featuredMedia) {
      this.featuredMedia = featuredMedia;
      }
      
      public String getCommentStatus() {
      return commentStatus;
      }
      
      public void setCommentStatus(String commentStatus) {
      this.commentStatus = commentStatus;
      }
      
      public String getPingStatus() {
      return pingStatus;
      }
      
      public void setPingStatus(String pingStatus) {
      this.pingStatus = pingStatus;
      }
      
      public Boolean getSticky() {
      return sticky;
      }
      
      public void setSticky(Boolean sticky) {
      this.sticky = sticky;
      }
      
      public String getTemplate() {
      return template;
      }
      
      public void setTemplate(String template) {
      this.template = template;
      }
      
      public String getFormat() {
      return format;
      }
      
      public void setFormat(String format) {
      this.format = format;
      }
      
      public List<Object> getMeta() {
      return meta;
      }
      
      public void setMeta(List<Object> meta) {
      this.meta = meta;
      }
      
      public List<Integer> getCategories() {
      return categories;
      }
      
      public void setCategories(List<Integer> categories) {
      this.categories = categories;
      }
      
      public List<Object> getTags() {
      return tags;
      }
      
      public void setTags(List<Object> tags) {
      this.tags = tags;
      }
      
      public Acf getAcf() {
      return acf;
      }
      
      public void setAcf(Acf acf) {
      this.acf = acf;
      }
      
      }
      -----------------------------------com.example.Excerpt.java-----------------------------------
      
      package com.example;
      
      import com.google.gson.annotations.Expose;
      import com.google.gson.annotations.SerializedName;
      
      public class Excerpt {
      
      @SerializedName("rendered")
      @Expose
      private String rendered;
      @SerializedName("protected")
      @Expose
      private Boolean _protected;
      
      public String getRendered() {
      return rendered;
      }
      
      public void setRendered(String rendered) {
      this.rendered = rendered;
      }
      
      public Boolean getProtected() {
      return _protected;
      }
      
      public void setProtected(Boolean _protected) {
      this._protected = _protected;
      }
      
      }
      -----------------------------------com.example.Guid.java-----------------------------------
      
      package com.example;
      
      import com.google.gson.annotations.Expose;
      import com.google.gson.annotations.SerializedName;
      
      public class Guid {
      
      @SerializedName("rendered")
      @Expose
      private String rendered;
      
      public String getRendered() {
      return rendered;
      }
      
      public void setRendered(String rendered) {
      this.rendered = rendered;
      }
      
      }
      -----------------------------------com.example.OPrednasce.java-----------------------------------
      
      package com.example;
      
      import com.google.gson.annotations.Expose;
      import com.google.gson.annotations.SerializedName;
      
      public class OPrednasce {
      
      @SerializedName("nazev_prednasky")
      @Expose
      private String nazevPrednasky;
      @SerializedName("den_prednasky")
      @Expose
      private String denPrednasky;
      @SerializedName("cas_prednasky")
      @Expose
      private String casPrednasky;
      @SerializedName("typ")
      @Expose
      private String typ;
      @SerializedName("misto_konani")
      @Expose
      private String mistoKonani;
      @SerializedName("doba_trvani")
      @Expose
      private String dobaTrvani;
      @SerializedName("prave_probiha")
      @Expose
      private String praveProbiha;
      
      public String getNazevPrednasky() {
      return nazevPrednasky;
      }
      
      public void setNazevPrednasky(String nazevPrednasky) {
      this.nazevPrednasky = nazevPrednasky;
      }
      
      public String getDenPrednasky() {
      return denPrednasky;
      }
      
      public void setDenPrednasky(String denPrednasky) {
      this.denPrednasky = denPrednasky;
      }
      
      public String getCasPrednasky() {
      return casPrednasky;
      }
      
      public void setCasPrednasky(String casPrednasky) {
      this.casPrednasky = casPrednasky;
      }
      
      public String getTyp() {
      return typ;
      }
      
      public void setTyp(String typ) {
      this.typ = typ;
      }
      
      public String getMistoKonani() {
      return mistoKonani;
      }
      
      public void setMistoKonani(String mistoKonani) {
      this.mistoKonani = mistoKonani;
      }
      
      public String getDobaTrvani() {
      return dobaTrvani;
      }
      
      public void setDobaTrvani(String dobaTrvani) {
      this.dobaTrvani = dobaTrvani;
      }
      
      public String getPraveProbiha() {
      return praveProbiha;
      }
      
      public void setPraveProbiha(String praveProbiha) {
      this.praveProbiha = praveProbiha;
      }
      
      }
      -----------------------------------com.example.Social.java-----------------------------------
      
      package com.example;
      
      import com.google.gson.annotations.Expose;
      import com.google.gson.annotations.SerializedName;
      
      public class Social {
      
      @SerializedName("odkaz")
      @Expose
      private String odkaz;
      @SerializedName("socialni_sit")
      @Expose
      private String socialniSit;
      
      public String getOdkaz() {
      return odkaz;
      }
      
      public void setOdkaz(String odkaz) {
      this.odkaz = odkaz;
      }
      
      public String getSocialniSit() {
      return socialniSit;
      }
      
      public void setSocialniSit(String socialniSit) {
      this.socialniSit = socialniSit;
      }
      
      }
      -----------------------------------com.example.Title.java-----------------------------------
      
      package com.example;
      
      import com.google.gson.annotations.Expose;
      import com.google.gson.annotations.SerializedName;
      
      public class Title {
      
      @SerializedName("rendered")
      @Expose
      private String rendered;
      
      public String getRendered() {
      return rendered;
      }
      
      public void setRendered(String rendered) {
      this.rendered = rendered;
      }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2019-02-17
        • 2016-08-08
        • 2017-12-04
        • 1970-01-01
        • 2015-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-23
        相关资源
        最近更新 更多