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

问题描述

对于简单的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;
    }
}
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值