Gson详解--提高篇

来源:互联网 发布:富善投资知乎 编辑:程序博客网 时间:2024/06/06 19:15

除了默认的序列化和反序列化行为,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());  }}//自定义对象创建,需要实现InstanceCreatorprivate 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

原创粉丝点击