GSON使用的学习笔记,入门篇

今天是我第一次处理json编、解码,也是第一次使用gson,这里记录一些学习中的笔记。

json是什么

        看到 { "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" } 这样的字符串时,不由的让我想起几年前看过一本讲述javascript编程的书籍,前言里提到javascript世界里对对象的定义,非常简短,但富有内涵,翻译之后为“对象是名、值对的组合”。这是json给我的第一感觉。

        百度百科里有个词条介绍了json,这里就不重复说明了。重点是json在web的javascript编程中应用非常多,使用时非常灵活、方便。json的格式很简单,大致上可以如下概括,{和}表示对象,[和]表示数组,加上名、值对,组成了json的格式。

简单入门

        下面的代码演示了非常简单的场景,包含一个简单的Java Bean和使用gson进行编码和解码的操作。

        首先是Java Bean的定义,为了简化定义,样例中使用了lombok来生成get/set以及toString、hashCode、equals方法。

  1. @Data  
  2. class Person {  
  3.     private String name;  
  4.     private int age;  
  5. }  
@Data
class Person {
    private String name;
    private int age;
}
        下面是编码和解码的过程。

  1. import lombok.Data;  
  2.   
  3. import com.google.gson.Gson;  
  4.   
  5. public class JsonTest {  
  6.     public static void main(final String[] args) {  
  7.         final Gson gson = new Gson();  
  8.         final Persion jack = new Person();  
  9.         jack.setAge(222);  
  10.         jack.setName("Jackie");  
  11.   
  12.         final String json = gson.toJson(jack);  
  13.         final Person jack2 = gson.fromJson(json, Person.class);  
  14.         System.out.println(jack.equals(jack2));  
  15.         System.out.println("jack = " + jack);  
  16.         System.out.println("jack2 = " + jack2);  
  17.         System.out.println(json);  
  18.     }  
  19. }  
import lombok.Data;

import com.google.gson.Gson;

public class JsonTest {
    public static void main(final String[] args) {
        final Gson gson = new Gson();
        final Persion jack = new Person();
        jack.setAge(222);
        jack.setName("Jackie");

        final String json = gson.toJson(jack);
        final Person jack2 = gson.fromJson(json, Person.class);
        System.out.println(jack.equals(jack2));
        System.out.println("jack = " + jack);
        System.out.println("jack2 = " + jack2);
        System.out.println(json);
    }
}

        如前述,样例很简单,应当不需要注释说明。如下是上述代码的执行结果。

  1. true  
  2. jack = Person(name=Jackie, age=222)  
  3. jack2 = Person(name=Jackie, age=222)  
  4. {"name":"Jackie","age":222}  
true
jack = Person(name=Jackie, age=222)
jack2 = Person(name=Jackie, age=222)
{"name":"Jackie","age":222}

进阶一,处理数组

        比如面对类似 [{"name":"Jackie","age":30},{"name":"Jackie Boy","age":1}] 这样的json格式的字符串需要解析处理,这时该如何处理?解决方法见下面的样例代码。

  1. import lombok.Data;  
  2.   
  3. import com.google.gson.Gson;  
  4.   
  5. public class JsonTest {  
  6.     public static void main(final String[] args) {  
  7.         final Gson gson = new Gson();  
  8.         final Person jack1 = new Person();  
  9.         jack1.setAge(30);  
  10.         jack1.setName("Jackie");  
  11.   
  12.         final Person jack2 = new Person();  
  13.         jack2.setAge(1);  
  14.         jack2.setName("Jackie Boy");  
  15.   
  16.         final String json = gson.toJson(new Person[] { jack1, jack2 });  
  17.         System.out.println(json);  
  18.   
  19.         final Person[] jacks = gson.fromJson(json, Person[].class);// 这里的语法很有意思,平时很难想到这样写也可以通过编译   
  20.         for (final Person person : jacks) {  
  21.             System.out.println("jack = " + person);  
  22.         }  
  23.     }  
  24. }  
import lombok.Data;

import com.google.gson.Gson;

