Gson bug?解串器的存在会破坏Gson中序列化的过程

时间:2014-03-20 15:39:07

标签: java serialization gson

在下面的示例中,我尝试序列化自定义类Couple,其中包含Point2D类型的字段。

我发现,SErialzing的过程取决于DEserializer的存在。

此外,如果存在反序列化器,则序列化过程的工作错误。

desrializer如何影响逆向过程以及它如何破坏它?

未使用Point2DInstanceCreator类。

package tests;

import java.awt.geom.Point2D;
import java.lang.reflect.Type;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;


public class Try07_Point2D {

    static class Couple {
        Point2D p1, p2;

        public Couple() {
            p1 = new Point2D.Double();
            p2 = new Point2D.Double();
        }

        public Couple(double x1, double y1, double x2, double y2) {
            p1 = new Point2D.Double(x1, y1);
            p2 = new Point2D.Double(x2, y2);
        }

        void set(double x1, double y1, double x2, double y2) {
            p1.setLocation(x1, y1);
            p2.setLocation(x2, y2);
        }

        @Override
        public boolean equals(Object object) {
            if( object instanceof Couple) {
                Couple ano = (Couple) object;
                return 
                        (p1 == null && ano.p1 == null || p1 != null && p1.equals(ano.p1)) &&
                        (p2 == null && ano.p2 == null || p2 != null && p2.equals(ano.p2));
            }
            return false;
        }
    }

    static class Point2DInstanceCreator implements InstanceCreator<Point2D>{

        @Override
        public Point2D createInstance(Type type) {
            return new Point2D.Double();
        }

    }

    static class Point2DDeserializer implements JsonDeserializer<Point2D> {

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

            Point2D.Double ans = new Point2D.Double();
            JsonObject obj = json.getAsJsonObject();

            ans.x = obj.get("x").getAsDouble();
            ans.y = obj.get("y").getAsDouble();

            return ans;
        }

    }

    public static void main(String[] args) {

        GsonBuilder gb;
        Gson gson0;

        gb = new GsonBuilder();

        gb = gb
         .enableComplexMapKeySerialization()
         .serializeNulls()
         .setPrettyPrinting()
         .setVersion(1.0)

    //     .registerTypeAdapter(Point2D.class, new Point2DInstanceCreator())
    //     .registerTypeAdapter(Point2D.class, new Point2DDeserializer())
         ;

        gson0 = gb.create();

        Couple value1;

        value1 = new Couple(12, 13, 14, 15);



        System.out.println("Version without deserializer:");
        System.out.println( gson0.toJson(value1) );

        gb = new GsonBuilder();

        gb = gb
         .enableComplexMapKeySerialization()
         .serializeNulls()
         .setPrettyPrinting()
         .setVersion(1.0)

//       .registerTypeAdapter(Point2D.class, new Point2DInstanceCreator())
         .registerTypeAdapter(Point2D.class, new Point2DDeserializer())
         ;

        gson0 = gb.create();



        System.out.println("Version with deserializer:");
        System.out.println( gson0.toJson(value1) );


    }

}

输出如下:

Version without deserializer:
{
  "p1": {
    "x": 12.0,
    "y": 13.0
  },
  "p2": {
    "x": 14.0,
    "y": 15.0
  }
}
Version with deserializer:
{
  "p1": {},
  "p2": {}
}

1 个答案:

答案 0 :(得分:1)

这看起来有点像Gson中的一个错误。如果您注册了TypeAdaptor,它似乎会被用于序列化和反序列化。

要解决此问题,请让Point2DDeserializer同时实现JsonDeserializer和JsonSerializer:

static class Point2DDeserializer implements JsonDeserializer<Point2D>, JsonSerializer<Point2D> {

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

        Point2D.Double ans = new Point2D.Double();
        JsonObject obj = json.getAsJsonObject();

        ans.x = obj.get("x").getAsDouble();
        ans.y = obj.get("y").getAsDouble();

        return ans;
    }

    @Override
    public JsonElement serialize(final Point2D point2D, final Type type, final JsonSerializationContext jsonSerializationContext) {
        return new Gson().toJsonTree(point2D);
    }
}