Gson详解

我平时使用到的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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值