Gson使用及多层嵌套 json 定义类

来源:互联网 发布:巨杉数据库 文档 编辑:程序博客网 时间:2024/05/29 13:27

问题描述

对于简单的Json数据,其对应的java bean 也比较简单,尤其用GSON处理的时候。
但是如果是多层嵌套的json数据,如果是手工用JSONArray和JSONObject进行解析,还是可以的,虽然会繁琐一点。但是如果用GSON开源库解析,有该如何定义java bean呢?
如果定义不好,会出现NEP空指针异常。

分析

在我的项目中,有这样的一段代码,

 public TopicApi getTopicService() {        if (mTopicApi == null) {            synchronized (new Object()) {                if (mTopicApi == null) {                    mTopicApi = new Retrofit.Builder()                            .baseUrl("https://www.v2ex.com")                            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())                            .addConverterFactory(GsonConverterFactory.create())                            .build().create(TopicApi.class);                }            }        }        return mTopicApi;    }
public interface TopicApi {    @GET("/api/topics/{category}")    Observable<ArrayList<TModel>> getTopicData(@Path("category") String category);}

出现这个问题的根源,我感觉一定是

addConverterFactory(GsonConverterFactory.create())

很明显,这里用到了Gson库,所以一定是Gson解析的时候,API提供的Json数据与相应的TModel 类对不上,导致出现NEP(因为找不到嵌套的Json所对应的javabean)

启示

感谢dubaidada的提示
后来发现这位博主才是原创

使用Gson解析复杂的json数据

String json = {"a":"100","b":[{"b1":"b_value1","b2":"b_value2"},{"b1":"b_value1","b2":"b_value2"}],"c":{"c1":"c_value1","c2":"c_value2"}}                首先我们需要定义一个序列化的Bean,这里采用内部类的形式,看起来会比较清晰一些:                public class JsonBean {                         public String a;                         public List<B> b;                         public C c;                         public static class B {                                  public String b1;                                  public String b2;                        }                        public static class C {                                 public String c1;                                 public String c2;                       }              }             很多时候大家都是不知道这个Bean是该怎么定义,这里面需要注意几点:             1、内部嵌套的类必须是static的,要不然解析会出错;             2、类里面的属性名必须跟Json字段里面的Key是一模一样的;             3、内部嵌套的用[]括起来的部分是一个List,所以定义为 public List<B> b,而只用{}嵌套的就定义为 public C c,                  具体的大家对照Json字符串看看就明白了,不明白的我们可以互相交流,本人也是开发新手!              Gson gson = new Gson();              java.lang.reflect.Type type = new TypeToken<JsonBean>() {}.getType();              JsonBean jsonBean = gson.fromJson(json, type);              然后想拿数据就很简单啦,直接在jsonBean里面取就可以了!       如果需要解析的Json嵌套了很多层,同样可以可以定义一个嵌套很多层内部类的Bean,需要细心的对照Json字段来定义

但是我发现就算内部嵌套的类不是static的,也没有出现什么问题。况且,为什么要用static呢?想不出什么原因呀?

于是我重新定义的TModel,如下所示,完美解决了问题

package com.example.a10648.v2ex.model;/** * Created by 10648 on 2016/10/3 0003. */public class TModel {    public String id;    public String title;    public String url;    public String content;    public String content_rendered;    public int replies;    public Member member;    public Node node;    public long created;    public long last_modefied;    public long last_touched;    public  class Member {        public String id;        public String username;        public String tagline;        public String avatar_mini;        public String avatar_normal;        public String avatar_large;        public String getId() {            return id;        }        public void setId(String id) {            this.id = id;        }        public String getUsername() {            return username;        }        public void setUsername(String username) {            this.username = username;        }        public String getTagline() {            return tagline;        }        public void setTagline(String tagline) {            this.tagline = tagline;        }        public String getAvatar_mini() {            return avatar_mini;        }        public void setAvatar_mini(String avatar_mini) {            this.avatar_mini = avatar_mini;        }        public String getAvatar_normal() {            return avatar_normal;        }        public void setAvatar_normal(String avatar_normal) {            this.avatar_normal = avatar_normal;        }        public String getAvatar_large() {            return avatar_large;        }        public void setAvatar_large(String avatar_large) {            this.avatar_large = avatar_large;        }    }    public  class Node{        public String id;        public String name;        public String title;        public String title_alternative;        public String url;        public int topics;        public String avatar_mini;        public String avatar_normal;        public String avatar_large;        public String getId() {            return id;        }        public void setId(String id) {            this.id = id;        }        public String getName() {            return name;        }        public void setName(String name) {            this.name = name;        }        public String getTitle() {            return title;        }        public void setTitle(String title) {            this.title = title;        }        public String getTitle_alternative() {            return title_alternative;        }        public void setTitle_alternative(String title_alternative) {            this.title_alternative = title_alternative;        }        public String getUrl() {            return url;        }        public void setUrl(String url) {            this.url = url;        }        public int getTopics() {            return topics;        }        public void setTopics(int topics) {            this.topics = topics;        }        public String getAvatar_mini() {            return avatar_mini;        }        public void setAvatar_mini(String avatar_mini) {            this.avatar_mini = avatar_mini;        }        public String getAvatar_normal() {            return avatar_normal;        }        public void setAvatar_normal(String avatar_normal) {            this.avatar_normal = avatar_normal;        }        public String getAvatar_large() {            return avatar_large;        }        public void setAvatar_large(String avatar_large) {            this.avatar_large = avatar_large;        }    }    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }    public String getUrl() {        return url;    }    public void setUrl(String url) {        this.url = url;    }    public String getContent() {        return content;    }    public void setContent(String content) {        this.content = content;    }    public String getContent_rendered() {        return content_rendered;    }    public void setContent_rendered(String content_rendered) {        this.content_rendered = content_rendered;    }    public int getReplies() {        return replies;    }    public void setReplies(int replies) {        this.replies = replies;    }    public long getCreated() {        return created;    }    public void setCreated(long created) {        this.created = created;    }    public long getLast_modefied() {        return last_modefied;    }    public void setLast_modefied(long last_modefied) {        this.last_modefied = last_modefied;    }    public long getLast_touched() {        return last_touched;    }    public void setLast_touched(long last_touched) {        this.last_touched = last_touched;    }    public Member getMember() {        return member;    }    public void setMember(Member member) {        this.member = member;    }    public Node getNode() {        return node;    }    public void setNode(Node node) {        this.node = node;    }}
1 1