public class JsonTest {
    public static void main(final String[] args) {
        final Gson gson = new Gson();
        final Person jack1 = new Person();
        jack1.setAge(30);
        jack1.setName("Jackie");

        final Person jack2 = new Person();
        jack2.setAge(1);
        jack2.setName("Jackie Boy");

        final String json = gson.toJson(new Person[] { jack1, jack2 });
        System.out.println(json);

        final Person[] jacks = gson.fromJson(json, Person[].class);// 这里的语法很有意思,平时很难想到这样写也可以通过编译
        for (final Person person : jacks) {
            System.out.println("jack = " + person);
        }
    }
}
        上述样例代码的输出如下。

  1. [{"name":"Jackie","age":30},{"name":"Jackie Boy","age":1}]  
  2. jack = Person(name=Jackie, age=30)  
  3. jack = Person(name=Jackie Boy, age=1)  
[{"name":"Jackie","age":30},{"name":"Jackie Boy","age":1}]
jack = Person(name=Jackie, age=30)
jack = Person(name=Jackie Boy, age=1)
        从样例代码中可以得出一个简单的结论,解析数组形式的json串然后生成对象时,只要把fromJson方法的第二个参数调整为对象的数组类的类型即可。这是一个简单的原则。

进阶二,处理复杂对象

        前面的样例中,用于测试的Person类成员都是简单类型,没有包含其它自定义的成员。下面给出的样例中会为Person类增加表示联系方式的成员,这个成员是一个自定义的对象,看看会有什么不同。

        改进后的Person类。

  1. @Data  
  2. class Person {  
  3.     private String name;  
  4.     private int age;  
  5.     private Contact contact;  
  6. }  
  7.   
  8. @Data  
  9. class Contact {  
  10.     private String email;  
  11.     private String phoneno;  
  12. }  
@Data
class Person {
    private String name;
    private int age;
    private Contact contact;
}

@Data
class Contact {
    private String email;
    private String phoneno;
}
        处理解码和编码的样例代码,如下。

  1. import lombok.Data;  
  2.   
  3. import com.google.gson.Gson;  
  4.   
  5. public class JsonTest {  
  6.     public static void main(final String[] args) {  
  7.         final Gson gson = new Gson();  
  8.         final Person jack1 = new Person();  
  9.         jack1.setAge(30);  
  10.         jack1.setName("Jackie");  
  11.   
  12.         final Contact contact = new Contact();  
  13.         contact.setEmail("email");  
  14.         contact.setPhoneno("phoneno");  
  15.         jack1.setContact(contact);  
  16.   
  17.         final Person jack2 = new Person();  
  18.         jack2.setAge(1);  
  19.         jack2.setName("Jackie Boy");  
  20.         jack2.setContact(new Contact());  
  21.   
  22.         final Person jack3 = new Person();  
  23.         jack3.setAge(1);  
  24.         jack3.setName("Jackie Mom");  
  25.   
  26.         final String json = gson.toJson(new Person[] { jack1, jack2, jack3 });  
  27.         System.out.println(json);  
  28.   
  29.         final Person[] jacks = gson.fromJson(json, Person[].class);  
  30.         for (final Person person : jacks) {  
  31.             System.out.println("jack = " + person);  
  32.         }  
  33.     }  
  34. }  
import lombok.Data;

import com.google.gson.Gson;

public class JsonTest {
    public static void main(final String[] args) {
        final Gson gson = new Gson();
        final Person jack1 = new Person();
        jack1.setAge(30);
        jack1.setName("Jackie");

        final Contact contact = new Contact();
        contact.setEmail("email");
        contact.setPhoneno("phoneno");
        jack1.setContact(contact);

        final Person jack2 = new Person();
        jack2.setAge(1);
        jack2.setName("Jackie Boy");
        jack2.setContact(new Contact());

        final Person jack3 = new Person();
        jack3.setAge(1);
        jack3.setName("Jackie Mom");

        final String json = gson.toJson(new Person[] { jack1, jack2, jack3 });
        System.out.println(json);

        final Person[] jacks = gson.fromJson(json, Person[].class);
        for (final Person person : jacks) {
            System.out.println("jack = " + person);
        }
    }
}
        样例输出如下。

  1. [{"name":"Jackie","age":30,"contact":{"email":"email","phoneno":"phoneno"}},{"name":"Jackie Boy","age":1,"contact":{}},{"name":"Jackie Mom","age":1}]  
  2. jack = Person(name=Jackie, age=30, contact=Contact(email=email, phoneno=phoneno))  
  3. jack = Person(name=Jackie Boy, age=1, contact=Contact(email=null, phoneno=null))  
  4. jack = Person(name=Jackie Mom, age=1, contact=null)  
