gson 在自定义反序列化器中调用标准反序列化

发布于 2024-09-27 03:03:16 字数 506 浏览 3 评论 0原文

是否可以在 gson 中编写一个 json 反序列化器,首先调用默认行为,然后我可以对我的对象进行一些后处理。例如:

public class FooDeserializer implements JsonDeserializer<Foo> {
    public Foo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {      
        Foo foo = context.deserialize(json, typeOfT);//Standard deserialization call?????
        foo.doSomething();
        return foo();
    }
}   

我正在使用 gson 1.3(我不能使用任何其他版本,因为我只能使用企业中的版本 存储库)

谢谢

Is it possible to write a json deserializer in gson that invokes the default behaviour first and then i can do some post processing on my object. For example:

public class FooDeserializer implements JsonDeserializer<Foo> {
    public Foo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {      
        Foo foo = context.deserialize(json, typeOfT);//Standard deserialization call?????
        foo.doSomething();
        return foo();
    }
}   

I am using gson 1.3 (I cannot use any other version as i can only use the versions in the corporate
repository)

thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

您可以通过为要反序列化的对象(例如 CustomClass.class)实现自定义 TypeAdapterFactory 来实现此目的,如下所示。

 public class CustomTypeAdapterFactory implements TypeAdapterFactory {

    public final TypeAdapter create(Gson gson, TypeToken type) {
     return new TypeAdapter() {
            @Override 
            public void write(JsonWriter out, Object value) throws IOException {
                JsonElement tree = delegate.toJsonTree(value);
                //add code for writing object
            }

            @Override 
            public Object read(JsonReader in) throws IOException {
                JsonElement tree = elementAdapter.read(in);
                //Add code for reading object
            }
        };
    }
  }

然后用Gson将其注册为

Gson gson = new GsonBuilder().registerTypeAdapter(CustomClass.class,new CustomTypeAdapterFactory()).create();

You can do that by implementing custom TypeAdapterFactory for your object (say CustomClass.class) to be deserialized as below.

 public class CustomTypeAdapterFactory implements TypeAdapterFactory {

    public final TypeAdapter create(Gson gson, TypeToken type) {
     return new TypeAdapter() {
            @Override 
            public void write(JsonWriter out, Object value) throws IOException {
                JsonElement tree = delegate.toJsonTree(value);
                //add code for writing object
            }

            @Override 
            public Object read(JsonReader in) throws IOException {
                JsonElement tree = elementAdapter.read(in);
                //Add code for reading object
            }
        };
    }
  }

And then registering it with Gson as

Gson gson = new GsonBuilder().registerTypeAdapter(CustomClass.class,new CustomTypeAdapterFactory()).create();
千纸鹤带着心事 2024-10-04 03:03:16

查看 http://gsonfire.io

这是我制作的一个库,它扩展了 Gson 来处理 Post-serialization 和 Post-serialization 等情况。反序列化

此外,它还有许多其他很酷的功能,这些功能是我随着时间的推移使用 Gson 所需要的。

Check out http://gsonfire.io

It's a library I made that extends Gson to handle cases like Post-serialization and Post-deserialization

Also it has many other cool features that I've needed over time with Gson.

仅此而已 2024-10-04 03:03:16
public class YourDeserializer<Foo> extends FooDeserializer<Foo>  
 {  
     public Foo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)    throws JsonParseException {       
        Foo foo = super.deserialize(json, typeOfT,context);  
        foo.doSomething();  //put logic   
        return foo();  
    }  
}  
public class YourDeserializer<Foo> extends FooDeserializer<Foo>  
 {  
     public Foo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)    throws JsonParseException {       
        Foo foo = super.deserialize(json, typeOfT,context);  
        foo.doSomething();  //put logic   
        return foo();  
    }  
}  
愛上了 2024-10-04 03:03:16

以下是基于 @user1556622 提供的不完整答案以及 code.google.com/p/google 中的讨论的完整实现-gson/issues/detail?id=43

因此,我们可以序列化抽象 Field 对象列表,并顺利地反序列化它,独立于特定 Field 的具体实现及其层次结构深度。

class MyClass { //class which we would like to serialiaze/deserialize
   List<Field> fields; //field is an hierarchy of classes
}


/**
 * Purpose of this adapter is simple:
 * 1) put during serialization in all Field objects additional property describing class
 * 2) during deserialization invoke (based on class info) necessary deserializer to create class
 */

public class FieldTypeAdapterFactory implements TypeAdapterFactory {
    private static final String CLASS_META_KEY="clz";
    Gson gson;
    TypeToken<?> type;
    TypeAdapter<Field> fieldAdapter;
    TypeAdapter<JsonElement> elementAdapter;
    TypeAdapterFactory taf;

    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        if (!Field.class.isAssignableFrom(type.getRawType()))
            return null; // this class only serializes 'Field' and its subtypes

