Gson库详解(包含大量实例)

1. gson

1.1 gson基本用法

回顾gson的使用,并找一些json格式的数据进行解析。

String response="[{img=0.0,name=非会员,qualify_amount=0.0}," +
                "{img=1.0,name=一级会员,qualify_amount=100.0}," +
                "{img=2.0, name=二级会员,qualify_amount=300.0}]";

由于是数组中有多个对象,所以可以用List的方法进行解析,解析方法如下:

 Gson gson=new Gson();
        //数组的话可以这么做
     List<User>users=gson.fromJson(response,new TypeToken<List<User>>(){
   }.getType());
     for (User user:users){
   
         System.out.println(user.img+" "+user.name+" "+user.qualify_amount);

1.2 属性重命名

这里参考自Gson用法详解。当我们的接口返回的数据与我们期望的数据不同时,我们可以使用属性重命名。或者下述的json数据中有一个tz,我们怕忘记它的意思想给他改成time,就需要使用@SerializedName 来建立与java字段的联系。

 /**
     * admin_area : 北京
     * tz : +8.00
     * location : 北京
     * lon : 116.4052887
     * parent_city : 北京
     * cnty : 中国
     * lat : 39.90498734
     * cid : CN101010100
     */
    private String admin_area;
    @SerializedName("tz")
    private String time;

SerializedName远比你想象的更强大,假如,json数据如下:userName,user_name,Name,都是指向一个值,此时我们可以使用alternate属性。很奇怪的是,我翻看了我的SerializedName类发现竟然没有alternate这个属性,黑人问号脸,为什么问号它围绕着我?

{
   \"userName\":\"leavesC\",\"age\":24,\"sex\":true}
{
   \"user_name\":\"leavesC\",\"age\":24,\"sex\":true}
{
   \"Name\":\"leavesC\",\"age\":24,\"sex\":true}


@SerializedName(value = "userName", alternate = {
   "user_name", "Name"})
    private String name;
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.google.gson.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({
   ElementType.FIELD})
public @interface SerializedName {
   
    String value();
}

1.3 JsonDeserializer

参考自Gson 解析复杂数据。首先有一个Json对象,表示一本书的基本信息。

{
   
  'title':    'Java Puzzlers: Traps, Pitfalls, and Corner Cases',
  'isbn-10':  '032133678X',
  'isbn-13':  '978-0321336781',
  'authors':  ['Joshua Bloch', 'Neal Gafter']
}

java的变量名不容许有‘-’符号的,我们可以使用@SerializedName注解来处理,不过对于一些复杂情况是难以处理的,所以我们使用JsonDeserializer。我们需要自定义一个JsonDeserializer,然后注册到GsonBuilder,GsonBuilder在解析时就会自动使用我们自定义的JsonDeserializer。
首先我们需要创建一个BookJsonDeserializer。它负责把Book对应的Json对象,解析为Java对象

public class BookDeserializer implements JsonDeserializer<Book> {
   

      @Override
      public Book deserialize(final JsonElement jsonElement, final Type typeOfT, final JsonDeserializationContext context)
          throws JsonParseException {
   

        //todo 解析字段

        final Book book = new Book();
        book.setTitle(title);
        book.setIsbn10(isbn10);
        book.setIsbn13(isbn13);
        book.setAuthors(authors);
        return book;
      }
    }

简单介绍下JsonDeserializer,它需要有一个Type,那肯定是我们的Book。我们要重写deserialize()函数,并在其中解析json数据,最后返回一个Book对象。这里比较重要的是,Gson解析Json对象在内部表示为JsonElement,虽然element是元素的意思,但JsonElement可以表示为下列的任何一种:

1. JsonPrimitive :Java 基本类型的包装类,以及 String
2. JsonObject:类比 Js 中 Object的表示,或者 Java 中的 Map<String, JsonElement>,一个键值对结构。
3. JsonArray:JsonElement 组成的数组,注意:这里是 JsonElement,说明这个数组是混合类型的。
4. JsonNull:值为 null

完整代码如下,根据上述所讲,就可以解释,为什么要用getAsString和getAsJsonArray了。使用getAsString时是这个JsonElement表示为JsonPrimitive。使用getAsJsonArray时,虽然读取的是[‘Joshua Bloch’, ‘Neal Gafter’]这个数组,但表示为JsonElement所以,要给他转化一下。

class BookDeserializer implements JsonDeserializer<Book>{
   
    @Override
    public Book deserialize(final JsonElement jsonElement, final Type typeOfT,
                            final JsonDeserializationContext context)throws JsonParseException{
   
        final JsonObject jsonObject=jsonElement.getAsJsonObject();
        JsonElement titleElement=jsonObject.get("title");
        final  String title=titleElement.getAsString();
        JsonElement isbn10Element=jsonObject.get("isbn-10");
        final String isbn10=isbn10Element.getAsString();
        JsonElement isbn13Element=jsonObject.get("isbn-13");
        final String isbn13=isbn13Element.getAsString();
        //虽然是个数组,但Gson解析json对象并在内部表示为JsonElement,
        // 这里的其实是表示为JsonElement的JsonArray,所以要在get之后用getAsJsonArray();
        JsonArray authors=jsonObject.get("authors").getAsJsonArray();
        String[]Authors=new String[authors.size()];
        //Array中存放的是element
        int i=0;
        for(JsonElement jsonElement1:authors){
   
            Authors[i++]=jsonElement1.getAsString();
        }

        //todo 解析字段
        final  Book book=new Book();
        book.setTitle(title);
        book.setIsbn10(isbn10);
        book.setIsbn13(isbn13);
        book.setAuthors(Authors);
        return book;
    }

Book类

class Book{
   
    private String[] authors;
    private String isbn10;
    private String isbn13;
    private String title;

    public String[] getAuthors() {
   
        return authors;
    }

    public void setAuthors(String[] authors) {
   
        this.authors = authors;
    }

    public String getIsbn10() {
   
        return isbn10;
    }

    public void setIsbn10(String isbn10) {
   
        this.isbn10 = isbn10;
    }

    public String getIsbn13() {
   
        return isbn13;
    }

    public void setIsbn13(String isbn13) {
   
        this.isbn13 = isbn13;
    }

    public String getTitle() {
   
        return title;
    }

    public void setTitle(String title) {
   
        this.title = title;
    }

    @Override
    public String toString() {
   
        return "Book{" +
                "authors=" + Arrays.toString(authors) +
                ", isbn10='" + isbn10 + '\'' +
                ", isbn13='" + isbn13 + '\'' +
                ", title='" + title + '\'' +
                '}';
    }
}

这里要注意一下,Book类我们要重写一下toString(),否则的话无法得到我们想要的结果,直接System.out.println(book)就会输出book对应的地址。我们的检验代码如下:

切记不要直接创建Gson,而是要县创建GsonBuilder实例,并通过registerTypeAdapter传入要解析成的类(Book)以及对应的解析器实例(BookDeserializer)去注册解析器,之后通过GsonBuilder创建Gson实例。

public static void main(String[]args){
   
        String response="{\"title\":\"Java Puzzlers: Traps, Pitfalls, and Corner Cases\"," +
                "\"isbn-10\":\"032133678X\"," +
                "\"isbn-13\":\"978-0321336781\"," +
                "\"authors\":[\"Joshua Bloch\"," +
                "\"Neal Gafter\"]}";
        //使用GsonBuilder来注册BookDeserializer,并创建Gson对象,这样的话,
        // 需要解析Book的时候,就会使用BookDeserializer来解析
        GsonBuilder gsonBuilder=new GsonBuilder();
        gsonBuilder.registerTypeAdapter(Book.class,new BookDeserializer());
        Gson gson=gsonBuilder.create();
        
        Book book = gson.fromJson(response, Book.class);
       
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值