[{"name":"Jackie","age":30,"contact":{"email":"email","phoneno":"phoneno"}},{"name":"Jackie Boy","age":1,"contact":{}},{"name":"Jackie Mom","age":1}]
jack = Person(name=Jackie, age=30, contact=Contact(email=email, phoneno=phoneno))
jack = Person(name=Jackie Boy, age=1, contact=Contact(email=null, phoneno=null))
jack = Person(name=Jackie Mom, age=1, contact=null)
        观察样例的输出信息,可以得出一些有意思的结论。

1、当成员包含有意义的字段时,生成的json串中将会看到成员的内部字段被 {}包括起来,比如对象Person(name=Jackie, age=30, contact=Contact(email=email, phoneno=phoneno)),对应的json串为{"name":"Jackie","age":30,"contact":{"email":"email","phoneno":"phoneno"}}。

2、当成员不为null,但其内部没有有意义的字段时,对象的json串中将会使用 {} 来表示对应的成员,比如对象Person(name=Jackie Boy, age=1, contact=Contact(email=null, phoneno=null)),其对应的json串为{"name":"Jackie Boy","age":1,"contact":{}}。
3、当成员为null时,对象的json串中将不包含对应的成员信息,比如对象Person(name=Jackie Mom, age=1, contact=null),对应的json串为{"name":"Jackie Mom","age":1}。

进阶三,处理容器

        容器的处理比较简,有了前述的使用经验,相信这部分代码不需要再做详细的说明。下面是对List类型的处理,唯一看起来复杂的地方即是使用TypeAdapter生成了泛型的类型对象,原理比较复杂,不过实地使用时,照猫画虎即可。

  1. import java.lang.reflect.Type;  
  2. import java.util.Arrays;  
  3. import java.util.List;  
  4.   
  5. import lombok.Data;  
  6.   
  7. import com.google.gson.Gson;  
  8. import com.google.gson.reflect.TypeToken;  
  9.   
  10. public class JsonTest {  
  11.     public static void main(final String[] args) {  
  12.         final Gson gson = new Gson();  
  13.         final Person jack1 = new Person();  
  14.         jack1.setAge(30);  
  15.         jack1.setName("Jackie");  
  16.   
  17.         final Contact contact = new Contact();  
  18.         contact.setEmail("email");  
  19.         contact.setPhoneno("phoneno");  
  20.         jack1.setContact(contact);  
  21.   
  22.         final Person jack2 = new Person();  
  23.         jack2.setAge(1);  
  24.         jack2.setName("Jackie Boy");  
  25.         jack2.setContact(new Contact());  
  26.   
  27.         final Person jack3 = new Person();  
  28.         jack3.setAge(1);  
  29.         jack3.setName("Jackie Mom");  
  30.   
  31.         final String json = gson.toJson(Arrays.asList(jack1, jack2, jack3));  
  32.         System.out.println(json);  
  33.   
  34.         final Type personListType = new TypeToken<List<Person>>() {  
  35.         }.getType();  
  36.         final List<Person> jacks = gson.fromJson(json, personListType);  
  37.         for (final Person person : jacks) {  
  38.             System.out.println("jack = " + person);  
  39.         }  
  40.     }  
  41. }  
  42.   
  43. @Data  
  44. class Person {  
  45.     private String name;  
  46.     private int age;  
  47.     private Contact contact;  
  48. }  
  49.   
  50. @Data  
  51. class Contact {  
  52.     private String email;  
  53.     private String phoneno;  
  54. }  
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;

