Android中Gson的使用 Android中Gson的使用 1 简介Gson是一个Java库,作用是将Java对象转换成它对应的JSON表示。 即使你无法修改源代码,你也能通过Gson对代码中的类做解析和变换。 充分支持Java泛型。 在学习过程中我们能发现,第一点很好理解,并且也简化了对Gson的使用;而第二点对泛型的支持,则是掌握Gson框架的一个难点。 下图是Gson的设计目标:
image 其中功能性是难点,也比较不好理解,先重点掌握Gson的基本使用方式即可。 2 快速上手Gson的基本使用是非常简单的。 在正式开始使用Gson之前,先来简单回顾一下JSON的基础知识。 number,例如10 string,例如“abcd” value,value可以是上面的number和String,也可以是下面的object和array,value的概念赋予了JSON嵌套表示的能力。value还包括三个特殊值:true,false和null。 array,形如 [value, value, ... value] 的列表形式。 object,形如 {string:value, string:value, ... string:value} 的键值对形式。 4 使用GsonGson库的关键类就是Gson,使用起来很简单,直接实例化 new Gson() 即可。它也可以通过GsonBuilder 类来实例化,进行一些初始化设置,初学时无需深入了解。 序列化是指将Java对象转换成JSON字符串,使用Gson.toJson(...)方法来进行序列化操作。举几个基本的序列化例子: number: Gson gson = new Gson(); gson.toJson(1); // ==> 1 gson.toJson(new Long(10)); // ==> 10string: gson.toJson("abcd"); // ==> "abcd"value: gson.toJson(true); // ==> trueobject: class BagOfPrimitives { private int value1 = 1; private String value2 = "abc"; private transient int value3 = 3; BagOfPrimitives() { // no-args constructor } } // Serialization BagOfPrimitives obj = new BagOfPrimitives(); Gson gson = new Gson(); String json = gson.toJson(obj); // ==> json is {"value1":1,"value2":"abc"}array: Gson gson = new Gson(); int[] ints = {1, 2, 3, 4, 5}; String[] strings = {"abc", "def", "ghi"}; // Serialization gson.toJson(ints); // ==> [1,2,3,4,5] gson.toJson(strings); // ==> ["abc", "def", "ghi"] 4.2 基本反序列化方法反序列化是指将JSON字符串传换成Java对象,使用Gson.fromJson(...)方法来进行反序列化操作。反序列化和序列化不同的一点是,你需要告诉Gson目标对象的类型是什么。举几个基本的反序列化例子: number: int one = gson.fromJson("1", int.class); Long one = gson.fromJson("1", Long.class);string: String str = gson.fromJson("\"abc\"", String.class);value: Boolean f = gson.fromJson("false", Boolean.class);object: class BagOfPrimitives { private int value1 = 1; private String value2 = "abc"; private transient int value3 = 3; BagOfPrimitives() { // no-args constructor } } String json = "{"value1":1,"value2":"abc"}"; BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);array: int[] ints = {1, 2, 3, 4, 5}; int[] ints2 = gson.fromJson("[1,2,3,4,5]", int[].class); // ==> ints2 和 ints 相同。 4.3 序列化和反序列化中的注意点对象的字段可以并推荐使用private。 无需使用注解指定哪些字段被包括在序列化和反序列化操作中。当前类,和它所有父类的所有字段都是默认包括的。 如果字段使用transient修饰,它被默认忽略,不包含在序列化和反序列化操作中。 Gson可以正确处理null值。 序列化时,值为null的字段会被跳过。 反序列化时,JSON中缺失的项,其对象对应的字段会被设为null。 内部类、匿名类等隐含的外部类的字段会被忽略,不包含在序列化和反序列化中。 5 Gson的进阶使用 5.1 修改字段名从上面的例子可以看出来,在序列化和反序列化时,字段名直接用来作为键值对中的key。有时,对象和它的JSON表示命名并不完全一致,这时就需要修改字段名,有两种方法: 结果将是 {"custom_naming":"first","SomeOtherField":"second"} 5.2 嵌套类(例如内部类)的情况对于静态内部类,Gson可以直接处理。 注意:默认情况下,B类不能用Gson序列化。 Gson不能讲{"b":"abc"}反序列化成B的对象,除非将B定义成静态的。另一个解决方法是写一个自定义的InstanceCreator: public class InstanceCreatorForB implements InstanceCreator<A.B> { private final A a; public InstanceCreatorForB(A a) { this.a = a; } public A.B createInstance(Type type) { return a.new B(); } }这是可行的,但不推荐这样来用。 5.3 集合的情况Gson对集合的处理方式比较丑陋,这是由于Java泛型机制决定的,没有更好的解决办法: Gson gson = new Gson(); Collection<Integer> ints = Lists.immutableList(1,2,3,4,5); // Serialization String json = gson.toJson(ints); // ==> json is [1,2,3,4,5] // Deserialization Type collectionType = new TypeToken<Collection<Integer>>(){}.getType(); Collection<Integer> ints2 = gson.fromJson(json, collectionType); // ==> ints2 和 ints 相同。如果集合中存储的是任意类型的对象,Gson可以序列化它,但不能做反序列化,这是因为用户无法指明集合中每一个对象的类型。在反序列化时,集合必须是一个明确的类型。如果遵循良好的Java编程规范,这基本不会造成什么问题。 5.4 泛型的处理泛型的处理和上面集合的处理类似,因为集合定义中使用的就是泛型。 要解决这一问题,你需要指明你的泛型类型的类型参数(parameterized type),使用集合的例子中看到过的TypeToken类: Type fooType = new TypeToken<Foo<Bar>>() {}.getType(); gson.toJson(foo, fooType); gson.fromJson(json, fooType);初步使用Gson时,可以不必深究这一泛型处理的实现原理,知道怎么做即可。 (责任编辑:) |