Gson详解--提高篇

除了默认的序列化和反序列化行为,gson还允许自定义某些类的序列化和反序列化行为。自定义行为一般用于需要使json对象具有和原来类不同的表示形式,或者默认行为会报错的情况。主要分为三个类
Json Serializers: 自定义某种对象类型的序列化行为

Json Deserializers: 自定义某种对象类型的反序列化行为

Instance Creators: 自定义某种对象的创建行为

此时我们需要配置gsonbuilder,然后用gsonbuilder来创建gson对象,builder模式大家应该很熟悉了
代码如下

GsonBuilder gsonBuilder= new GsonBuilder();
gson.registerTypeAdapter(MyType.class, new MySerializer());
gson.registerTypeAdapter(MyType.class, new MyDeserializer());
gson.registerTypeAdapter(MyType.class, new MyInstanceCreator());
Gson gson=gsonBuilder.create();

为某类型注册了自定义的序列化和反序列化行为之后,在转换的过程中一旦遇到该类型的对象,就会调用你注册的行为来序列化。
这些的类的实现也很容易。

//自定义序列化,需要实现JsonSerializer接口
private class DateTimeSerializer implements JsonSerializer<DateTime> {
  public JsonElement serialize(DateTime src, Type typeOfSrc, JsonSerializationContext context) {
    return new JsonPrimitive(src.toString());
  }
}
//自定义序列化,需要实现DateTimeDeserializer 接口
private class DateTimeDeserializer implements JsonDeserializer<DateTime> {
  public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {
    return new DateTime(json.getAsJsonPrimitive().getAsString());
  }
}
//自定义对象创建,需要实现InstanceCreator
private class MoneyInstanceCreator implements InstanceCreator<Money> {
  public Money createInstance(Type type) {
    return new Money("1000000", CurrencyCode.USD);
  }
}

在我个人使用gson的过程中,我发现有些时候是不得不用自定义序列化和反序列化的,因为在使用默认的行为的情况下,对一些复杂对象经常出错,具体原因我也不知道为什么,很多时候都是出现了死循环,可能java一些类中本身就存在双向引用吧,此外还有一些其他的异常,主要原因都是java一些类本身的继承结构太深了。

我们以序列化Image为例(该类直接序列化会报错)
这个代码是我实际项目中使用的,将javafx的image对象序列化(当然对于图像对象,最后还要使用压缩流来减少体积)

public class GsonImage implements JsonSerializer<Image>,JsonDeserializer<Image> {

    @Override
    public Image deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
            throws JsonParseException {

        Gson gson=new Gson();
        byte[] bs=gson.fromJson(json.getAsString(), byte[].class);
        BufferedImage image = null;
        try {
            //从字节数组创建图片
            image = ImageIO.read(new ByteArrayInputStream(bs));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Image image2=SwingFXUtils.toFXImage(image, null);

        return image2;
    }

    @Override
    public JsonElement serialize(Image image, Type typeOfSrc, JsonSerializationContext context) {



        Gson gson=new Gson();
        ByteArrayOutputStream stream=new ByteArrayOutputStream();
        BufferedImage bufferedImage=SwingFXUtils.fromFXImage(image, null);
        try {
            ImageIO.write(bufferedImage, "PNG", stream);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        byte[] imgBytes=stream.toByteArray();
        //实际上序列化的是字节数组
        String string=gson.toJson(imgBytes);

        return new JsonPrimitive(string);
    }

}

除了三种自定义行为之外,gsonbuilder还提供了一些配置

setPrettyPrinting() //设置输出格式为可读性优先(默认是体积小优先)
serializeNulls() //设置输出null(默认null会被忽略)
excludeFieldsWithModifiers()//设置不被包括在序列化中的修饰符(默认为static //transient,但是你可以覆盖设置)

关于gson就介绍到这里

可以访问gson的github帮助页面来获取更多信息
https://github.com/google/gson/blob/master/UserGuide.md

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值