import lombok.Data;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class JsonTest {
    public static void main(final String[] args) {
        final Gson gson = new Gson();
        final Person jack1 = new Person();
        jack1.setAge(30);
        jack1.setName("Jackie");

        final Contact contact = new Contact();
        contact.setEmail("email");
        contact.setPhoneno("phoneno");
        jack1.setContact(contact);

        final Person jack2 = new Person();
        jack2.setAge(1);
        jack2.setName("Jackie Boy");
        jack2.setContact(new Contact());

        final Person jack3 = new Person();
        jack3.setAge(1);
        jack3.setName("Jackie Mom");

        final String json = gson.toJson(Arrays.asList(jack1, jack2, jack3));
        System.out.println(json);

        final Type personListType = new TypeToken<List<Person>>() {
        }.getType();
        final List<Person> jacks = gson.fromJson(json, personListType);
        for (final Person person : jacks) {
            System.out.println("jack = " + person);
        }
    }
}

@Data
class Person {
    private String name;
    private int age;
    private Contact contact;
}

@Data
class Contact {
    private String email;
    private String phoneno;
}
        代码的执行输出如下。

  1. [{"name":"Jackie","age":30,"contact":{"email":"email","phoneno":"phoneno"}},{"name":"Jackie Boy","age":1,"contact":{}},{"name":"Jackie Mom","age":1}]  
  2. [{"name":"Jackie","age":30,"contact":{"email":"email","phoneno":"phoneno"}},{"name":"Jackie Mom","age":1}]  
  3. jack = Person(name=Jackie, age=30, contact=Contact(email=email, phoneno=phoneno))  
  4. jack = Person(name=Jackie Mom, age=1, contact=null)  
[{"name":"Jackie","age":30,"contact":{"email":"email","phoneno":"phoneno"}},{"name":"Jackie Boy","age":1,"contact":{}},{"name":"Jackie Mom","age":1}]
[{"name":"Jackie","age":30,"contact":{"email":"email","phoneno":"phoneno"}},{"name":"Jackie Mom","age":1}]
jack = Person(name=Jackie, age=30, contact=Contact(email=email, phoneno=phoneno))
jack = Person(name=Jackie Mom, age=1, contact=null)
        如下是对Map类型的处理。

  1. import java.lang.reflect.Type;  
  2. import java.util.Arrays;  
  3. import java.util.HashMap;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6.   
  7. import lombok.Data;  
  8.   
  9. import com.google.gson.Gson;  
  10. import com.google.gson.reflect.TypeToken;  
  11.   
  12. public class JsonTest {  
  13.     public static void main(final String[] args) {  
  14.         final Gson gson = new Gson();  
  15.         final Person jack1 = new Person();  
  16.         jack1.setAge(30);  
  17.         jack1.setName("Jackie");  
  18.   
  19.         jack1.putValue("email""email");  
  20.         jack1.putValue("phoneno""phoneno");  
  21.   
  22.         final Person jack2 = new Person();  
  23.         jack2.setAge(1);  
  24.         jack2.setName("Jackie Boy");  
  25.   
  26.         final Person jack3 = new Person();  
  27.         jack3.setAge(1);  
  28.         jack3.setName("Jackie Boy");  
  29.         final Contact contacts = new Contact();  
  30.         contacts.setEmail("email");  
  31.         contacts.setPhoneno("phoneno");  
  32.         jack3.putValue("contacts", contacts);  
  33.   
  34.         final String json = gson.toJson(Arrays.asList(jack1, jack2, jack3));  
  35.         System.out.println(json);  
  36.   
  37.         final Type personListType = new TypeToken<List<Person>>() {  
  38.         }.getType();  
  39.         final List<Person> jacks = gson.fromJson(json, personListType);  
  40.         for (final Person person : jacks) {  
  41.             System.out.println("jack = " + person);  
  42.         }  
  43.     }  
  44. }  
  45.   
  46. @Data  
  47. class Person {  
  48.     private String name;  
  49.     private int age;  
  50.     private Map<String, Object> contact;  
  51.   
  52.     // private Contact contact;   
  53.     public Person() {  
  54.         contact = new HashMap<String, Object>();  
  55.     }  
  56.   
  57.     public void putValue(final String key, final Object value) {  
  58.         contact.put(key, value);  
  59.     }  
  60. }  
  61.   
  62. @Data  
  63. class Contact {  
  64.     private String email;  
  65.     private String phoneno;  
  66. }  
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lombok.Data;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class JsonTest {
    public static void main(final String[] args) {
        final Gson gson = new Gson();
        final Person jack1 = new Person();
        jack1.setAge(30);
        jack1.setName("Jackie");

        jack1.putValue("email", "email");
        jack1.putValue("phoneno", "phoneno");

        final Person jack2 = new Person();
        jack2.setAge(1);
        jack2.setName("Jackie Boy");

        final Person jack3 = new Person();
        jack3.setAge(1);
        jack3.setName("Jackie Boy");
        final Contact contacts = new Contact();
        contacts.setEmail("email");
        contacts.setPhoneno("phoneno");
        jack3.putValue("contacts", contacts);

        final String json = gson.toJson(Arrays.asList(jack1, jack2, jack3));
        System.out.println(json);

        final Type personListType = new TypeToken<List<Person>>() {
        }.getType();
        final List<Person> jacks = gson.fromJson(json, personListType);
        for (final Person person : jacks) {
            System.out.println("jack = " + person);
        }
    }
}

