Gson详解

来源:互联网 发布:美团app数据分析报告 编辑:程序博客网 时间:2024/06/03 14:09

我平时使用到的Json库主要是Gson,为了更 进一步了解我对Gson做了比较详细的学习

Gson的API设计

首先了解一下Gson的关于json的主要API,最顶层的类是JsonElement(表示这是一个Json对象),子类有如下几个

  1、JsonArray 数组形式,可以理解为List类型的数据,如 [  {'a':'a'}, {'b','b'} ]等

2、JsonNull 指null类型

3、JsonObject:指的是标准的json对象{'a':'a' },并且提供了一系列方法,如添加属性 jsonObject.addProperty("b","b") , 还可以添加其他JsonElement,如jsonObject.add("a",jsonElement),这里jsonElement可以为任何JsonElement及其子类

  4、JsonPrimitive:指原始类型 


Gson反序列化时(如果有泛型)是如何获取泛型的具体类型的

我们知道java在运行的时候是用了泛型擦除的机制,在运行期,其实所有泛型都是Object类型的,我们如果设想自己想要实现反序列化(也就是将字符串转为对象)我们可能会这样

1、解析数据 如果为 [ {  'username' :' abc123'  , 'password': '666'' } ] ,得到键值对如 :username = abc123等

2、拿到要转化对象的类型如果为  List<Person> aa = new ArrayList<Person>();, 我们可能想象有一个方法可以通过aa.getClass()然后通过class来获得Person类型,但是这里jdk里面是没有这样的方法的,那我们如何获得呢

Type type = new TypeToken<List<Person>>(){}.getType();

通过Type就能获得class了,其实这里是利用了jdk中class的一个方法getGenericSuperclass();可以通过class获得当前类的父类的泛型参数类型,了解了原理我们再看

Gson的实现,其实是创建了一个匿名内部类,这个类的父类是TypeToken,而参数类型就是我们想要转换的类型


Gson使用篇

 Gson的使用很简单,将对象转化为json

Gson g  = new Gson();g.toJson(object);

自定义Gson

1 如果想要得到自定义的效果(如想要自定义日期格式)

可以这样常见gson

Gson g = new GsonBuilder().setDateFormat("yyyy-MM-dd hh-mm-ss ").create();


2 自定义某个字段的输出名称

如果有一个类 

class Person{  private String id;  private String username;  private String desc;}


在序列化的时候,我们想要将id变为 person_id,username变为 uname,我们可以设置fieldNamingStrategy(字段命名策略)

自定义命名策略需要实现FieldNamingStrategy接口,然后实现里面的translateName方法

class PersonFieldNamingStrategy{public String translatename(Field f){if(f.getName().equals("id"))return "person_id";if(f.getName().equals("username")) return "uname";   }}


gson在对字段进行序列化的时候都会调用translateName方法,我们就可以再这里进行字段名的修改,

其实修改字段序列化名称还有一种比较简单的方法,那就是给对象加上注解,如

@SerializedName("person_id")private String id;

这样在序列化时就会生成  {'person_id' : '001'}


3 如果序列化时想要排除某些字段

拿上面的Person举例,如果我们序列化时想要排除id字段

自定义排除策略,这需要实现ExcludeStrategy

class PersonExcludeStrategy implements ExcludeStrategy{//如果不想序列化某个类就在这里返回true  public boolean shouldSkipClass(Class<?> arg0) {  return false; }//如果不想序列化某个字段public boolean shouldSkipField(FieldAttributes f) {   if(f.getName().equals("id"))return true;   return false;  }}


这样序列化就能排除id字段 , 如果字段为 tranisent,则不会序列化


4 自定义序列化器,和反序列化器

如果想要更灵活的方式来控制序列化和反序列化,我们就要自定义自己的Serializer和Deserializer了

自定义Serializer(序列化器)

class PersonSerializer  implements JsonSerializer<Person>{   public JsonElement serialize(Person p, Type type,JsonSerializationContext context) {//在这里返回任何类型的JsonElement,gson会直接序列化这里返回的jsonElement }}

如果要使用这个Serializer,我们需要注册

Gson g = new GsonBuilder().registerTypeAdapter(Person.class,PersonSerializer)

反序列化器也是差不多,需要实现JsonDeserializer

class PersonDeserializer implements JsonDeserializer<Person>{public Person deserialize(JsonElement elt, Type type,JsonDeserializationContext context) throws JsonParseException {if(elt.isJsonObject()){JsonObject  j  = (JsonObject) elt;Person p = (Person)type.getClass().newInstance();p.setUsername(  j.getProperty("username") .getAsString()  )  ;}}}
注册反序列化器

Gson g = new GsonBuilder().registerTypeAdapter(Person.class, PersonDeserializer);


这里说了更多关gson使用的 介绍 http://blog.csdn.net/zxhoo/article/details/21471005

http://blog.csdn.net/canchew/article/details/7545363

0 0
原创粉丝点击