        this.type=type;
        this.gson=gson;
        this.taf=this;
        fieldAdapter = gson.getDelegateAdapter(taf, TypeToken.get(Field.class));
        elementAdapter = gson.getAdapter(JsonElement.class);
        TypeAdapter<T> result = new FieldTypeAdapter<T>();
        result.nullSafe();
        return result;
    }

    class FieldTypeAdapter<T> extends TypeAdapter<T> {

        public FieldTypeAdapter() {
        }

        @Override
        public void write(JsonWriter out, Object value) throws IOException {
            if(value instanceof Field) {
                JsonObject object = fieldAdapter.toJsonTree((Field )value).getAsJsonObject();
                object.addProperty(CLASS_META_KEY, value.getClass().getCanonicalName());
                elementAdapter.write(out, object);
            }
            else {
                elementAdapter.write(out, (JsonElement) value);
            }
        }

        @Override
        public T read(JsonReader in) throws IOException {
            JsonObject object = elementAdapter.read(in).getAsJsonObject();
            if (object.has(CLASS_META_KEY)) {
                String className=object.get(CLASS_META_KEY).getAsString();
                try {
                    Class<?> clz = Class.forName(className);
                    TypeAdapter<?> adapter = gson.getDelegateAdapter(taf, TypeToken.get(clz));
                    return (T) adapter.fromJsonTree(object);
                }
                catch (Exception e) {
                    return (T )fieldAdapter.fromJsonTree(object);
                }
            }
            else
                return (T )elementAdapter.fromJsonTree(object);
        }
    }
}

工厂注册:

Gson gson = new GsonBuilder()
                .registerTypeAdapterFactory(new FieldTypeAdapterFactory())
                .create();

Here's full implementation based on incomplete answer provided by @user1556622 and discussion in code.google.com/p/google-gson/issues/detail?id=43.

As a result we can serialize list of abstract Field objects and smoothly deserialize it independent on concrete implementation of specific Field and its hierarchy depth.

class MyClass { //class which we would like to serialiaze/deserialize
   List<Field> fields; //field is an hierarchy of classes
}


/**
 * Purpose of this adapter is simple:
 * 1) put during serialization in all Field objects additional property describing class
 * 2) during deserialization invoke (based on class info) necessary deserializer to create class
 */

public class FieldTypeAdapterFactory implements TypeAdapterFactory {
    private static final String CLASS_META_KEY="clz";
    Gson gson;
    TypeToken<?> type;
    TypeAdapter<Field> fieldAdapter;
    TypeAdapter<JsonElement> elementAdapter;
    TypeAdapterFactory taf;

    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        if (!Field.class.isAssignableFrom(type.getRawType()))
            return null; // this class only serializes 'Field' and its subtypes

        this.type=type;
        this.gson=gson;
        this.taf=this;
        fieldAdapter = gson.getDelegateAdapter(taf, TypeToken.get(Field.class));
        elementAdapter = gson.getAdapter(JsonElement.class);
        TypeAdapter<T> result = new FieldTypeAdapter<T>();
        result.nullSafe();
        return result;
    }

    class FieldTypeAdapter<T> extends TypeAdapter<T> {

        public FieldTypeAdapter() {
        }

        @Override
        public void write(JsonWriter out, Object value) throws IOException {
            if(value instanceof Field) {
                JsonObject object = fieldAdapter.toJsonTree((Field )value).getAsJsonObject();
                object.addProperty(CLASS_META_KEY, value.getClass().getCanonicalName());
                elementAdapter.write(out, object);
            }
            else {
                elementAdapter.write(out, (JsonElement) value);
            }
        }

        @Override
        public T read(JsonReader in) throws IOException {
            JsonObject object = elementAdapter.read(in).getAsJsonObject();
            if (object.has(CLASS_META_KEY)) {
                String className=object.get(CLASS_META_KEY).getAsString();
                try {
                    Class<?> clz = Class.forName(className);
                    TypeAdapter<?> adapter = gson.getDelegateAdapter(taf, TypeToken.get(clz));
                    return (T) adapter.fromJsonTree(object);
                }
                catch (Exception e) {
                    return (T )fieldAdapter.fromJsonTree(object);
                }
            }
            else
                return (T )elementAdapter.fromJsonTree(object);
        }
    }
}

Registration of factory:

Gson gson = new GsonBuilder()
                .registerTypeAdapterFactory(new FieldTypeAdapterFactory())
                .create();
小草泠泠 2024-10-04 03:03:16
public class FooDeserializer implements JsonDeserializer<Foo> {
public Foo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {      
    Foo foo=new Gson().fromJson(json, Foo.class); // use default Gson object
    foo.doSomething();
    return foo;
}
public class FooDeserializer implements JsonDeserializer<Foo> {
public Foo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {      
    Foo foo=new Gson().fromJson(json, Foo.class); // use default Gson object
    foo.doSomething();
    return foo;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文