我的序列化器相互依赖,我如何确保两者都使用

时间:2016-09-09 16:04:03

标签: java serialization gson

想象一下,我有两个课程,MyClassMyOtherClass。我为MyClass编写了一个序列化程序。没有它,尝试序列化MyOtherClass将无法正常工作(因为MyClass在没有我编写的序列化程序的情况下无法序列化。

package com.mycompany.javatest;

import com.google.gson.*;
import java.lang.reflect.*;

public class JavaTest {

    static class MyClass {

        private int someValue = 123;
    }

    static class MyOtherClass {

        private MyClass mc = new MyClass();
    }

    static class MyClassSerializer implements JsonSerializer<MyClass> {

        @Override
        public JsonElement serialize(MyClass t, Type type, JsonSerializationContext jsc) {

            JsonObject result = new JsonObject();
            // (Doing some magic to serialize the object here...)
            result.add("someValue", jsc.serialize(t.someValue));
            return result;

        }
    }

    static class MyOtherClassSerializer implements JsonSerializer<MyOtherClass> {

        @Override
        public JsonElement serialize(MyOtherClass t, Type type, JsonSerializationContext jsc) {

            JsonObject result = new JsonObject();
            result.add("mc", jsc.serialize(t.mc)); // <--- Will fail if not using the MyClassSerializer
            return result;

        }
    }

    public static void main(String[] args) {

        GsonBuilder gb = new GsonBuilder();
        gb.registerTypeAdapter(MyOtherClassSerializer.class, new MyOtherClassSerializer());
        Gson gson = gb.create();
        MyOtherClass object = new MyOtherClass();

        String json = gson.toJson(object, MyOtherClass.class); // <--- MyClassSerializer.serialize MUST be invoked, or this will fail

    }
}

我的问题是,如何在注册MyClassSerializer时强制注册MyOtherClassSerializer?显而易见的答案是只注册两个类型的适配器,但我想知道在注册MyOtherClassSerializer时是否有办法强制注册。一种选择是只允许类型适配器被&#34;寄存器&#34;像这样的方法,但我不喜欢这个解决方案。我仍然希望MyClassSerializer可以访问。

public void registerMyOtherClassSerializer(GsonBuilder builder) {

    builder.registerTypeAdapter(MyClass.class, new MyClassSerializer());
    builder.registerTypeAdapter(MyOtherClass.class, new MyOtherClassSerializer());

}

思想?

1 个答案:

答案 0 :(得分:0)

感谢ThomasKläger。这就是我最终做的事情:

package com.mycompany.javatest;

import com.google.gson.*;
import com.google.gson.reflect.*;
import com.google.gson.stream.*;
import java.io.*;

public class JavaTest {

    static class MyClass {
        private final int someValue = 123;
    }

    static class MyOtherClass {
        private final MyClass mc = new MyClass();
    }

    public static void main(String[] args) {

        GsonBuilder gb = new GsonBuilder();
        gb.registerTypeAdapterFactory(new MyTypeAdapterFactory());
        Gson gson = gb.create();
        MyOtherClass object = new MyOtherClass();

        String json = gson.toJson(object, MyOtherClass.class);
        System.out.println(json);

    }

    static class MyTypeAdapterFactory implements TypeAdapterFactory {

        @Override
        public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> tt) {

            if (MyClass.class.isAssignableFrom(tt.getRawType())) {
                return (TypeAdapter<T>) new MyClassAdapter();
            }

            return null;
        }

        private static class MyClassAdapter extends TypeAdapter<MyClass> {

            @Override
            public MyClass read(JsonReader reader) throws IOException {
                throw new UnsupportedOperationException();
            }

            @Override
            public void write(JsonWriter writer, MyClass t) throws IOException {
                writer.beginObject();
                writer.name("someValue");
                writer.value(t.someValue); // (Doing some magic to serialize the object here...)
                writer.endObject();
            }
        }
    }
}