@Data
class Person {
    private String name;
    private int age;
    private Map<String, Object> contact;

    // private Contact contact;
    public Person() {
        contact = new HashMap<String, Object>();
    }

    public void putValue(final String key, final Object value) {
        contact.put(key, value);
    }
}

@Data
class Contact {
    private String email;
    private String phoneno;
}

        代码的输出如下。

  1. [{"name":"Jackie","age":30,"contact":{"email":"email","phoneno":"phoneno"}},{"name":"Jackie Boy","age":1,"contact":{}},{"name":"Jackie Boy","age":1,"contact":{"contacts":{"email":"email","phoneno":"phoneno"}}}]  
  2. jack = Person(name=Jackie, age=30, contact={email=email, phoneno=phoneno})  
  3. jack = Person(name=Jackie Boy, age=1, contact={})  
  4. jack = Person(name=Jackie Boy, age=1, contact={contacts={email=email, phoneno=phoneno}})  
[{"name":"Jackie","age":30,"contact":{"email":"email","phoneno":"phoneno"}},{"name":"Jackie Boy","age":1,"contact":{}},{"name":"Jackie Boy","age":1,"contact":{"contacts":{"email":"email","phoneno":"phoneno"}}}]
jack = Person(name=Jackie, age=30, contact={email=email, phoneno=phoneno})
jack = Person(name=Jackie Boy, age=1, contact={})
jack = Person(name=Jackie Boy, age=1, contact={contacts={email=email, phoneno=phoneno}})

        对比之下可以发现,gson在处理Map类型时,不需要专门定义类型适配器来做类型转换,算是一个优点吧。


======================================

        如下是牢骚,和技术无关。

======================================

        最近项目里需要和一个新产品对接,看到接口文档的时候,我和小伙伴们都震惊了。对方给出的接口文档里提出使用SOAP来完成业务上的方法调用,但数据使用json格式描述,这使我不得不承认人类的想像力是多么的丰富。以前使用SOAP的时候场景是比较简单的,借助Apache Axis 1.4工具,先用Java原生的接口和Bean定义好Java类,然后使用工具对Java类进行处理,生成对应的WSDL,最后分别生成客户端和服务器端的编、解码的存根和框架库,其余的事情就是实现服务端或者调用客户端了。现在做的事情稍复杂点,过程是类似的,只是接口调用后拿到的字段是json格式描述的,使用时还需要根据接口文档描述,写代码解析出业务相关的信息,进而根据这些信息完成业务逻辑实现。也许是对方产品的业务场景比复杂吧,导致他们养成了定义类似这种接口的习惯。

        最近感觉整个人比较懒,可能是进入了新的迷茫期吧,遇到没有使用过的技术时钻研的动力不足。不过好在json技术比较成熟,可供选择的开源软件非常多,使用都比较简单。我在项目里应用的是gson.jar,文档和能力都让我非常满意。在短暂的学习与尝试,这个过程大约有一个小时吧,又花了一个小时完成了项目特性的开发,总体而言没有让我费太大的力气,反倒是钻研接口文档花了不少时间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值