详谈gson解析

最后更新于:2022-04-01 14:25:53

gson是google的产物,用于解决json数据解析比较繁琐的问题。以前解析json需要层层解析,gson出现后解析往往只需几行代码。下面从简单到复杂说说我对gson用法的理解。 ### 一,简单的json的解析 在使用之前当然要导入Gson的jar包。本文最后会给出代码的下载地址,可以从代码中获取jar包。首先看看最简单的用法,单个类解析 看以下的json数据。 ~~~ {name:"mike",age:18} ~~~ 通过解析以上的json串来熟悉下gson的用法。因为以上是一个JSONObject,首先我们先定义一个Model类。 ~~~ public class Easy { public String name; public int age; public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public int getAge() { return age; } } ~~~ 然后接上来的就很简单了,看如下代码: ~~~ Easy easy = new Gson().fromJson(json,Easy.class ); ~~~ 其中json就是要解析的字符串,到此就完成了解析,相当方便。那如果是对象里嵌套对象呢,也很简单,只要修改下Model文件。如解析如下数据: ~~~ {name:"mike",age:18{name:tank}} ~~~ 只需把model改成如下: ~~~ public class Easy { public String name; public int age; public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public int getAge() { return age; } public class child{ public String name; </span>public String getName() { return name; } ~~~ ~~~ public void setName(String name) { this.name = name; } ~~~ 接下来我们来看看JSONArray的解析。解析如下json数据: ~~~ [{name:"mike",age:11},{name:"alan",age:15}] ~~~ 以上是一个JSONArray,解析方式如下: ~~~ Type type = new TypeToken<ArrayList<Easy>>(){}.getType(); ArrayList<Easy> list = new Gson().fromJson(new MyJsonParse().arrayParse(), type); ~~~ 这样解析后的数据就存在数组list中。简单的用法介绍完了,接下来介绍复杂点的json解析。 ### 二,复杂的gson解析 接下来来尝试解析下豆瓣api读书的json数据。 ~~~ {"category":{ "@scheme":"http://www.douban.com/2007#kind", "@term":"http://www.douban.com/2007#book"}, "db:tag":[ {"@count":20,"@name":"片山恭一"}, {"@count":14,"@name":"日本"}, {"@count":10,"@name":"小说"}, {"@count":8,"@name":"日本文学"}, {"@count":4,"@name":"爱情"} ], "title":{"$t":"满月之夜白鲸现"}, "author":[ {"name":{"$t":"(日)片山恭一"}} ], "summary":{"$t":"冷静地想一想吧!公寓的一个房间里只有两上人,连被褥都铺 好了,理应是犯错误的时候,我为什么却这么拘谨?一直胆小的毛病又犯了。事到 如今,不要说上床,就连接吻也还差得很远。这就是横亘在男人和女人之间的又深 又暗的河流吗?\n 如果有可能,我希望把手伸进她的心里,把她内心所有的东 西都掏出来。她对我究竟是一种什么感觉呢?我在她的心昊确实占有一席之地吗? 抑或只是她生命中的匆匆过客?"}, "link":[ {"@rel":"self","@href":"http://api.douban.com/book/subject/1220562"}, {"@rel":"alternate","@href":"http://book.douban.com/subject/1220562/"}, {"@rel":"image","@href":"http://img3.douban.com/spic/s1747553.jpg"} ], "db:attribute":[ {"$t":"(日)片山恭一","@name":"author"}, {"$t":"7543632608","@name":"isbn10"}, {"$t":"9787543632608","@name":"isbn13"}, {"$t":"180","@name":"pages"}, {"$t":"豫人","@name":"tranlator"}, {"$t":"18.00","@name":"price"}, {"$t":"青岛出版社","@name":"publisher"}, {"$t":"平装(无盘)","@name":"binding"}, {"$t":"片山恭一,1959年生于日本爱媛县,九州大学农学系农业经济学专业 毕业。学生时代通读了包括夏目漱石和大江健三郎在内的日本近现代文学全集, 同时读了笛卡尔、莱布尼茨到结构主义的欧洲近现代哲学。也读了马克思。 学士论文写的是马克思,硕士论文写的是恩格斯。二十二三岁开始创作小说。 代表作有《在世界中心呼唤爱》、《世界在你不知道的地方运转》、《气息》、 《别相信约翰·列侬》、《满月之夜白鲸现》、《空镜头》以及新作《倘若我在 彼岸》、《雨天的海豚们》等。","@name":"author-intro"} ], "id":{"$t":"http://api.douban.com/book/subject/1220562"}, "gd:rating":{"@min":1,"@numRaters":39,"@average":"3.69","@max":5} } ~~~ 以上json格式比较复杂。如果你不需要全部读取,只需读取一部分,比如读取内容,可以用以下方式。先定义内容的Model类 ~~~ public class Content { String $t; public void set$t(String $t) { this.$t = $t; } public String get$t() { return $t; } } ~~~ 再对其进行读取 ~~~ Gson gson = new Gson(); JsonElement element = new JsonParser().parse(json); JsonObject object = element.getAsJsonObject(); JsonElement cElement = object.get("summary"); Content c = gson.fromJson(cElement, Content.class); ~~~ 这样就把summary的类读取了出来。不用全部读。那如果要把所有内容都读取出来呢。我们来实现下以下的功能。读取相关信息并显示如下的界面。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-08_570771b4ba036.jpg) 难点在于Model类的编写。Model的编写是按照json格式来的。如下: ~~~ public class BookInfo { private categories category; @SerializedName(" db:tag") private List<tag> db; private Title title; private List<Author> author; private Content summary; private List<link> link; @SerializedName(" db:attribute") public List<attribute> attributes; public Id id; @SerializedName(" db:rating") public rating rating; public void setCategory(categories category) { this.category = category; } public void setDb(List<tag> db) { this.db = db; } public void setTitle(Title title) { this.title = title; } public void setAuthor(List<Author> author) { this.author = author; } public void setContent(Content content) { this.summary = content; } public void setLink(List<BookInfo.link> link) { this.link = link; } public void setAttributes(List<attribute> attributes) { this.attributes = attributes; } public void setId(Id id) { this.id = id; } public void setRating(BookInfo.rating rating) { this.rating = rating; } public categories getCategory() { return category; } public List<tag> getDb() { return db; } public Title getTitle() { return title; } public List<Author> getAuthor() { return author; } public Content getContent() { return summary; } public List<BookInfo.link> getLink() { return link; } public List<attribute> getAttributes() { return attributes; } public Id getId() { return id; } public BookInfo.rating getRating() { return rating; } public class categories{ @SerializedName("@scheme") public String scheme; @SerializedName("@term") public String term; public void setScheme(String scheme) { this.scheme = scheme; } public void setTerm(String term) { this.term = term; } public String getScheme() { return scheme; } public String getTerm() { return term; } } public class tag{ @SerializedName("@count") public String count; @SerializedName("@name") public String name; public void setCount(String count) { this.count = count; } public void setName(String name) { this.name = name; } public String getCount() { return count; } public String getName() { return name; } } public class Title{ @SerializedName("$t") private String title; public void setTitle(String title) { this.title = title; } public String getTitle() { return title; } } public class Author{ private Name name; public void setName(Name name) { this.name = name; } public Name getName() { return name; } } public class Name{ @SerializedName("$t") public String authorName; public void setAuthorName(String authorName) { this.authorName = authorName; } public String getAuthorName() { return authorName; } } public class Content{ @SerializedName("$t") public String content; public void setContent(String content) { this.content = content; } public String getContent() { return content; } } public class link{ @SerializedName("@rel") public String lrel; @SerializedName("@href") public String lhref; public void setLrel(String lrel) { this.lrel = lrel; } public String getLrel() { return lrel; } public void setLhref(String lhref) { this.lhref = lhref; } public String getLhref() { return lhref; } } public class attribute{ public List<myAttribute> myAttribute; public void setMyAttribute(List<BookInfo.myAttribute> myAttribute) { this.myAttribute = myAttribute; } public List<BookInfo.myAttribute> getMyAttribute() { return myAttribute; } } public class myAttribute{ @SerializedName("$t") public String aRel; @SerializedName("@name") public String aNname; public void setaRel(String aRel) { this.aRel = aRel; } public void setaNname(String aNname) { this.aNname = aNname; } public String getaRel() { return aRel; } public String getaNname() { return aNname; } } public class Id{ @SerializedName("$t") public String id; public void setId(String id) { this.id = id; } public String getId() { return id; } } public class rating{ @SerializedName("@min") public int min; @SerializedName("@numRaters") public int numRaters; @SerializedName("@average") public String average; public int getMax() { return max; } public int getMin() { return min; } public int getNumRaters() { return numRaters; } public String getAverage() { return average; } public void setMin(int min) { this.min = min; } public void setNumRaters(int numRaters) { this.numRaters = numRaters; } public void setAverage(String average) { this.average = average; } public void setMax(int max) { this.max = max; } @SerializedName("@max") public int max; } } ~~~ 本来变量名都要定义成与json中名一样,但因为此json数据很多名称如@rel并不适合当变量名,所以使用注解@serizalName来转化名字,这样只要保持@serizalName后的名称与json数据中名称一致就可以,Model类中的变量名可以自己起。以上代码有点长,我们就挑图片url获取为例子,其它以此类推。 ~~~ "link":[ {"@rel":"self","@href":"http://api.douban.com/book/subject/1220562"}, {"@rel":"alternate","@href":"http://book.douban.com/subject/1220562/"}, {"@rel":"image","@href":"http://img3.douban.com/spic/s1747553.jpg"} ], ~~~ 如上,我们要获取第三个。因为link里是一个数组,数组里有三个object,所以其定义为 ~~~ <pre name="code" class="java">private List<link> link;<span style="font-family: Arial, Helvetica, sans-serif;">  </span> ~~~ ~~~ public class link{ @SerializedName("@rel") public String lrel; @SerializedName("@href") public String lhref; public void setLrel(String lrel) { this.lrel = lrel; } public String getLrel() { return lrel; } public void setLhref(String lhref) { this.lhref = lhref; } public String getLhref() { return lhref; } } ~~~ 首先因为是数组,所以link应该定义成List,而link类是我们自己起的类,其中有两个属性,分别对应json中的两个属性。这样就定义完成。接下来很简单了。调用gson来进行解析,代码如下: ~~~ Gson gson = new Gson(); BookInfo info = gson.fromJson(json, BookInfo.class); ~~~ ~~~ BookInfo info = new MyJsonParse().parseInfoBook(msg.obj.toString()); bookTitle.setText(info.getTitle().getTitle()); bookAuthor.setText(info.getAuthor().get(0).getName().getAuthorName()); bookAbstract.setText(info.getContent().getContent()); Picasso.with(BookDetailActivity.this).load(info.getLink().get(2).getLhref()).placeholder(R.drawable.book_head).error(R.drawable.book_head).into(bookPic); ~~~ 这样就把数据解析出来了。 gson的出现给我们读取json数据带来很大的方便,应该好好的使用它。附上代码的下载地址。 [github下载地址](https://github.com/reallin/GsonPrase.git)
';